Access super field from subclass object

青春壹個敷衍的年華 提交于 2019-12-24 14:12:28

问题


This may be a strange question, but I don't understand how have I managed to get this to work. My intention was to access the super's field from an object that overrides the field. First, what did work (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);
    }
}

I first tried to use something like (2):

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

which didn't work. I then tried to use (3):

Foo f() {
    return super;
}

and that didn't work either.

So, referring to the numbered parts above:

  1. Why does return this cast to Foo return a reference to the b.super object?
  2. In main, I would have thought b.super would be the reference to the instantiated object "b" 's super reference. Is there any way to access the reference to the super object from the containing object? Maybe something from reflection, but I don't want access to the .class object (b.getClass().getSuper()), but rather the instantiated Foo contained within b.
  3. Why does return.super not return a reference to the b.super object?

回答1:


My intention was to access the super's field from an object that overrides the field.

You are not "overriding" the field. You are creating a second, unrelated field with the same name. The resulting name clash is the direct cause of your difficulty.

If the two fields are unrelated, give them different names.

If, on the other hand, you are trying to achieve polymorphic behaviour, turn them into methods:

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

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



回答2:


since fields can not be overridden, they remains hidden when you use the same name in sub classes. Thats why you can not access those super class fields if you have redefined field in subclasses.

if you want to access those, you should provide getters/setters in superclass.




回答3:


  1. Because fields are not accessed in a polymorphic, dynamic way. The declared type of the object returned is Foo, so Foo's field is accessed. Fields can't be overridden. Defining i in the subclass creates another field that happens to have the same name as the one in the superclass, and thus hides it.
  2. There's no way. You should amost never access fields of an object directly. Use methods instead.
  3. Because that's invalid Java code. return super makes no sense. super is not a different object. super and this are the same object.



回答4:


You don't need reflection, you need to define setter and getter methods in your superclass.




回答5:


Your questions answered:

  1. Why does return.this cast to Foo return a reference to the b.super object?

    • It does not, exactly. It returns a reference to 'this' which is an instance of Bar and also of Foo, because Bar extends Foo.
  2. In main, I would have thought b.super would be the reference to the instantiated object "b" 's super reference. Is there any way to access the reference to the super object from the containing object? Maybe something from reflection, but I don't want access to the .class object (b.getClass().getSuper()), but rather the instantiated Foo contained within b.

    • b and b.super are one and the same. You can access Foo protected fields from Bar code without a problem
  3. Why does return.super not return a reference to the b.super object?

    • Again, b and b.super are the same instance.


来源:https://stackoverflow.com/questions/15860206/access-super-field-from-subclass-object

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!