第八章多态

1、多态不但能够改善代码的组织结构和可读性,还能够创建可扩展的程序。
2、“封装”通过合并特征和行为来创建新的数据类型。“实现隐藏”则通过将细节“私有化”把接口和实现分离开来。
3、多态的作用是消除类型之间的耦合关系。
4、继承允许将对象视为它自己本身的类型或其及类型来加以处理。它允许将多种类型(从同一基类导出的)视为同一类型来处理,而同一份代码也就可以毫无差别的运行在这些不同类型之上了。
5、多态方法调用允许一种类型表现出与其他相似类型之间的区别,只要他们都是从同一基类导出而来的。这种区别是根据方法行为的不同而表示出来的,虽然这些方法都可以通过同一个基类来调用。
8.1 再论向上转型
1、把某个对象的引用视为对其基类的引用的做法被称作为向上转型。
8.1.1忘记对象类型
1、不管导出类的存在,编写的代码只与基类打交道。
8.2 转机
8.2.1 方法调用绑定
1、将一个方法调用同一个方法主体关联起来被称为绑定。若在程序执行前进行绑定,叫做前期绑定。
2、后期绑定:在运行时根据对象的类型进行绑定。(也叫作运行时绑定)
3、Java中除了static方法和final方法(private方法属于final方法)之外,其他所有的方法都是后期绑定。这意味着通常情况下,不必判定是否应该进行后期绑定–它会自动发生。
4、为什么要将某个方法声明为final方法(private方法属于final方法)?这样做可以有效地“关闭”动态绑定,或者说,告诉编译器不需要对其进行动态绑定。
8.2.2 产生正确的行为
1、Java中所有方法都是通过动态绑定实现多态。就可以编写只与基类打交道的程序代码了,并且这些代码对所有的导出类都可以正确运行。(即发送消息给某个对象,让该对象去断定应该做什么事)
2、在编译时,编译器不需要获得任何特殊信息就能进行正确的调用。
8.2.3 可扩展性
1、程序时可扩展的,因为可以从通用的基类继承出新的数据类型,从而新添一些功能。哪些操纵基类接口的方法不需要任何改动就可以应用于新类。
2、多态是一项让程序员“将改变的事务与未变的事务分离开来”的重要技术。
3、只有非private方法才可以覆盖,但是还需要密切注意覆盖private方法的现象,这时虽然编译器不会报错,但是也不会按照所期望的来执行。确切的说,在导出类中,对于基类中的private方法,最好采用不同的名字。
8.2.5 缺陷:域与静态方法
1、只有普通方法的调用可以是多态的。如果直接访问某个域,这个访问就将在编译器进行解析。
2、通常会将所有的域都设置为private,因此不能直接访问它们,其副作用是只能调用方法来访问。
3、某个方法是静态的,它的行为就不具有多态性。静态方法是与类,而并非与单个的对象相关联的。
8.3 构造器和多态
1、构造器不同于其他种类的方法,涉及到多态仍是如此。尽管构造器并不具有多态性(它们实际上是static方法,只不过该static声明是隐式的)
2、基类的构造器总是在导出类的构造器中被调用,并且按照继承层次逐渐向上链接,以使每个基类的构造器否能得到调用。构造器有一项特殊任务:检查对象是否被正确地构造。导出类只能访问它自己的成员,不能访问基类中的成员(基类成员通常是private)。只有基类的构造器才具有恰当的知识和权限来对自己的元素进行初始化。因此,必须令所有构造器都得到调用,否则就不可能正确构造完整对象。这正是编译器为什么强制每个导出类部分都必须调用构造器的原因。在导出类的构造器主体中,如果没有明确指定调用某个基类构造器,就会调用默认构造器。如果不存在默认构造器,编译器就会报错。
3、复杂对象调用构造器遵照以下顺序:
①调用基类构造器②按声明顺序调用成员的初始化方法。③调用导出类构造器的主体。
8.3.2继承与清理
1、某个子对象依赖于其他对象,销毁的顺序应该和初始化顺序相反。对于字段,则意味着与声明的顺序相反。对于基类,应该首先对其导出类进行清理,然后才是基类。这是因为导出类的清理可能会调用基类中的某些方法,所以需要使基类中的构建仍起作用而不应该过早地销毁它们。
8.3.3构造器内部的多态方法的行为
1、初始化的实际过程:
①在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的零。
②调用基类构造器。
③按照声明的顺序调用成员的初始化方法。
④调用导出类的构造器主体
2、在构造器内唯一能够安全调用的那些方法是基类中的final方法(也使用于private方法,它们自动属于final方法)。这些方法不能被覆盖,因此不会出现问题。
8.4 协变返回类型
8.5 用继承进行设计
1、用继承表达行为间的差异,并用字段表达状态上的变化。
8.5.1纯继承与扩展
1、基类可以接收发送给导出类的任何信息,因为二者有着完全相同的接口。我们只需从导出类向上转型,永远不需知道正在处理的对象的确切类型。所有这一切,都是通过多态来处理的。
2、导出类中接口的扩展部分不能被基类访问,因此,一旦向上转型,就不能调用新的方法。
8.5.2向下转型与运行时类型识别
8.6总结
1、多态意味着“不同的形式”。在面向对象的接口设计中,持有从基类继承而来的相同接口,以及使用该接口的不同形式:不同版本的动态绑定方法。

猜你喜欢

转载自blog.csdn.net/panda_____/article/details/80261096