多态(Polymorphism)
关于java语言当中的多态语法机制:【只是多态的基础语法,多态的作用在后续的例子中讲解。】
Anima1、Cat、Bird三个类之间的关系:
Cat继承 Anima
Bird维承 Anima
Cat和Bird之间没有任何继承关系面向对象三大特征:封装、继承、多态
关于多态中涉及到的几个概念:
向上转型(upcasting)
子类型—->父类型
又被称为:自动类型转换。Animal animal1 = new Cat(); // 子转父类 向上转型
向下转型(downcasting)
父类型—->子类型
又被称为:强制类型转换。【需要加强制类型转换符】Cat cat = (Cat) animal1; // 父类转子类 向下转型
需要记忆:
无论是向上转型还是向下转型,两种类型之间必须要有继承关系。
没有继承关系,程序是无法编译通过的。注意:
java程序永远都分为编译阶段和运行阶段。
先分析编译阶段,再分析运行阶段,编译无法通过,根本是无法运行的。
编译阶段编译器检查a2这个引用的数据类型为 Anima1,由于 Anima1.c1ass
> 字节码当中有move()方法,所以编译通过了。这个过程我们称之为静态绑定,编译阶段绑定。
> 只有静态绑定成功之后才有后续的运行。
在程序运行阶段,JV唯堆内存当中真实创建的对象是cat对象,那么以下程序在运行阶段一定会调用cat对象的move()方法,此时发生了程序的动态绑定,运行阶段绑定。
无论是cat类有没有重写move方法,运行阶段一定调用的是cat对象的move方法,因为底层真实对象就是cat对象。
父类型引用指向子类型对象这种机制导致程序存在编译阶段绑定和运行阶段绑定两种不同的形态/状态,这种机制可以成为一种多态语法机制。
instanceof运算符(返回boolean类型)
Animal animal1 = new Cat(); // 子转父类 向上转型
Dog dog = (Dog) animal1;
dog.action();
/**
* 以上会编译报错:cannot be cast to class (cat类不能强制转换为dog类)
* 原因:
* 1. 编译未报错:
* - 编译检测时候当前Animal里面包含Dog类所以语法正确
* 2. 运行错误报错:
* - 运行时候由于堆内存中是Cat类由于Cat与Dog不是继承关系,所以无法完成向下转型
* 3. 解决方法:
* - Sun公司给出了一个运算符叫做:instanceof
* - 语法:引用 instanceof 类名 --------> 返回值:Boolean
*/
// 解决办法
if (animal1 instanceof Dog) { // 当animal的堆内存中存储的是dog对象时执行
Dog dog = (Dog) animal1;
animal1.action();
}else if (animal1 instanceof Cat) {// 当animal的堆内存中存储的是cat对象时执行
Cat cat = (Cat) animal1;
animal1.action();
}
// 这样有效的避免了编译报错:cannot be cast to class
总结:
如果创建了一个B对象,且B类继承自A类,如果B类想使用A类中方法
这种情况使用向上转型(upcasting)
- 如果创建了一个B对象,且B类继承自A类,且B类现在已经向上转型了,但是现在向调用子类方法
这种情况使用向下转型(downcasting)