Java编程思想总结篇(1-11章学习笔记)——第八章

第八章 多态

从这章开始难度增加,我会更新少一点,写的细一点。

多态是继数据抽象和继承之后的第三种基本特征

多态(也称作动态绑定后期绑定运行时绑定)。

多态的作用是消除类型之间的耦合关系。

向上转型:某个对象的引用视为对其基类型的引用的做法

1 方法调用绑定

将一个方法调用与一个方法主体关联起来称作绑定

有了动态绑定,就可以编写只与基类打交道的代码,并且这些代码对所有导出类都可以正确运行。

前期绑定

若在程序执行前进行绑定(如果有的话,由编译器和连接程序实现),叫做前期绑定。它是面向过程语言中不需要选择就默认的绑定方式。

后期绑定

后期绑定,就是在运行时根据对象的类型进行绑定。后期绑定也叫做动态绑定或运行时绑定。

如果一种语言想实现后期绑定,就必须具有某种机制,以便在运行时能判断对象的类型,从而调用恰当的方法。也就是说,编译器一直不知道对象的类型,但是方法调用机制能找到正确的方法体,并加以调用。

后期绑定机制随编程语言的不同而有所不同,但是只要想一下就会得知,不管怎样都必须在对象中安置某种“类型信息”。

再谈final(”覆盖“私有方法)

Java中除了static和final方法(private是隐式的final)之外,其他所有的方法都是后期绑定。

final方法可以防止其他人覆盖该方法。但更重要的一点是:这样做可以有效地关闭动态绑定,或者说,告诉编译器不需要对其进行动态绑定。这样,编译器就可以为final方法调用生成更有效的代码

因此,最好根据设计来决定是否使用final,而不是出于试图提高性能的目的来使用final。

2 域和静态方法

域是不具有多态性的,只有普通的方法调用是多态的。如果直接访问某个域,这个访问就将在编译期进行解析,即域是静态解析的。

静态方法也是不具有多态性的。静态方法是与类,而非与单个的对象相关联的。

3 构造器与多态

复杂对象调用构造函数的顺序:

a.将分配给对象的存储空间初始化成二进制的零。

b.调用基类的构造函数。整个步骤会不断的反复递归下去,首先是构造整个层次结构的根,然后是下一层导出类,直到最底层的导出类。

c.按声明顺序调用成员的初始化方法。

d.调用导出类构造函数的主体。

如果在构造器内部调用正在构造的对象的某个动态绑定方法,由于动态绑定是在运行时才决定的,而此时,该对象还正在构造中,所以它不知道自己属于哪个类(父类还是自己),并且方法所操纵的成员可能还未进行初始化,这可能会产生一引起难于发现的隐藏错误。

编写构造函数时有一条有效的准则:用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其他方法。在构造函数内唯一能够安全调用的方法是基类中的final方法(也适用于private,因为它是隐式final)。

4 协变返回类型

导出类中的覆盖方法可以返回基类方法返回类型的某种导出类型(导出类中的覆盖方法的返回类型可以比基类方法返回类型更具体)。

5 用继承进行设计

首选组合,尤其是不能十分确定应该使用哪一种方式时。还有一条通用的准则:“用继承来表达行为间的差异,用字段表达状态上的变化。”

纯继承是一种is-a关系,导出类的接口与基类接口完全相同,因此可以全程利用多态和向上转型。

扩展继承是一种is-like-a关系,导出类比基类拥有更多的功能(更多的接口),这样程序实现起来更灵活,而且貌似更符合Java开发者的本意(因为继承用了关键字extends)。但是在向上转型时就会丢失导出类那些新增的功能。

Java中,所有转型都会检查,在进入运行时仍会检查,如果不是该类型,就会抛出ClassCastException异常。运行期间对类型进行检查的行为称作“运行时类型识别(RTTI)”。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值