日期:2014-05-20  浏览次数:20746 次

子类覆盖父类的方法与属性后,把子类强制转化为父类类型,为什么这时方法体是子类的,而属性却是父类的呢?
子类覆盖父类的方法与属性后,把子类强制转化为父类类型,为什么这时方法体是子类的,而属性却是父类的呢?
有如下代码可证(呵呵,透露一下,是IBM的面试题,至今我还未解开这个迷,请高手多多指教,不才感激不尽!):
Java code
public class FatherClild {
    public static void main(String[] are) {
        Child c = new Child();
        Parent p = c;
        System.out.println(p.ParentVar);
        System.out.println(p.ParentStaticVar);
        System.out.println(p.ParentStaticStr);
        System.out.println(c.ParentVar);
        System.out.println(c.ParentStaticVar);
        System.out.println(c.ParentStaticStr);
        p.parentMethod();
        p.parentStaticMethod();
        c.parentMethod();
        c.parentStaticMethod();
    }

}

class Child extends Parent {
    public int ParentVar = 15;

    public static int ParentStaticVar = 14;
    
    //public static String ParentStaticStr = "child";
    
    static {
        System.out.println("this is a Child static block");
    }

    public Child() {
        System.out.println("this is a Child construct");
    }

    public void parentMethod() {
        System.out.println("this is a Child method");
    }

    public int getParentStaticVar() {
        return super.ParentVar;
    }

    public static void parentStaticMethod() {
        System.out.println("this is a Child static method");
    }
}

/*
 * 
 */
class Parent {
    public int ParentVar = 5;

    public static int ParentStaticVar = 4;

    public static String ParentStaticStr = "parent";
    
    static {
        System.out.println("this is a parent static block");
    }

    public Parent() {
        System.out.println("this is a parent  construct");
    }

    public void parentMethod() {
        System.out.println("this is a parent method");
    }

    public static void parentStaticMethod() {
        System.out.println("this is a parent static method");
    }
}


打印的结果是:

this is a parent static block
this is a Child static block
this is a parent construct
this is a Child construct
5
4
parent
15
14
parent
this is a Child method
this is a parent static method
this is a Child method
this is a Child static method

通过学习,把我对这些了解的与大家共享一下,望能有更多的交流

1) 类被自动执行的顺序  
静态域(类被加载时)  
静态初始化块(类加载时,当然这时的静态域要先有值,才便于正确执行)  
非静态域(实例开辟内存时)  
非静态初始化块(实例开辟内存时)  
构造方法(实例生成对象引用时)  
2) 当实例化一个第3代的类时,发生的动作将是这样的  
加载第3代,但第3代来源于第2代  
所以加载第2代,但第2代来源于第1代  
所以加载第1代。  
所以:  
(1) 第1代类被加载,发生第1代类加载时的动作(即,静态初始化块)  
(2) 第2代类被加载,发生第2代类加载时的动作  
(3) 第3代类被加载,发生第3代类加载时的动作  
加载完之后,开始创建第3代,但第3代来源于第2代  
所以创建第2代,但第2代来源于第1代  
所以创建第1代  
所以  
(4) 第1代被创建,并初始化,完成该时期的动作(即,非静态初始化块,接着 构造方法)  
(5) 第2代被创建,并初始化,完成该时期的动作  
(6) 第3代被创建,并初始化,完成该时期的动作  
继承父类的理解[]  
从个人理解上看:  
创建父类对象的证据是:子类里都有一个super,它就是父类对象,可见,要创建子类,一定会先创建父类,只是父类做为子类的一个属性(可以这么理解)所以整体上看,是只创建了一个子类。  
简明地说:  
设计者让子类的初始化是首先用父的构造方法来展开的,所以子类在完成造构之前(刚完成调用父类的构造方法展开)父类就实例化了。  
所以我理解了,为什么有的程序只是创建一个对象,却执行了满世界的代码了  
还有一重大发现:  
当父类有多个造构方法时,在子类的构造方法里,可以决定自己是用父类的那个构造方法生成的,所以super()只能用一次,且必须放在构造方法的第一句。  
可见,java在代码复用上下的功夫真不少:  
1) 父类的代码可以供所有的子类使用