《JAVA编程思想》第四版学习 需要我记住的something--多态

转自:http://blog.csdn.net/icesnows/archive/2009/06/10/4259012.aspx

一. 面向对象编程三个基本特性:数据抽象(data abstraction)、继承(inheritance)和多态(polymorphism)。


二.通过分离"做什么"和"怎么做",多态从另一个角度将接口与实现分离开。 
      多态不但能够改善代码组织结构和可读性,而且可以创建"可扩展"(extensible)的代码(无论是在项目最初创建时,还是在需要添加新功能时,都可以进行扩充)。
      多态-消除类型(types)之间的耦合关系(多个继承自同一基类的类都可以当做一种类型-基类来看待)。
      多态、动态绑定(dynamic binding)、后绑定(late binding)、运行时绑定(run-time binding)。

三. 多态使程序更简洁,可扩展。不使用向上转型和多态,而采用重载的方式实现,那在扩充继承类的时候,将有大量的工作要做(如添加以新增类为参数的方法代码)。所以,忘记对象类型吧(该忘记的时候)。
多态使你的代码变动不会破坏程序中不应受影响的其它部分,换句话说,多态是一项"将变化的事情与不变的事情分离开"的重要技术。


四.绑定(binding):将一个方法调用同方法实体链接起来; 
      前绑定(early binding):绑定发生在程序运行之前(编译器、链接器完成);
      后绑定(late binding)、动态绑定、运行时绑定:在程序运行时,根据对象的具体类型进行绑定。需要某种机制在运行时确定对象具体类型,并调用对应方法。因此,对象中需要存储关于类型的信息。

     Java中除了static或final方法(private方法隐式final)外,都是后绑定。 
      final方法,禁止override;关掉后绑定,提高效率。但应只从设计角度出发考虑final,而不应从效率的角度出发,因为大多数情况下,final方法并不能提高程序整体性能,尤其是在后来的JVM中(采用HotSpot技术)。

五.可扩展性:好的OOP程序,绝大多数或者全部方法应该只与基类接口打交道,这样的程序就是"可扩展"(extensible)的。


六.错误:重写private方法。 private自动是final,因此不可重写,继承类中与基类private方法签名相同的方法只是个全新的method;由于private方法在继承类中不可见,因此也不会是重载。

七.直接访问field和static方法都不是多态的,均为在编译期解析绑定。super.field,在继承类中访问基类field。

八.构造器不具备多态性,因为隐式static。

九.继承类的析构应在基类之前,因为继承类的析构可能需要调用基类的方法,需要保证基类对象存活。

十.当多个对象共享一个成员对象时,需要谨慎对待dispose,需要采用引用计数的方法(reference counting)来跟踪访问共享对象的对象数,在共享对象的dispose中判断refCount==0再进行真正的清理。

十一. 在构造器中调用多态方法必须小心,因为继承类的成员尚未初始化完,此时产生的结果可能并不是所需,导致程序bug(C++在这方面表现得更合理)。因此,构造器编写原则:尽可能简单的使对象进入正常状态,如果有可能,不要调用类中其它方法(唯一能安全调用的是final方法(private也是final))。

十二. 对象自动初始化(清零,binary zero)发生在其它初始化之前(static初始化呢?)。

十三. Java SE5之后,添加了协变返回类型(covariant return types),即继承类的重写方法可以返回基类对应方法返回类型的子类(不能是父类,可以试着考虑upcast之后对该方法的调用,如果是父类就可能出问题)。

十四. 尽管多态如此强大,设计时仍应先考虑使用组合而不是继承,尤其是在不明确该用哪个时。组合更灵活,可以动态选择类和相应的行为;而继承需要在编译器知道确切类型。参见例Transmogrify。 
      解释一下:使用组合,可以在运行时赋给所包含对象引用不同值(如不同继承类对象的引用,state pattern);而继承必须在编译时就确定基类,不能运行时再继承自不同类。
      原则:使用继承实现行为上的差异,用fields表现状态上的变化。(组合不正是把其它类型对象作为自己的fields么?)

十五. Substitution & Extension 
      pure substitution:不需要知道继承类的更多信息,甚至不需要知道对象的确切类型,只需upcast,多态完成一切。但有时,extension才是解决特定问题的完美方案。

十六. downcasting & runtime type information (RTTI) 
      upcasting永远安全,downcasting则不然。 
      Java,所有cast都被检验(因此可以只通过cast操作符()来实现,而C++需要执行特殊操作获得type-safe cast)。运行时类型识别runtime type identification (RTTI),出错抛出ClassCastException(似乎不需要为该异常写处理代码,因为它更多时候指示的是程序员的错误,除非特殊需要)。
      RTTI当然不只是用来对付cast,例如你还可以通过它来获取所处理对象的确切类型。

十七. 习题发现,finalize()方法是可以直接调用的(SE6测试)。

posted on 2010-11-24 11:13  kis$ove  阅读(553)  评论(0编辑  收藏  举报

导航