9

次のコードは、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);
        }
    }
}

慣例により、メソッドのオーバーライドでは、スーパークラスとサブクラスの両方で同じシグニチャ(リターンタイプ)が使用されます。上記のコードでは、getList()メソッドの戻り型はSuperClassisListであり、そのサブクラスでは戻り型はArrayListです。ここでメソッドのオーバーライドはどのように機能しますか?

ちなみに、これがインターフェースArrayListの実装であることは明らかですが、コンパイラーはメソッドListをオーバーライドしながら、ここで戻り型をどのように処理しますか?getList()

このようなことを信じるべきですか...オーバーライドされたメソッドの戻り型は、オーバーライドされたメソッドの戻り型のサブタイプであることが許可されています。

4

4 に答える 4

20

はい。

初期のJavaではそうではありませんでしたが、Java5.0で変更されました。

リターンタイプのみが異なるシグニチャを持つ同じクラスに2つのメソッドを含めることはできません。J2SE 5.0リリースまでは、クラスがスーパークラスから継承するメソッドの戻り型をオーバーライドできないことも事実でした。このヒントでは、共変リターン型を可能にするJ2SE5.0の新機能について学習します。これが意味するのは、サブクラスのメソッドは、スーパークラスの同じシグニチャを持つメソッドによって返されるタイプのサブクラスであるタイプのオブジェクトを返す可能性があるということです。この機能により、過剰な型チェックとキャストの必要がなくなります。

この情報のソースは、インターウェブでは利用できなくなりました。

于 2012-04-13T02:41:57.310 に答える
5

オブジェクト指向プログラミングでは、メソッドの共変戻り型は、メソッドがサブクラスでオーバーライドされたときに「より狭い」型に置き換えることができるものです。これがかなり一般的なパラダイムである注目すべき言語は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();
     }
 }

より具体的には、共変(ワイドからナロー)またはコントラバリアント(ナローからワイド)のリターンタイプは、オーバーライドするメソッドのリターンタイプが、元のオーバーライドされたメソッドのリターンタイプに関連する(ただし異なる)タイプに変更される状況を指します。 。

2つの共変リターンタイプ間の関係は、通常、リスコフの置換原則に従って、一方のタイプをもう一方のタイプに置換できる関係です。

これは通常、オーバーライドするメソッドの戻り型が、オーバーライドされるメソッドの戻り型のサブタイプになることを意味します。上記の例は、そのような場合を具体的に示しています。置換が許可されていない場合、戻りタイプは不変であり、コンパイルエラーが発生します。

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

于 2012-07-05T08:51:27.077 に答える
3

はい、その通りです。ArrayListはリストであるため、元のメソッドがリストを返したときにArrayListを返すことができます。

于 2012-04-13T02:43:37.147 に答える
0

OPの例のjavapコマンドでバイトコードを確認したところ、コンパイラがSubClassクラスに追加のメソッドを生成していることがわかりました。

//1
public java.util.List getList();

を呼び出す

//2
public java.util.ArrayList getList();

メソッドとその結果を返します。

SubClass sc=new SubClass();
//the ArrayList getList() will be invoked:
sc.getList();

SuperClass s=...;
//the List getList() will be invoked:
s.getList();
于 2021-04-27T18:29:34.300 に答える