多态性
多态—在Java中,子类的对象可以替代父类的对象使用
一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
Student m = new Student();
m.school = “pku”; //合法,Student类有school成员变量
Person e = newStudent();
e.school = “pku”; //非法,Person类没有school成员变量
属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误
虚拟方法调用
正常的方法调用
Person e = new Person();
e.getInfo();
Studente = new Student();
e.getInfo();
虚拟方法调用(多态情况下)
Person e = new Student();
e.getInfo(); //调用Student类的getInfo()方法
编译时类型和运行时类型
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。—— 动态绑定
总结:多态
1.在java中,子类的对象可以代替父类的对象使用或父类的引用可以指向子类的对象。
2.在多态情况下,父类的实例变量不能再访问子类中添加的属性和方法。
3.方法的调用是在运行时确定的,所以调用的是Man 类的getInfo()方法。--动态绑定(虚拟方法调用)。
4.存在父子关系(多态)情况下,可以把父类的引用类型强制转换为子类的引用类型。若实际上不能转换,即不符合实际,则抛出类型转换异常。
5.为了避免4中的异常,在转换之前可以先判断一下对象实际上是否为指定的子类类型,使用instanceof运算符。注意:使用该运算符,必须要求前面的引用指向的变量和后边的类之间存在父子关系。
6. x instanceof A:检验x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
如果x属于类A的子类B,x instanceof A值也为true。
代码实例:
packagecom.atgugu.java;
importjava.util.Date;
publicclass TestPerson {
public static void main(String[] args) {
//多态
//1. 创建一个 Man 的实例
Man m1 = new Man();
//2. 创建一个 Woman 的实例
Woman w1 = new Woman();
//3. 创建一个 Person 的实例
Person p1 = new Person();
/**
* 多态: 在Java中,父类的引用可以指向子类的对象.
*1. 在多态情况下, 父类的实例变量不能再访问子类中添加的属性和方法
*2. 方法的调用是在运行时确定的,所以调用的是Man 类的 getInfo() 方法。—— 动态绑定(虚拟方法法调用)
*3. 在存在父子关系(多态)的情况下, 可以把父类的引用类型强制转换为子类的引用类型. 若实际上不能进行转换则系统
* 会抛出 java.lang.ClassCastException 异常.
*4. 如何避免出现java.lang.ClassCastException 异常呢? 在转换之前可以先判断一下对象实际上是否为指定的子类类型.
* 使用 instanceof 运算符. 注意, 使用 instanceof 运算符, 必须要求前面的引用指向的变量和后边的类之间存在父子关系
*/
//需要一个人, 但来的是一个男人! OK. 因为男人一定是一个人.
Person p2 = new Man();
System.out.println(p2.getInfo());
//需要一个人, 但来的是一个女人! OK. 因为女人一定是一个人
Person p3 = new Woman();
//在多态情况下, 可以进行强制的类型转换
Man m2 = (Man) p2;
System.out.println(p3 instanceof Man);
System.out.println(p3 instanceof Woman);
// System.out.println(m2 instanceof Person);
// Man m3 = (Man) p3;
//需要一个男人, 但来的是个人! NO. 因为人不一定是男人.
//Man m2 = new Person();
//需要个男人, 但来的是一个女人。 NO!
//Man m3 = new Woamn();
}
}
对Java对象的强制类型转换称为造型
– 从子类到父类的类型转换可以自动进行(man—>person)
– 从父类到子类的类型转换必须通过造型(强制类型转换)实现(person——>man)
– 无继承关系的引用类型间的转换是非法的
在造型前可以使用instanceof操作符测试一个对象的类型