第8章 多态
面向对象的三大基本特征:封装,继承,多态
多态通过分离做什么和怎么做,从另一个角度将接口和实现分离出来。多态的作用是消除类型之间的耦合关系。一般是使用动态绑定,后期绑定或运行期绑定。
我们知道,继承允许将对象视为自己本身的类型或其基类型进行处理,而同一份代码可以毫无差别地运行在这些不同类型之上。多态方法调用允许一种类型表现出与其他相似类型之间的区别,只要他们都是从同一几类导出来的。这种区别是根据方法行为的不同而表示出来的,虽然这些方法都可以通过同一个基类来调用。
向上转型
对象可以把它当做是一个基类对象使用,这种调用方法叫做向上转型。向上转型之后就会出现一个现象,忘记对象类型,我们的调用代码之和基类打交道,而不管导出类是什么。
方法绑定
将一个方法调用同一个方法主体关联起来称作绑定。若在程序执行之前进行绑定(一般由编译器和连接程序实现),叫做前期绑定。
后期绑定就是就是在运行时根据对象的类型进行绑定。后期绑定也叫动态绑定或运行时绑定。
Java除了static和final方法(private属于final方法)之外,其他方法都是后期绑定。因此final方法不仅可以防止方法被覆盖,而且还可以有效“关闭”动态绑定,然而这对程序整体性能改变不会很大。特别需要注意的是private的方法不能多态,如果在父类对象中有一个private f()方法,而子类有public f()的同名方法,在父类中调用父类引用到子类对象,然后想再调用f()方法,那么只会调用父类的private方法,因为private不能多态,早期绑定了,不再查找子类的方法。
有了动态绑定,当我们调用一个基类引用的对象方法时,会根据对象的真正的方法进行调用(而不是调用基类的方法),这样就可以产生不同的行为。
向下转型和运行时类型识别
向上转型会导致类型丢失,但是要解决某些问题时需要得到对象的具体类型(一般子类会有更多的特有方法),但是向下转型的风险比较大,需要某种方法确保向下转型的正确性,java可以对对象的类型进行检查,这种行为叫做“运行时类型识别(RTTI)”。其可以使用instance of
检查对象是哪一个类的实例。