I'm currently learning Java classes and objects from java tutorial oracle and have encountered the following statements and code. I understand the concept but I do not know why we can't override a method and define it to return a superclass of the original method? What is the reason behind it? Could someone please enlighten me? Thanks in advance for any help!
You can override a method and define it to return a subclass of the original method, like this:
public Number returnANumber() {
...
}
Override original method:
public ImaginaryNumber returnANumber() {
...
}
It doesn' make sense to override a method to return a more "general" class (i.e. a superclass), because in this case you are breaking the "contract" of returning "at least" a
ImaginaryNumbe
r with its correspoding funtionality. If suddenly someone oveeride this method to return only a regularNumber
, the callers of that method will break as they rely on getting anImaginaryNumber
(maybe they are calliing something likegetImaginaryPart()
which does not make sense for a non-imaginary number).The other way round (e.g. returning a subclass, that is, a more specific class) does not break the contract, because the subclass has at least the same functionality as the superclass.
Imagine if it was possible:
See, it's just a contract thing. When you go to a coffee shop, you expect it to sell coffee. Something can't be called "a coffee shop" if it doesn't comply to this contract: a coffee shop must sell coffee. It can sell milked coffee, because a milked coffee is still a coffee. (just like a car factory can produce Toyota only, because Toyota is a car, and you can drive a Toyota like any other car, without even knowing it's a Toyota: that's polymorphism).
When someone writes code that uses the super-class, they only rely on the contract defined by the super-class.
So you can write something like this :
Now,
instance
may be an instance of any sub-class ofSuperClass
, some of which may overridereturnNumber()
. If the overriding method returns a sub-class ofNumber
, it still returns aNumber
(any sub-class ofNumber
is still aNumber
), so the assignment is still valid. If the overriding method could return a super class ofNumber
, the assignment wouldn't be valid anymore, and therefore it's not allowed.