class One {
public One foo() { return this; }
}
class Two extends One {
public One foo() { return this; }
}
class Three extends Two {
public Object foo() { return this; }
}
public Object foo() { return this; } throws a compilation error. Why is that? Can someone explain why "Object" type is not possible? Is Object the base class of Class One, Two? If So why does it throws an error?
Please change the title of the question as I couldnt find a suitable title.
-
You are changing the signature of the foo method in a way not supported. Polymorphism only works for different argument list, not for identical methods only different by the return type.
And if you think about it, it is quite natural... If it worked and someone who only knows about one of the two super classes would call Three.foo() he would expect it to return a One (because that is how it works in One and Two) but in Three you could actually return a HashMap and still behave correctly.
Jon (in the comment below) is correct, you can narrow the scope but then you would still follow the protocol that you will return a "One" (should you return a Three from Three.foo()) because subclasses will all implement the superclass interface. However, return type is still not part of the polymorphism, hence you cannot have three different methods that only differs by return type.
Jon Skeet : Not true. You can override by making the return type *more* specific.Fredrik : I was about to say that in an edit but you were two quick for me :-) -
Three.foois trying to overrideTwo.foo(), but it doesn't do it properly. Suppose I were to write:One f = new Three(); One other = f.foo();Ignoring the fact that actually
Three.foo()does return aOne, the signature ofThree.foo()doesn't guarantee it. Therefore it's not an appropriate override for a method which does have to return aOne.Note that you can change the return type and still override, but it has to be more specific rather than less. In other words, this would be okay:
class Three extends Two { public Three foo() { return this; } }because
Threeis more specific thanOne. -
It would enable:
class Four extends Three { public Object foo() { return "This String is not an instance of One"; } } -
Overriding a method and trying to return a less specific type is a violation of the Liskov substitution principle, which says that subclasses must fulfill all contracts of their superclass. Your class Three violates the superclass contract "foo() returns an instance of One".
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.