第8章 多态

8.2 转机

  1. Java中除了static, final & private(private归为final一类)方法,都是动态绑定。
  2. 域同样是静态绑定。

8.3 构造器和多态

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

在C++中,应该避免在构造函数中调用virtual方法,因为这样的结果可能不是你想要的。

同样在Java中,应当避免在构造器中调用static, final或者private以外的方法。

如果在基类的构造器中调用了被导出类覆盖的方法,实际上是动态绑定在起作用,也就是基类中调用了导出类的行为。

 1 import static java.lang.System.out;
 2 class Base {
 3   void draw() {
 4     out.println("Base draw()");
 5   }    
 6   Base(){
 7     out.println("Base constructor start");
 8       draw();
 9     out.println("Base constructor end");
10   } 
11 }
12 
13 public class Derive extends Base {
14   private int i = 3;
15   void draw() {
16     out.println("Derive draw() i = " + i);
17   }
18   Derive(){
19     out.println("Derive constructor start");
20       draw();
21     out.println("Derive constructor end");
22   }    
23   public static void main(String args[]){
24     new Derive();
25   }
26 }/* Output:
27 Base constructor start
28 Derive draw() i = 0
29 Base constructor end
30 Derive constructor start
31 Derive draw() i = 3
32 Derive constructor end
33 */

在前面的章节中也提到过这个顺序:首先是类加载(自低向上)(类加载的过程包括abstract class但不包括interface,详细请参见第9章 接口,类加载(其实是Class的某个对象)的时候进行连个动作:分配空间,所有空间初始为空(Native为0,引用为Null,Boolean为False);其次调用域默认初始化和域初始化块,构造函数的调用,这个过程是自顶向下的,先基类再导出类。需要注意的是,因为在类加载后,方法的动态绑定就已经完成了,所以在第二部初始化(或者是初始化块,或者是构造函数,或者是域的默认初始化)中的函数调用都是动态绑定,也就造成了基类的初始化过程中,可以调用导出类的函数行为。

再次:应该避免这种使用方法!

posted on 2013-05-02 14:47  peter9606  阅读(121)  评论(0编辑  收藏  举报

导航