尚硅谷JavaSE基础
6.8 基本特征三 多态
曰:“白马非马,可乎?”
曰:“可。”
曰:“何哉?”
曰:“马者,所以命形也。白者,所以命色也。命色者,非命形也,故曰白马非马。”
6.8.1 什么是多态
1. 本态
一个对象的本类形态就是本态.
2. 多态
一个对象的多种父类形态就是多态
6.8.2多态的使用
1. 多态引用
将子类对象赋值于父类类型的引用变量就是多态引用, 在这里对象其实还是子类对象, 只不过是被看作是一个父类类型的对象.
Person person = new Student();
- 多态性,是面向对象中最重要的概念,在java中有两种体现:
- 方法的重载(overload)和重写(overwrite)。
- 对象的多态性 ——可以直接应用在抽象类和接口上。
- Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。
注意:若编译时类型和运行时类型不一致,就出现多态(Polymorphism)
2. 多态带来的问题
- 一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
Student m = new Student();
m.school = “pku”; //合法,Student类有school成员变量
Person e = new Student();
e.school = “pku”; //非法,Person类没有school成员变量
属性是在编译时确定的,编译时e为Person类型,没有school成员变量,
因而编译错误。
6.8.3虚拟方法调用(Virtual Method Invocation)
1. 什么是虚拟方法
正常的方法调用:
Person e = new Person();
e.getInfo();
Student e = new Student();
e.getInfo();
虚拟方法调用(多态情况下):
Person e = new Student();
e.getInfo(); //调用Student类的getInfo()方法
编译时类型和运行时类型:
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。
——动态绑定
2. 多态小结
前提:
需要存在继承或者实现关系
要有覆盖操作
成员方法:
编译时:要查看引用变量所属的类中是否有所调用的方法。
(编译时检查父类类型)
运行时:调用实际对象所属的类中的重写方法。
(运行时执行子类类型)
成员变量:
不具备多态性,只看引用变量所属的类。