从子类对象访问超级字段

时间:2013-04-07 08:02:32

标签: java inheritance

这可能是一个奇怪的问题,但我不明白我是如何设法让它工作的。我的目的是从一个覆盖该字段的对象访问super的字段。首先,做了什么工作(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对象的引用?

5 个答案:

答案 0 :(得分:2)

  

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

你不是“压倒”这个领域。您正在创建具有相同名称的第二个不相关的字段。由此产生的名称冲突是造成困难的直接原因。

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

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

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

public class Bar extends Foo {
    @Override
    protected int get_i() { return 1; }
}

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

如果你想访问它们,你应该在超类中提供getters/setters

答案 3 :(得分:1)

  1. 因为不能以多态,动态的方式访问字段。返回的对象的声明类型是Foo,因此访问Foo的字段。字段无法覆盖。在子类中定义i会创建另一个恰好与超类中的字段相同的字段,从而隐藏它。
  2. 没办法。你应该永远不要直接访问对象的字段。改用方法。
  3. 因为那是无效的Java代码。 return super毫无意义。 super不是一个不同的对象。 superthis是同一个对象。

答案 4 :(得分:1)

您的问题已经回答:

  1. 为什么return.this cast to 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是同一个实例。