Java继承成员和继承方法的区别

        几乎所有的Java书籍或资料都会介绍:当子类继承父类时,子类会获得父类中定义的成员变量和方法。当访问权限允许的情况下,子类可以直接访问父类中定义的权限和方法。这种介绍其实有些笼统,而且字面理解上会产生歧义和错误。因为Java继承中对成员变量和成员方法的处理是不通的。

 

比如如下代码:

class Base {
    int count = 2;

    public void display() {
        System.out.println(this.count);
    }
}

class Derived extends Base {
    int count = 20;

    @Override
    public void display() {
        System.out.println(this.count);
    }
}

public class StaticTest {

    final static StaticTest INSTANCE = new StaticTest(2.0);

    public StaticTest(double discount) {
        currentPrice = initPrice - discount;
    }

    static double initPrice = 20;
    double currentPrice;
    String kkk = "dfa";

    /**
     * @param args
     */
    public static void main(String[] args) {
        // 第一组
        Base b = new Base();
        System.out.println(b.count);
        b.display();
        //第二组
        Derived d = new Derived();
        System.out.println(d.count);
        d.display();
        //第三组
        Base bd = new Derived();
        System.out.println(bd.count);
        bd.display();
        //第四组
        Base bd2 = d;
        System.out.println(bd2.count);
    }

}


 

第一组的Base,输出的都是2,这个应该是没有疑问的。

第二组的Derived,因为是子类,而且是覆盖父类的方法,成员变量的取近法则,所以输出都是20,也是没有疑问的。

第三组:讲一个Derived子类赋给Base的父类,此时系统将会自动向上转型以保证程序的正确。问题是,当程序通过db来访问count实例变量时输出到底是多少?通过db的display()方法时输出又是多少?答案是,直接访问实例变量,输出的将是声明时的类型,也就是Base的实例变量的值,而访问方法的时候,则表现的是运行时的类型,也就是子类的行为方式。于是输出的结果就是2和20。

第四组:这组其实有些诡异。因为当把d赋给db2的时候,代表着这两个变量指向了同一个内存。但是,实际访问d.count时输出是20,访问db2.count时输出的却是2。正常来说,两个指向同一个对象的变量,分类访问他们的实例变量时应该是同一个值,但是... 这说明了db2和d所指向的Java对象中包含了两块内存,分别存放值为2的count实例变量和值为20的count实例变量。

 

最后,结论是,不管d变量,还是bd变量,bd2变量,只要它们实际指向一个Derived对象,不管声明它们用的是什么类型,当通过这些变量调用方法时,方法的行为总是表现出它们实际类型的行为,但如果通过这些变量来访问它们所指的对象的实例变量时,这些实例变量的值总是表现出声明这些变量所用的类型的行为。由此可见,Java继承在处理成员变量和方法时是有区别的。

 

 

你可能感兴趣的:(Java继承成员和继承方法的区别)