2

这可能是一个奇怪的问题,但我不明白我是如何设法让它工作的。我的意图是从覆盖该字段的对象访问超级字段。首先,什么工作(1):

class Foo {
    protected int i = 0;

}

public class Bar extends Foo {
    int i = 1;
    Foo f() {
        return this;
    }
    public static void main (String[] args) {
        Bar b = new Bar();
        System.out.println(b.i);
        System.out.println(b.f().i);
    }
}

我首先尝试使用类似(2)的东西:

System.out.println(b.super.i);

这没有用。然后我尝试使用(3):

Foo f() {
    return super;
}

那也没有用。

所以,参考上面编号的部分:

  1. 为什么return this强制转换为 Foo 返回对 b.super 对象的引用?
  2. main中,我会认为b.super是对实例化对象 "b" 的超级引用的引用。有没有办法从包含对象访问对超级对象的引用?也许来自反射,但我不想访问 .class 对象(b.getClass().getSuper()),而是包含在 b 中的实例化 Foo。
  3. 为什么不return.super返回对 b.super 对象的引用?
4

5 回答 5

2

我的意图是从覆盖该字段的对象访问超级字段。

您没有“覆盖”该领域。您正在创建第二个不相关的同名字段。由此产生的名称冲突是您遇到困难的直接原因。

如果这两个字段不相关,请给它们不同的名称。

另一方面,如果您试图实现多态行为,请将它们转换为方法:

class Foo {
    protected int get_i() { return 0; }
}

public class Bar extends Foo {
    @Override
    protected int get_i() { return 1; }
}
于 2013-04-07T08:11:43.593 回答
1

您不需要反射,您需要在超类中定义 setter 和 getter 方法。

于 2013-04-07T08:05:17.410 回答
1

由于字段不能被覆盖,当您在子类中使用相同的名称时,它们将保持隐藏状态。这就是为什么如果您在子类中重新定义了字段,您将无法访问那些超类字段。

如果你想访问这些,你应该getters/setters在超类中提供。

于 2013-04-07T08:05:46.853 回答
1
  1. 因为字段不是以多态、动态的方式访问的。返回的对象的声明类型是Foo,因此Foo的字段被访问。字段不能被覆盖。在子类中定义i会创建另一个字段,该字段恰好与超类中的字段名称相同,因此将其隐藏。
  2. 不可能。您几乎不应该直接访问对象的字段。改用方法。
  3. 因为那是无效的 Java 代码。return super没有意义。super不是一个不同的对象。super并且this是同一个对象。
于 2013-04-07T08:10:05.563 回答
1

您的问题已回答:

  1. 为什么 return.this 强制转换为 Foo 返回对 b.super 对象的引用?

    • 它没有,确切地说。它返回对“this”的引用,它是 Bar 和 Foo 的一个实例,因为 Bar 扩展了 Foo。
  2. 总的来说,我认为 b.super 将是对实例化对象 "b" 的超级引用的引用。有没有办法从包含对象访问对超级对象的引用?也许来自反射,但我不想访问 .class 对象(b.getClass().getSuper()),而是包含在 b 中的实例化 Foo。

    • b 和 b.super 是一回事。您可以毫无问题地从条形码访问受 Foo 保护的字段
  3. 为什么 return.super 不返回对 b.super 对象的引用?

    • 同样, b 和 b.super 是同一个实例。
于 2013-04-07T08:20:23.847 回答