web-dev-qa-db-ja.com

Javaインターフェースと戻り値の型

私が次のインターフェースを持っていると考えてください:

public interface A { public void b(); }

ただし、それを実装する各クラスに、メソッドb()の異なる戻り値の型が必要です。

例:

public class C { 
  public C b() {} 
}

public class D { 
  public D b() {} 
}

これを可能にするために、インターフェイスをどのように定義しますか?

34
Jonathan

戻り値の型がインターフェイスを実装するクラスの型でなければならない場合、必要なものは F-bounded type と呼ばれます。

_public interface A<T extends A<T>>{ public T b(); }

public class C implements A<C>{
  public C b() { ... }
}

public class D implements A<D>{
  public D b() { ... }
}
_

つまり、Aは、Tを実装する各具象型の値を取得する型パラメーターAを宣言しています。これは通常、適切に型指定されたclone()またはcopy()メソッドなどを宣言するために使用されます。別の例として、それは _Java.lang.Enum_ によって使用され、各列挙型の継承されたcompareTo(E)メソッドがその特定のタイプの他の列挙型にのみ適用されることを宣言します。

このパターンを頻繁に使用すると、thisTタイプにする必要があるシナリオに出くわします。一見するとそれが明らかであるように見えるかもしれません1ただし、実際には、実装者が_return this_として簡単に実装する必要があるabstract T getThis()メソッドを宣言する必要があります。

[1]コメンターが指摘したように、XYが適切に連携していれば、_X implements A<Y>_のような卑劣なことを行うことができます。 T getThis()メソッドの存在により、XAインターフェースの作成者の意図を迂回していることがさらに明確になります。

50
Matt McHenry

ジェネリック。

public interface A<E>{
    public E b();
}

public class C implements A<C>{
    public C b(){
        return new C();
    }
}

public class D implements A<D>{
    public D b(){
        return new D();
    }
}

詳細についてジェネリックを検索しますが、(非常に)基本的に、AEの型を実装クラス(CDに任せることになります) )。

したがって、基本的にAは、特定の実装でEが何であるかを知りません(知る必要もありません)。

37
Cam

Java 共変の戻り値の型をサポート (Java 1.5)以降)なので、次のことができます。

public interface A { public Object b(); }
2
meriton