【问题标题】:Java - Problems with understanding inheritanceJava - 理解继承的问题
【发布时间】:2016-11-17 14:34:37
【问题描述】:

我在 Java 中遇到了一些关于继承的问题。 我不明白为什么以下两个程序有这些输出! 有人可以帮我吗? :)

1)

public class A {
    int foo() {
        return 1;
    }
}

public class B extends A {
    int foo() {
        return 2;
    }
}

public class C extends B {
    int bar(A a) {
        return a.foo();
    }
}

C x = new C();  
System.out.println(x.bar(x));

// OUTPUT:2

2)

public class A {
    int e=1;
}

public class B extends A {
    int e=2;
}

public class C extends B {
    int bar(A a){
        return a.e;
    }
}

C x= new C();
System.out.println(x.bar(x));

// OUTPUT:1

【问题讨论】:

    标签: java inheritance


    【解决方案1】:

    在这两种情况下,您都将C 类型的对象传递给打印函数。 bar 函数请求A 类型的对象,但您仍然可以传入C 类型的对象,因为它是A 的子类。所以首先,重要的是要记住 a.foo()a.e 是在 C 对象上调用的。

    所以在这两种情况下发生的是它正在搜索列表中最低的属性或方法。这是 Java 在第 1 部分中所做工作的一个非常简化的版本:

    1. 嘿,您已将C 类型的对象传递给bar 方法!现在让我们调用它的foo 方法。
    2. 哎呀! C 没有 foo 方法!让我们对B 类进行下一步,看看它是否有foo 方法。
    3. 耶! B 有一个 foo 方法,所以我们调用它。无需继续努力学习A 课程,因为我们已经在 B 中找到了我们需要的内容。

    这完全是为了理解参数从A 向下转换为C。第 2 部分使用了完全相同的逻辑。它注意到传入了 C 类型的对象,因此它从对象 B 获取 e 属性,因为它是层次结构中包含该属性的最低类属性。

    希望能回答你的问题!

    【讨论】:

    • 您对示例 2 有误 - 输出为“1”。 B类有自己的成员e,对外隐藏。如果 B 没有成员 e 但为其设置了一个值,我们会得到一个输出“2”,但事实并非如此,我们读取的是 A 类的成员值
    • 嗯,按照你的逻辑,第二个程序中的答案应该是 2,不是吗?
    • @Johanna 是我的问题吗?
    • 不,问题是给 Jake Fairbaim,但如果你能更好地向我解释,我没有问题:p
    • @Johanna 我已经做到了。 Jake Fairbairn 对示例 1 是正确的 - 有虚拟方法有效,但在第二个中,来自 B 的成员 e 不会覆盖来自 A 的成员。类就像一个结构:{members; [虚函数表]}。当一个应用程序被执行,并且你调用一个方法时,JVM 在一个表中查找它并调用一个真实对象的函数,但它不能为一个成员解析类似的东西,所以它只给你一个 A。
    猜你喜欢
    • 2014-02-22
    • 1970-01-01
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多