Java 中的协变返回类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10134571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 23:43:59  来源:igfitidea点击:

Covariant return type in Java

java

提问by Lion

The following code uses the concept of method overriding in Java.

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

package pkg;

import java.util.ArrayList;
import java.util.List;

abstract class SuperClass
{
    abstract public List<String>getList();
}

final class SubClass extends SuperClass
{
    private List<String>list=null;

    @Override
    public ArrayList<String> getList()
    {
        list=new ArrayList<String>();
        list.add("A");
        list.add("B");
        return (ArrayList<String>) list;
    }
}

final public class Main
{
    public static void main(String[] args)
    {
        SuperClass s=new SubClass();
        List<String>list=s.getList();

        for(String str:list)
        {
            System.out.println(str);
        }
    }
}

By convention, method overriding uses the same signature (with return type) in both super class and subclass. In the above code, the return type of the getList()method in the SuperClassis Listand in its subclass the return type is ArrayList. How does method overriding work here?

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

By the way, it's obvious that ArrayListis an implementation of the Listinterface but how does the compiler treat the return type here while overriding the getList()method?

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

Should I believe something like this... The return type of the overridden method is allowed to be a subtype of the overridden method's return type.

我应该相信这样的事情吗...重写方法的返回类型允许是重写方法返回类型的子类型。

回答by emory

Yes.

是的。

In early java that was not the case, but it was changed in Java 5.0.

在早期的 Java 中并非如此,但在 Java 5.0 中发生了变化。

You cannot have two methods in the same class with signatures that only differ by return type. Until the J2SE 5.0 release, it was also true that a class could not override the return type of the methods it inherits from a superclass. In this tip you will learn about a new feature in J2SE 5.0 that allows covariant return types. What this means is that a method in a subclass may return an object whose type is a subclass of the type returned by the method with the same signature in the superclass. This feature removes the need for excessive type checking and casting.

同一类中不能有两个方法的签名仅因返回类型不同而不同。在 J2SE 5.0 发布之前,类不能覆盖它从超类继承的方法的返回类型也是事实。在本技巧中,您将了解 J2SE 5.0 中允许协变返回类型的新特性。这意味着子类中的方法可能返回一个对象,该对象的类型是超类中具有相同签名的方法返回的类型的子类。此功能消除了对过度类型检查和强制转换的需要。

The source of this information is no longer available on the interwebs.

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

回答by AZ_

In object-oriented programming, a covariant return type of a method is one that can be replaced by a "narrower" type when the method is overridden in a subclass. A notable language in which this is a fairly common paradigm is C++. Covariant return types have been (partially) allowed in the Java language since the release of JDK5.0, so the following example wouldn't compile on a previous release:

在面向对象的编程中,当方法在子类中被重写时,方法的协变返回类型可以被“更窄”的类型替换。这是一种相当常见的范式,其中一种值得注意的语言是 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();
     }
 }

More specifically, covariant (wide to narrower) or contravariant (narrow to wider) return type refers to a situation where the return type of the overriding method is changed to a type related to (but different from) the return type of the original overridden method.

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

The relationship between the two covariant return types is usually one which allows substitution of the one type with the other, following the Liskov substitution principle.

两种协变返回类型之间的关系通常是一种关系,它允许根据 Liskov 替换原则将一种类型替换为另一种类型。

This usually implies that the return types of the overriding methods will be subtypes of the return type of the overridden method.The above example specifically illustrates such a case. If substitution is not allowed, the return type is invariant and causes an compile error.

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

Reference: https://en.wikipedia.org/wiki/Covariant_return_type

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

回答by lrAndroid

Yes, that is correct. Since an ArrayList is a List, you can return an ArrayList when the original method returned a List.

对,那是正确的。由于 ArrayList 是一个 List,所以当原始方法返回一个 List 时,您可以返回一个 ArrayList。