Specifically, why would a variable declared in both a parent and child class be invisible in an instance of the child class passed to a method where the argument is the parent class?
Here is a simplified example of an issue that’s puzzling me. There are three classes, a parent and two child subtypes. The classes have a Foo object as a field and this static sort of factory method:
class Parent {
public Foo myFoo;
public static ThinChild createThinChild(Foo someFoo) {
ThinChild thinChild = new ThinChild(someFoo);
return thinChild;
}
public Foo getFoo() {
return myFoo;
}
}
class ThinChild extends Parent {
public Foo myFoo;
public ThinChild(Foo someFoo) {
myFoo = someFoo;
}
}
class ThickChild extends Parent {
public Foo myFoo;
public ThickChild(Foo someFoo) {
myFoo = someFoo;
}
}
Now consider this handler class:
class ChildHandler {
private void doSomethingToThinChild(ThinChild thinChild) {
assert(thinChild.getFoo() != null);
doSomethingToAllChildren(thinChild);
}
private void doSomethingToAllChildren(Parent thinOrThickChild) {
assert(thinOrThickChild.getFoo() != null);
}
}
When I call doSomethingToThinChild, the assert passes. But in the method doSomethingToAllChildren, the assert fails. This is not what I expect.
Moreover, if I add the same exact getFoo method that’s in the Parent class to my ThinChild class, the assert now works. Which solves my immediate problem but seems undesirable to me insofar as I’m now maintaining identical code in each of the child classes where I’d prefer just to maintain it in the parent.
My actual case is a bit more complicated, but I hope I’ve captured all the relevant details. Assuming that I have, is there any explanation for why this would be expected behavior?
It is possible that there’s an additional complication in my actual code that I haven’t represented here. But I’d first like to confirm that my understanding of class inheritance in Java is sound.
Thanks.
Remove
public Foo myFoo. In nested classes, this field extends from parent class. You can’t change it because you have 2 variables with same name. So JVM initialized the variable with the smaller scope.Also the good way is to create constructor in parent:
and then call it in subclasses: