why we can't override a method and define it to return a superclass of the original method?

大兔子大兔子 提交于 2019-12-02 06:09:33

问题


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() {
    ...
}

回答1:


Imagine if it was possible:

public class CarFactory {
    Car giveMeACar() { ... };
}

public class SpecialCarFactory extends CarFactory {
    @Override
    Object giveMeACar() {
        return "hello world";
    }
)

public class Driver {
    void drive() {
        CarFactory carFactory = new SpecialCarFactory();

        Car car = carFactory.giveMeACar();
        // err, wait, sorry, can't do that. 
        // This car factory, despite its name, doesn't produce cars. 
        // It produces objects, and I've heard they're just 
        // "hello world" strings. Good luck driving a "hello world"
        // string on a highway!
    }
}

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).




回答2:


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 ImaginaryNumber with its correspoding funtionality. If suddenly someone oveeride this method to return only a regular Number, the callers of that method will break as they rely on getting an ImaginaryNumber (maybe they are calliing something like getImaginaryPart() 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.




回答3:


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 :

SuperClass instance = ...
Number num = instance.returnANumber();

Now, instance may be an instance of any sub-class of SuperClass, some of which may override returnNumber(). If the overriding method returns a sub-class of Number, it still returns a Number (any sub-class of Number is still a Number), so the assignment is still valid. If the overriding method could return a super class of Number, the assignment wouldn't be valid anymore, and therefore it's not allowed.



来源:https://stackoverflow.com/questions/36418671/why-we-cant-override-a-method-and-define-it-to-return-a-superclass-of-the-origi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!