getValue()方法以两种方式被覆盖。哪一个是正确的?

时间:2016-02-15 16:48:02

标签: java constructor

我对以下示例的问题是我已经读过如果覆盖一个函数,除非你覆盖一个后代对象,否则不能更改返回类型,在这种情况下你可以改变{{1}的返回类型到ParentClass,但在这两种情况中都不是这种情况。我们在第一个示例中将返回类型从String更改为Object,在第二个示例中将Object更改为Object,它们都不是A类或B类。也许您可以在任何被覆盖的函数中返回更具体的类型?

I:这个肯定是假的,因为你在覆盖时会返回一个更通用的类型。

ChildClass

II:这一定是正确的,但我不明白,因为我认为你只能覆盖从B类返回类型B到A类中的A类。这是唯一的例外,在以前的Java版本中,即使这是不允许的,所以我不知道如何将Object更改为String。

 public class Test {
  public static void main(String[] args) {
    A a = new A();
    System.out.println(a.getValue());
  }
}

class B {
  public String getValue() {
    return "Any object";
  }
}

class A extends B {
  public Object getValue() {
    return "A string";
  }
}

2 个答案:

答案 0 :(得分:4)

第二种情况很好,因为JLS 8.4.8.3中的这条规则:

  

如果返回类型为R1的方法声明d1覆盖或隐藏了另一个返回类型为R2的方法d2的声明,那么对于d2,d1必须是return-type-substitutable(第8.4.5节),或者是编译时错误发生。

     

此规则允许协变返回类型 - 在覆盖方法时优化方法的返回类型。

ObjectString的超类,因此对于先前声明为返回Object的方法,在子类覆盖中进行优化以返回String

没关系,因为任何只知道超类方法的代码都会将返回值用作Object,并且可以使用任何String引用作为Object引用,例如

String x = ...; // Anything here
Object y = x; // No problem

听起来你在这两种类型之间感到困惑::

  • 声明方法和类重写它的类
  • 原始方法中的返回类型和覆盖中的返回类型

这是四个完全独立的课程 - 分别来自BAObjectString

答案 1 :(得分:1)

全部约为Covariant return type

看看这篇文章它会对你有所帮助。