2012-04-13 9 views
6

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

慣例として、メソッドのオーバーライドでは、スーパークラスとサブクラスの両方で同じシグネチャ(戻り値付き)が使用されます。上記のコードでは、SuperClassgetList()メソッドの戻り値の型はListであり、戻り値の型はArrayListです。メソッドオーバーライドはどのように機能しますか?ところで

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

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

+0

(むしろ 'ArrayList'より)' List'として 'SubClass.list'を宣言するためには良い理由があるようですません。 –

+0

@ MichaelBrewer-Davis - 'SuperClass'のように扱うのではなく、' SubClass'を直接使用しているときには、より良いものにすることができます。 –

+0

@Brendan - 私は(プライベート)メンバー変数があまりにも一般的であり、メソッドがあまりにも具体的ではないと話していました。メソッドの共分散は日照と蝶です。 –

答えて

19

はい。

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

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

この情報のソースは、もは​​やインターウェブ上で利用できません。

+0

リンクが切れています。 – Ghos3t

3

はい、正しいです。 ArrayListはListであるため、元のメソッドがListを返したときにArrayListを返すことができます。

4

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

+0

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