多态
多态是指某一引用可以指向多种形态的对象,调用同一个方法可以执行多种形态的结果;代码层面就是父类的引用可以指向不同子类的对象实例:
package characteristic.polymorphism;
/**
* 声明Person类
*
* @author 学霸联盟 - 赵灿
*/
public class Person {
private String name = "人";
//创建一个睡觉的方法
public void sleep(){
/*
* 封装的又一大好处,如果不将属性name封装成getName方法
* 这里就无法通过重写getName方法获得子类对象的姓名
* 当传入的对象时LiuBei时,调用的getName时LiuBei中重写后的
*/
System.out.println(getName() + ":闭着眼睛睡觉");
}
//获取姓名的方法
public String getName(){
return name;
}
}
package characteristic.polymorphism;
/**
* 创建刘备:用于测试继承的情况
* @author 学霸联盟 - 赵灿
*/
public class LiuBei extends Person {
private String name = "刘备";
//获取姓名的方法
public String getName(){
return name;
}
}
package characteristic.polymorphism;
/**
* 创建关羽:用于测试重写的情况
* @author 学霸联盟 - 赵灿
*/
public class GuanYu extends Person {
private String name = "关羽";
//重写父类的方法
@Override
public void sleep() {
System.out.println(getName() + ":睁着一只眼睛睡觉");
}
//获取姓名的方法
public String getName(){
return name;
}
}
package characteristic.polymorphism;
/**
* 创建张飞:用于测试重写的情况
* @author 学霸联盟 - 赵灿
*/
public class ZhangFei extends Person {
private String name = "张飞";
//重写父类的方法
public void sleep() {
System.out.println(getName() + ":睁着两只眼睛睡觉");
}
//获取姓名的方法
public String getName(){
return name;
}
}
package characteristic.polymorphism;
/**
* 测试多态
*
* @author 学霸联盟 - 赵灿
*/
public class Test {
// 创建main方法
public static void main(String[] args) {
//创建一个刘备
LiuBei liuBei = new LiuBei();
//创建一个关羽
GuanYu guanyu = new GuanYu();
//创建一个人,这个人是张飞,父类引用指向子类对象
Person zhangfei = new ZhangFei();
//执行时会将liuBei中存储的地址,赋值给参数p
testSleep(liuBei);
//执行时会将guanyu中存储的地址,赋值给参数p
testSleep(guanyu);
//执行时会将zhangfei中存储的地址,赋值给参数p
testSleep(zhangfei);
}
/**
* 测试人类是怎样睡觉的
* 首先需要人,这个人是谁都可以
* 如果选用LiuBei作为参数,其他人就无法传入这个方法
* 选用其他人也存在一样的问题
* 所以这里选用Person作为参数,只要继承人类的类都可以
*/
private static void testSleep(Person p) {
//调用人类睡觉的方法,传入不同的子类,执行后获得不同的结果
p.sleep();
}
}
运行结果:
刘备:闭着眼睛睡觉
关羽:睁着一只眼睛睡觉
张飞:睁着两只眼睛睡觉
一句话总结:父类引用指向子类对象时,该引用可以调用自身访问修饰符允许访问的成员和子类重写后的方法
关键字final
放在变量前,表示该变量为常量,只能被赋值一次;放在方法前,表示该方法不能被重写
放在类前,表示该类不能被继承
实例一:
package characteristic.inherit._final;
/**
* final修饰的类不能被继承
* @author 学霸联盟 - 赵灿
*/
public final class FinalDemo {
//final修饰的属性,声明和赋值必须写成一条语句
public final String s = "常量值";
//final修饰的方法不能被重写
public final void m(){
//final修饰的局部变量,声明和赋值可以分成两条语句
final String s;
s = "";
}
//final修饰的方法可以被重载
public final void m(final String s){
//final修饰的参数s,在方法中不能被修改
s = "";//这里会出现编译错误
}
}
实例二:
package characteristic.inherit._final;
/**
* 测试static方法是否可以被重载
* @author 学霸联盟 - 赵灿
*/
public class Bird {
//静态的不可被重写的飞行方法
public static final void fly(){}
//静态的攻击方法
public static void fire(){}
}
package characteristic.inherit._final;
/**
* 测试static方法是否可以被重载
* @author 学霸联盟 - 赵灿
*/
public class BlueBird extends Bird{
//这里会出现编译错误
public static void fly(){}
}
package characteristic.inherit._final;
/**
* 测试static方法是否可以被重载
* @author 学霸联盟 - 赵灿
*/
public class RedBird extends Bird{
/*
* 这里也会出现编译错误
* 但是如果不写@Override不会出现编译错误
* 如果不写@Override表示这个fire方法只属于RedBird类
*/
@Override
public static void fire() {}
}
总结:被static和final修饰的方法都不能被重写