多态的基础语法:
1.学习多态基础语法之前,我们需要普及两个概念:
第一个:向上转型
子———>父(强制类型转换)
第二个:向下转型
父———>子(自动类型转换)
注意:
java中允许向上转型,也允许向下转型,
无论是向上转型还是向下转型,两种类型之间必须有继承关系,没有继承关系,编译器报错。
注意:!!!!无论是向上转型还是向下转型,都必须有继承关系。
2.经过测试,得知java中支持这样一个语法:
父类型的引用允许指向子类型的对象
Animal a = new Cat();
a就是父类型的引用
new Cat()是一个子类型的对象子类型对象
允许a这个父类型的引用指向子类型这个对象。
3.多态指的是什么?
多态指的是,父类型引用指向子类型对象,
包括编译阶段和运行阶段。
编译阶段:绑定父类型当中的方法
运行阶段:动态绑定子类型对象的方法
多种形态。(在编译阶段过程中是不会创建对象的)
4.Animal a = new Cat();//底层对象是一只猫
a.catchmouse();//猫这个类的当中有捕捉老鼠这个方法
分析这个程序能否编译和运行?
分析程序一定要分析编译阶段的静态绑定和运行时段的动态绑定,
只有编译通过的代码才能运行,没有编译,根本轮不到运行。
错误,找不到符号
why???因为编译器只知道a的类型是Animal,去Animal.class文件中去找catchmouse()这个方法,结果没有找到,静态绑定失败,所以编译报错,无法运行,语法不合法。
假设我代码写到了这里,必须调用这个方法,我该怎么做,这时候就到了向下转型(强制类型转换)
Cat x = (Cat)a;
x.catchmouse;
5.什么时候必须进行向下转型?
这个方法是子类中独有的,父类想要调用,则需要向下转型(强制类型转换)
6.Animal a2 = new Bird();
Cat x2 = (Cat)a2;
x2.catchmoouse();
分析以上这个程序,是编译报错还是运行报错?
编译器检测到a2的类型是Animal类型,而Animal和Bird是继承关系,可以进行向下转型,编译没毛病。
运行阶段,堆内存的运行对象是Bird,在实际运行过程中,拿着Bird类型的对象转换成Cat类型的对象就不行,因为二者之间没有继承关系。
运行出现异常,这个异常和空指针异常一样重要,也一样经典。
7.运算符:instanceof
第一:instance可以在运行阶段动态判段引用所指向的对象类型。
第二:instance的语法:
(引用 instanceof 类型)
第三:instanceof运算符的运行结果只能是true和false
第四:c是一个引用,c这个变量里保存内存地址来指向堆内存中的对象。
假设(c instanceof Cat)为true 表示c保存的地址指向的是一个Cat类型的对象
假设(c instanceof Cat)为false 表示c保存的地址不是一个Cat类型的对象
总结:在进行向下转型(强制类型转换)的时候一定要使用instanceof进行判断!!!!
8.`静态不谈覆盖,私有不能覆盖。
public class Text2 {
public static void main(String[] args) {
Animal a = new Cat();//多态
a.move();//这样调用不好
//动态方法可以使用引用.来调用吗?答案是可以
//虽然使用引用.来调用,但是和对象无关
//静态方法和对象无关,实际运行还是Animal.move();
}
}
class Animal{
public static void move(){
System.out.println("动物在进行移动");
}
}
class Cat extends Animal{
public static void move(){ //静态方法覆盖没有任何意义
System.out.println("猫可以捕捉老鼠");
}
}