Java class question

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; } public Object foo() { return this; } throws a compilation error. Why is this? Can someone explain why the type β€œObject” is not possible? Is an object a base class of class one, two? If so, why is this causing an error?

Please change the title of the question, as I could not find a suitable title.

+4
source share
4 answers

Three.foo trying to override Two.foo() , but it is not doing it right. Suppose I had to write:

 One f = new Three(); One other = f.foo(); 

Ignoring the fact that Three.foo() actually returns a One , the signature of Three.foo() does not guarantee it. Therefore, this is not a suitable override for the method that One should return.

Please note that you can change the return type and still override it, but it should be more specific, not less. In other words, this will be fine:

 class Three extends Two { public Three foo() { return this; } } 

because Three more specific than One .

+16
source

You change the signature of the foo method in a way that is not supported. Polymorphism works only for different lists of arguments, and not for identical methods that differ only in the type of return value.

And if you think about it, it’s quite natural ... If it works, and someone who knows only about one of the two superclasses calls Three.foo (), he expects it to return One (because it's like this works in One and Two), but in Three you really can bring back the HashMap and still behave correctly.

Jon (in the comment below) is correct, you can narrow the scope, but then you will still follow the protocol in which you will return β€œOne” (if you return β€œThree from Three.foo ()), because subclasses will be all implement the superclass interface, however, the return type is still not part of the polymorphism, so you cannot have three different methods that differ only in the type of return value.

+5
source

This will allow:

 class Four extends Three { public Object foo() { return "This String is not an instance of One"; } } 
+2
source

Overriding a method and attempting to return a less specific type violates the Liskov substitution principle , which states that subclasses must fulfill all the contracts of their superclass. Your class Three violates the contract for the superclass. "Foo () returns an instance of One."

+2
source

All Articles