菜鸟教程:Java面向对象
指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用) 现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。
(1)继承 (2)重写 (3)父类引用指向子类对象
1.可替换性(substitutability) 多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。 2.可扩充性(extensibility) 多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。 3.接口性(interface-ability) 多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。 4.灵活性(flexibility) 它在应用中体现了灵活多样的操作,提高了使用效率。 5.简化性(simplicity) 多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
如果Father类型方法表中没有方法f1,那么即使Son类型中方法表有,编译的时候也通过不了。因为调用方法f1的类的对象father的声明为Father类型。
将一个方法调用同一个方法主体关联起来被称为绑定
在编译阶段就能够确定调用哪个方法的方式,我们叫做 静态绑定机制 。 除了被static 修饰的静态方法,所有被private 修饰的私有方法、被final 修饰的禁止子类覆盖的方法。JVM会采用静态绑定机制来顺利的调用这些方法。
在程序运行过程中,通过动态创建的对象的方法表来定位方法的方式,我们叫做 动态绑定机制 。 类对象方法的调用必须在运行过程中采用动态绑定机制。 首先,根据对象的声明类型(对象引用的类型)找到“合适”的方法。具体步骤如下: ① 如果能在声明类型中匹配到方法签名完全一样(参数类型一致)的方法,那么这个方法是最合适的。 ② 在第①条不能满足的情况下,寻找可以“凑合”的方法。标准就是通过将参数类型进行自动转型之后再进行匹配。(根据继承树从叶子向上找)如果匹配到多个自动转型后的方法签名f(A)和f(B),则用下面的标准来确定合适的方法:传递给f(A)方法的参数都可以传递给f(B),则f(A)最合适。反之f(B)最合适 。 ③ 如果仍然在声明类型中找不到“合适”的方法,则编译阶段就无法通过。
解析: (1)A a1 = new A();创建对象,a1具有调用方法1、2的能力。 根据方法的重载,a1.show(b)会与方法2绑定;a1.show©会与方法2绑定;a1.show(d)会与方法1绑定。 (2)A a2 = new B();多态,B实现了向上转型。创建了一个父类引用,指向子类对象。向上转型的缺点,就是不能调用子类中有而父类没有的方法。故a2具有调用方法1、4的能力。 a2.show(b)会与方法4绑定;a2.show©会与方法4绑定;a2.show(d)会与方法1绑定。 (3)B b = new B();创建对象,b具有调用方法1、3、4的能力。 b.show(b)会与方法3绑定,b.show©会与方法3绑定,b.show(d)会与方法1绑定。