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

dro*_*y11 0 java constructor

以下示例的问题是,我已阅读到,如果您覆盖一个函数,则除非更改后代对象,否则无法更改返回类型,在这种情况下,您可以将返回类型从更改为ParentClassChildClass但不是这样在任何一种情况下。在第一个示例中,我们将返回类型从String更改为Object,在第二个示例中将其从Object更改为String,这两个都不是类A或B。也许是这样的情况,您可以在任何覆盖的函数中返回更具体的类型?

我:这绝对是错误的,因为在覆盖时您将返回一个更通用的类型。

 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";
  }
}
Run Code Online (Sandbox Code Playgroud)

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 Object getValue() {
    return "Any object";
  }
}

class A extends B {
  public String getValue() {
    return "A string";
  }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

第二个很好,因为JLS 8.4.8.3中的规则:

如果返回类型为R1的方法声明d1覆盖或隐藏了返回类型为R2的另一个方法d2的声明,则d1必须是d2的返回类型可替换的(第8.4.5节),否则会发生编译时错误。

此规则允许使用协变返回类型-重写方法时完善其返回类型。

Object是的超类String,因此可以将先前声明为return的方法Object在子类重写中完善为return String

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

String x = ...; // Anything here
Object y = x; // No problem
Run Code Online (Sandbox Code Playgroud)

听起来您在这里对这两对类型感到困惑:

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

那些有四个完全独立的类-在这里BAObjectString分别。