方法的继承与变量的继承有何不同?

时间:2014-07-19 15:47:05

标签: java inheritance

在为OCJP考试做准备的同时,我偶然发现了一个我无法解决的问题。这是(我有点修改过)一个问题的代码:

class Foo {
    public int a = 3;
    public void addFive() {
        a += 5;
        System.out.print("f ");
    }
}

class Bar extends Foo {
    public int a = 8;
    public void addFive() {
        a += 5;
        System.out.print("b ");
    }
}

public class TestInheritance {
    public static void main(String [] args) {
        // part 1
        Foo f = new Bar();
        f.addFive();
        System.out.println(f.a);

        // part 2
        Bar b = new Bar();
        b.addFive();
        System.out.println(b.a);
    }
}

,输出为:

b 3
b 13

第2部分我能理解。这里没什么好惊讶的。然而,第1部分不让我晚上睡觉。我理解为什么运行了Bar.addFive,但是当我使用f.a来实例化对象时,为什么第1部分Foo.a会打印new Bar()?对于方法而言,继承的工作方式与变量的工作方式完全不同。我在这里错过了什么来理解这个概念?我失败了什么?

4 个答案:

答案 0 :(得分:3)

  

对于变量的方法,继承的工作方式看起来很不一样。

更确切地说,继承并不会使变量具有多态性。声明相同的方法时,派生类中的方法会覆盖基类中的方法。声明相同的变量时,基类中的变量将被派生类中的变量隐藏。

在您的示例中,Bar有两个变量a,但只有一个方法addFive()。实质上,每个Bar对象包含两个整数 - Foo.aBar.a。这两个是单独的变量。但是,addFive方法是Bar中定义的方法,因为它从addFive覆盖(替换)Foo

请注意,Java允许Bar通过调用Foo.addFive访问super.addFive(),但Bar的用户缺乏此可能性。

答案 1 :(得分:2)

变量不是多态的。只有方法。

但是,如果声明protectedpublic或通过setter和getters

,您可以从父类访问它们

答案 2 :(得分:0)

 Foo f = new Bar();

仅此一行意味着访问Bar中的实现和来自Foo的成员:)

因此,您将从a获取Foo,并从Bar

获取方法实施

答案 3 :(得分:0)

为了理解第1部分,您需要了解静态和动态绑定之间的区别。

静态绑定在编译期间发生,private,final和static方法和变量使用静态绑定。静态绑定使用Type(Class)信息进行绑定。

基于上面的定义,当行Foo f = new Bar();得到编译后,变量a被初始化为3。

使用动态绑定解决方法,动态绑定使用Object解析绑定。 由于对象属于Class Bar(),因此执行Bar类的addFive()方法。因此输出b3