Java中的协变返回类型

以下代码使用Java中方法覆盖的概念。

package pkg; import java.util.ArrayList; import java.util.List; abstract class SuperClass { abstract public ListgetList(); } final class SubClass extends SuperClass { private Listlist=null; @Override public ArrayList getList() { list=new ArrayList(); list.add("A"); list.add("B"); return (ArrayList) list; } } final public class Main { public static void main(String[] args) { SuperClass s=new SubClass(); Listlist=s.getList(); for(String str:list) { System.out.println(str); } } } 

按照惯例,方法重写在超类和子类中都使用相同的签名(带有返回类型)。 在上面的代码中, getList()方法的返回类型是List ,在其子类中返回类型是ArrayList 。 方法覆盖如何在这里工作?

顺便说一句,很明显ArrayListList接口的一个实现,但是在重写getList()方法时,编译器如何处理返回类型?

我应该相信这样的事情…… 被覆盖方法的返回类型被允许是被重写方法的返回类型的子类型。

是。

在早期的Java中并非如此,但它在Java 5.0中已经改变了。

您不能在同一个类中拥有两个方法,其签名只有返回类型不同。 在J2SE 5.0发布之前,类也无法覆盖从超类inheritance的方法的返回类型。 在本技巧中,您将了解J2SE 5.0中允许协变返回类型的新function。 这意味着子类中的方法可以返回一个对象,该对象的类型是由超类中具有相同签名的方法返回的类型的子类。 此function消除了过多类型检查和转换的需要。

互联网上不再提供此信息的来源。

在面向对象的编程中,方法的协变返回类型是在子类中重写方法时可以用“较窄”类型替换的类型。 一种值得注意的语言是C ++,这是一种相当普遍的范例。 自JDK5.0发布以来,已经(部分)允许在Java语言中使用协变返回类型,因此以下示例不会在先前版本上进行编译:

  // Classes used as return types: class A { } class B extends A { } // "Class B is more narrow than class A" // Classes demonstrating method overriding: class C { A getFoo() { return new A(); } } class D extends C { B getFoo() { return new B(); } } 

更具体地说,协变(从宽到窄)或逆变(从窄到宽)返回类型是指将覆盖方法的返回类型改变为与原始重写方法的返回类型相关(但不同)的类型的情况。 。

两个协变返回类型之间的关系通常是允许用Liskov替换原则替换另一个类型的关系。

这通常意味着重写方法的返回类型将是重写方法的返回类型的子类型。 上面的例子具体说明了这种情况。 如果不允许替换,则返回类型是不变的并导致编译错误。

参考: https : //en.wikipedia.org/wiki/Covariant_return_type

对,那是正确的。 由于ArrayList是List,因此当原始方法返回List时,可以返回ArrayList。