问题
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:
- Why does
return thiscast to Foo return a reference to the b.super object? - In
main, I would have thoughtb.superwould 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. - Why does
return.supernot 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:
- 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
iin the subclass creates another field that happens to have the same name as the one in the superclass, and thus hides it. - There's no way. You should amost never access fields of an object directly. Use methods instead.
- Because that's invalid Java code.
return supermakes no sense.superis not a different object.superandthisare the same object.
回答4:
You don't need reflection, you need to define setter and getter methods in your superclass.
回答5:
Your questions answered:
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.
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
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