Java 为什么我们不能重写一个方法并将其定义为返回原始方法的超类?

Java 为什么我们不能重写一个方法并将其定义为返回原始方法的超类?,java,return,overriding,subclass,Java,Return,Overriding,Subclass,我目前正在学习Java类和对象,遇到了以下语句和代码。我理解这个概念,但我不知道为什么我们不能重写一个方法并定义它以返回原始方法的超类?背后的原因是什么?有人能告诉我吗?提前感谢您的帮助 您可以重写一个方法并将其定义为返回 原始方法,如下所示: 覆盖原始方法: public ImaginaryNumber returnANumber() { ... } 重写一个方法以返回一个更一般的类(即超类)是没有意义的,因为在这种情况下,您违反了至少返回一个ImaginaryNumber及其相应函

我目前正在学习Java类和对象,遇到了以下语句和代码。我理解这个概念,但我不知道为什么我们不能重写一个方法并定义它以返回原始方法的超类?背后的原因是什么?有人能告诉我吗?提前感谢您的帮助

您可以重写一个方法并将其定义为返回 原始方法,如下所示:

覆盖原始方法:

public ImaginaryNumber returnANumber() {
    ...
}

重写一个方法以返回一个更一般的类(即超类)是没有意义的,因为在这种情况下,您违反了至少返回一个ImaginaryNumber及其相应函数的约定。如果突然有人放弃了这个方法,只返回一个常规的数字,那么这个方法的调用方就会中断,因为他们依赖于获取一个ImaginaryNumber,也许他们调用的是像getImaginaryPart这样的东西,这对于一个非虚数字来说是没有意义的


另一种方法,例如返回子类,即更具体的类不会破坏约定,因为子类至少具有与超类相同的功能。

当有人编写使用超类的代码时,他们只依赖由超类定义的约定

所以你可以这样写:

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

现在,instance可以是超类的任何子类的实例,其中一些可以覆盖returnNumber。如果重写方法返回一个子类Number,它仍然返回一个数字。任何子类Number仍然是一个数字,因此赋值仍然有效。如果重写方法可以返回一个数字的超类,那么赋值将不再有效,因此它是不允许的。

想象一下如果可能的话:

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!
    }
}
看,这只是一个合同问题。当你去咖啡店时,你希望它能卖咖啡。如果不遵守本合同,就不能称之为咖啡店:咖啡店必须出售咖啡。
它可以出售牛奶咖啡,因为牛奶咖啡仍然是咖啡。就像汽车工厂只能生产丰田一样,因为丰田是一辆汽车,你可以像其他汽车一样驾驶丰田,甚至不知道它是丰田:这是多态性。

@KevinEsche,这不太准确。您可以重写一个方法来返回一个子类。@shmosel是的,您是对的。教程已经解释了为什么不可以:但是,对象不一定是一个数字,它可以是字符串或其他类型。客户端可能只通过超类型知道您的类,因此在这种情况下需要一个数字。在这种情况下,如果给它一个超类型的Number对象或可序列化,它将中断。每个ImaginaryNumber都是一个数字,但每个数字都不是一个ImaginaryNumber给定的ImaginaryNumber扩展/实现数字
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!
    }
}