携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情
多态性应用举例
- 方法声明的形参类型为父类类型,可以使用子类的对象作为实参调用该方法
public class Test {
public void method(Person e) {
// ……
e.getInfo();
}
public static void main(Stirng args[]) {
Test t = new Test();
Student m = new Student();
t.method(m); // 子类的对象m传送给父类类型的参数e
}
}
虚拟方法调用(Virtual Method Invocation)
- 正常的方法调用
Person e = new Person();
e.getInfo();
Student e = new Student();
e.getInfo();
虚拟方法调用(多态情况下)
- 子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
Person e = new Student();
e.getInfo(); //调用Student类的getInfo()方法
- 编译时类型和运行时类型编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类 的getInfo()方法。——动态绑定
前提:
- Person类中定义了welcome()方法,各个子类重写了welcome()。
执行:
- 多态的情况下,调用对象的welcome()方法,实际执行的是子类重写的方法。
从编译和运行的角度看:
- 重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。引用一句Bruce Eckel的话:“不要犯傻,如果它不是晚绑定,它就不是多态。” 多态小结
多态作用:
- 提高了代码的通用性,常称作接口重用
前提:
- 需要存在继承或者实现关系
- 有方法的重写
成员方法:
- 编译时:要查看引用变量所声明的类中是否有所调用的方法。
- 运行时:调用实际new的对象所属的类中的重写方法。
成员变量:
- 不具备多态性,只看引用变量所声明的类。