Java基本语法-面向对象(十二)-多态性(二)

122 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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的对象所属的类中的重写方法。

成员变量:

  • 不具备多态性,只看引用变量所声明的类。