Reputation: 97681
I have code that looks like this:
public class A
{
public void doStuff()
{
System.out.print("Stuff successfully done");
}
}
public class B extends A
{
public void doStuff()
{
System.out.print("Stuff successfully done, but in a different way");
}
public void doMoreStuff()
{
System.out.print("More advanced stuff successully done");
}
}
public class AWrapper
{
public A member;
public AWrapper(A member)
{
this.member = member;
}
public void doStuffWithMember()
{
a.doStuff();
}
}
public class BWrapper extends AWrapper
{
public B member;
public BWrapper(B member)
{
super(member); //Pointer to member stored in two places:
this.member = member; //Not great if one changes, but the other does not
}
public void doStuffWithMember()
{
member.doMoreStuff();
}
}
However, there is a problem with this code. I'm storing a reference to the member in two places, but if one changes and the other does not, there could be trouble. I know that in Java, an inherited method can narrow down its return type (and perhaps arguments, but I'm not certain) to a derived class. Is the same true of fields?
Upvotes: 3
Views: 191
Reputation: 29240
You can accomplish this better with generics.
public class AWrapper<T extends A>
{
public T member;
public AWrapper(T member)
{
this.member = member;
}
public void doStuffWithMember()
{
a.doStuff();
}
}
public class BWrapper extends Wrapper<B>
{
public BWrapper(B member)
{
super(member);
}
public void doStuffWithMember()
{
member.doMoreStuff();
}
}
The fact that the subclass wrapper specifies the type of B allows you to access B's functions in the BWrapper, without storing an additional reference.
Upvotes: 3
Reputation: 68907
In your class BWrapper
you have to remove the line public B member;
. And in the method doMoreStuffWithMember()
replace the line with:
((B) member).doMoreStuff();
Upvotes: 0