对象的多态
- 一个对象的编译类型和运行类型就可以不一致
- 编译类型再定义对象时,就确定了 不能改变
- 运行类型是可以变化的
- 编译类型看定义时等号左边 运行类型看等号右边
Animal animal=new Dog();/*animal编译类型是Animal 运行类型是Dog*/
animal=new Cat();/*animal的运行类型变成了Cat 编译类型仍然是Animal*/
向上转型:父类的引用指向子类的对象
语法:父类类型引用名=new 子类类型();
animal animal=new cat();
向上转型调用方法的规则如下:
- 可以调用父类中的所有成员(需遵守访问权限)
- 但是不能调用子类的特有的成员 因为在编译阶段 能调用哪些成员,是由编译类型决定的
- 最终运行结果看子类(运行类型)的具体实现,即调用方法时,按照从子类(运行类型)开始查找方法,然后调用,子类没有就向上一级查找
向下转型:
语法:子类类型 引用名=(子类类型)父类引用;
cat的编译类型cat 运行类型是cat
cat cat=(cat) animal;
要求父类的引用必须指向的是当前目标类型的对象
dog dog=(dog)animal;
/*已经强转为cat类型了 就不能再转为dog类型*/
多态的注意事项:
调用方法的时候看运行类型aa.cat() 先看cat
调用属性的时候看编译类型 Base base=new sub();看Base类中的属性值
属性没有重写之说!属性的值看编译类型
instanceOf比较操作符 用于判断对象的运行类型是否为XX类型或者XX类型的子类型
Object objStr=new Integer(5);/*可以 向上转型*/
String str=(String)objPri;/*错误 ClassCastException 指向Interger的父类引用 转成String*/
Interger str1=(Interger)objPri;/*可以 向下转型*/
instanceOf注意事项
BB bb=new BB();
System.out.println(bb instanceof BB);//true
System.out.println(bb instanceof AA);//true
/*aa的编译类型是AA 运行类型是BB*/ 看运行类型
AA aa=new BB();
System.out.println(aa instanceof AA);//true
System.out.println(aa instanceof BB);//true
Object obj=new Object();
System.out.println(obj instanceof AA);//false
String str="hello";
System.out.println(str instanceof AA);//报错
System.out.println(str instanceof Object);//true
class AA(){}
class BB() extends AA(){}