Thinking in JAVA笔记——第8章 多态

多态分离做什么和怎么做。又成为动态绑定,后期绑定或运行时绑定。

8.1再论向上转型

对象可以当做它的父类型来使用,称为向上转型。

一个方法接受父类为参数,所有的子类都能调用这个方法,编译器在编译时间不确定执行哪个方法,在运行时间根据相应的子类是否重写了方法决定调用哪个方法,这样做大大减少了编程。

8.2转机?

8.2.1方法调用绑定

将方法调用和方法主体关联起来被称作绑定。

后期绑定:在运行时根据对象的类型进行绑定

编译器不知道对象的类型(因为编译器只知道这是个父类,不知道是哪个子类传入的)

Java中除了static方法和final方法外都是后期绑定。

8.2.2产生正确的行为

编译器只知道对象是一种父类,只有到运行时间才知道对象具体是什么类,并执行正确的行为。

8.2.3  可扩展性

操作基类的方法不用经过任何修改!

Parent s=new Son();

发生了什么:new一个子类,为子类申请空间,但向上转型后子类增加的部分就不可见了(仍然存在!),调用方法也优先考虑子类覆盖的方法!

8.2.4 缺陷:“覆盖”私有方法

覆盖private方法不会报错,但语义不是覆盖,而是新方法,向上转型后就不可见了,达不到多态的效果。

因此,要避免“覆盖”private方法,应该起一个不同的名字!

8.2.5 缺陷:域与静态方法

域(成员变量)是在编译时间绑定的,是不会覆盖的。

如果子类和父类域名相同,则各自有各自的空间,向上转型后子类的域就不可见了(除非调用子类覆盖的方法)

实践中应该避免这种情况,首选尽量将所有的域定义为private,其次不要为子类加一个同名的域!

静态方法也不具有多态性。

 

8.3构造器和多态

构造器不具有多态性,(构造器是隐式static方法)

8.3.1构造器的调用顺序

父类的构造器在子类的构造器中调用,并按照继承层次逐渐向上链接。

使得对象被正确的构造。如果没有显示调用父类构造器,就会自动调用默认构造器。

调用顺序(与普通构造顺序稍微不同,父类构造器最先调用!):

按顺序调用父类构造器

按声明顺序初始化成员

调用子类构造器主体

要求在执行子类的所有操作之前,父类的一切都是已知的,所以要最先调用父类构造器!

8.3.2继承与清理

一般情况下不必执行清理动作,一旦需要手动清理,则必须谨慎加小心!!!

清理动作子类覆盖父类,并调用父类的清理动作。清理顺序与初始化顺序相反,以防对象的依赖性,避免出现问题!

如果成员对象存在这被多个对象共享的情况,问题就更加复杂了,不能简单的清理。必须使用引用计数来耿宗共享对象的对象数

 

8.3.3构造器内部的多态方法的行为

在构造器中调用方法,可能会出现父类构造器调用了子类覆盖方法的情况。

所以,编写构造器应该遵守原则:尽可能简单的使对象构造,避免调用其他方法,可以调用private,final等不能继承的方法。

 

8.4 协变返回类型

实质上是对象的向上转型。

返回类型是子类的方法的结果可以赋值给父类对象的引用。

 

8.5 用继承进行设计

 

posted @ 2015-05-18 20:14  cjrzh  阅读(215)  评论(0编辑  收藏  举报