21.多态

多态是java语言的核心机制

  • 关于多态中涉及到几个概念
向上转型		upcasting
子类型转换成父类型——自动类型转型
向下转型 		downcasting
父类行转换成子类型——需要强制类型转换符
  • 无论是向上还是向下转型,两种类型之间需要有继承关系,否则,程序无法编译通过

Animal b1 = new Bird();
b1.move();

Bird是Animal的子类,java允许这种语法,父类型引用指向子类型

java程序分为编译阶段和运行阶段,编译无法通过就无法运行,编译器检查b1的数据类型为Animal,由于Anima.class字节码当中有move( )的方法,所以编译通过,这个过程称为静态绑定,也叫编译阶段绑定。
在程序运行阶段,JVM真实存在的对象是Bird对象,那么以下程序在运行阶段,一定会用Bird对象的move()方法,此时发生了程序的动态绑定,也叫运行阶段绑定。
无论是Bird类有没有重写方法,运行阶段一定调用的是Bird对象的move方法。因为底层真实的对象就是Bird对象

父类型引用指向子类型对象的这种机制导致程序存在编译阶段的绑定和运行阶段的绑定两种不同的状态

如果绑定的方法是子类特有的方法,要编译通过
可以通过将子类强制转换为父类,称为向下转型,两种 类型也需要继承关系,需要强制类型转换符
什么时候需要向下转型呢?

Bird c1 = (Bird)b1;

如果想访问子类特有的方法,对b1进行向下转型

Animal b2 = new Bird();
Cat c2 = (Cat)b2;

编译虽然通过了,但是运行的时候会发生异常,因为JVM真实存在的是Bird类型,而BIrd类型无法转换为Cat类型,两种类型间不存在继承关系,因此发生了著名的异常:java.lang.classCastEception
向下转型存在隐患,怎么避免向下转型的隐患
使用instanceof运算符可以避免以上的异常
语法格式:
引用 instanceof 数据类型名
以上运算符的执行结果是布尔类型,结果可能为真或假
a instanceof animal
结果为真表示:a这个对象指向一个animal类型
结果为假表示:a这个对象不是指向一个animal类型

因此,当b2这个类型指向Bird的时候,才强制转换类型

多态在实际开发的作用

创建类——》创建对象——》进行协同操作
提高程序的扩展力,降低程度的耦合度
如果方法对象设置为父类,那么子类都可以调用,向上兼容,父类型引用指向子类型对象
因此要面向抽象编程,不要面向具体编程,能使用多态尽量使用多态