为什么我不能更改覆盖方法的返回类型(协变返回类型除外)?

请注意 - 我在问为什么?如果您能给出一个更改返回类型实际上会破坏代码的示例,那将非常有用


为什么我不能更改重写方法的返回类型(协变返回类型除外)。


class Parent{


   public void sayhello(){ ... };


}


class Child extends Parent{


    public String sayhello() { . . .}


}

现在,如果我运行以下代码:


class test{


    public static void main(String[] args){


       Parent p = new Child();

       p.sayHello(); 


        }

    }

凸轮某人请确认是否正在发生以下步骤:

  1. 编译器找出父对象“p”的类型。

  2. 编译器检查父类中是否存在方法“sayHello()”。

  3. 在 Runtime 期间,JVM 发现它是一个 Child 对象并调用该方法的子版本。

  4. 子方法被调用。

谢谢。


呼唤远方
浏览 109回答 3
3回答

慕无忌1623718

让我们用一个简单的例子来解释为什么改变重写方法的返回类型没有任何意义。假设我有一个Car对象:class Car {    public String getModel() {        return "Awesome Car";    }}此类Car有一个方法getModel()返回一个String.现在,您有另一个扩展Car并覆盖该getModel()方法的类:class DumbCar extends Car {    @Override    public Hamburger getModel() {        return new Hamburger();    }}突然间,你遇到了一个大问题。您创建了一个DumbCar对象,因为您知道所有Car对象都可以告诉您它们的模型,所以您尝试获取该模型:DumbCar myCar = new DumbCar();System.out.println(myCar.getModel());输出是A juicy Big Mac!这对你有意义吗?你不能驾驶巨无霸。Java 是一种高度类型安全的语言。当你写一个要求的声明时getModel(),你需要绝对地,100% 肯定,你得到的数据是你所期望的。Java 强制执行该期望。

幕布斯6054654

问题基本上是这样的事情会使 Java 类型系统不健全,并且由于 Java 有一个静态类型系统,这是不允许的。假设你有一个Expression接口:interface Expression {    Integer evaluate();}现在你有了一个Addition实现:class Addition implements Expression {   private Expression left;   private Expression right;   Addition(Expression left, Expression right) {       this.left = left;       this.right = right;   }   @Override   public Integer evaluate() {     return left.evaluate() + right.evaluate();   }}只要表达式计算为整数,这就有效,例如class Constant implements Expression {   private Integer value;   Constant(Integer value) {       this.value = value;   }   @Override   public Integer evaluate() {       return this.value;   }}这允许我们做这样的事情:Expression left = new Constant(1);Expression right = new Constant(2);Expression addition = new Addition(left, right);Integer result = addition.evaluate();如果你有一个表达式,而不是评估Integer为其他不是表达式的东西,比如 aCat或 a ,现在会发生什么Dog?它会立即破坏您过去编写的所有其他表达式的可靠性,例如上一个示例的表达式,或者我们在假设Addition.evaluate和表达式返回 not 或 的方法left中right所做Integer的Cats明显假设Dogs。

慕桂英4014372

Java 是一种静态类型语言。这意味着编译器会在程序运行之前检查所有类型是否有意义。因此,您不会在运行时出现错误,因为某些方法或字段不“存在”。为了使它工作,如果你有这样的代码MyBean x = something.getMyBean();不允许编译器确定类型的子类something将返回类型更改getMyBean()为除此之外的其他MyBean类型(也允许子类MyBean,这称为缩小返回类型——但即使那样也是不可能的Java 5 之前)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java