2016-08-24 15 views
1

私は以下のようになりますいくつかのコードを探しています:Javaのジェネリック型

public class Parent<T is_or_extends Parent<T>> { 
    public T function() { 
     // do some stuff // 
     return correct(); 
    } 
    public T correct() { 
     return (T) this; 
    } 
} 

これは、任意の子クラスは、他の親機能にアクセスする必要がありますそうです、まだ意志独立したクラスのままになります(function()の戻り値をParentのインスタンスにアップキャストしません)。 そして、プログラマは(戻りオブジェクトをダウンキャスト)(その親のインスタンスが機能せずに作成することができます)独立だけでなく親クラスを使用することができます

実装:

public class Child extends Parent<Child> {} 

は使用方法:

Child child = new Child(); // ok 
Parent<Child> polymorph = new Child(); // ok 
Parent<Parent> parent = new Parent<Parent>(); // ERROR! 

違いを説明するだけで、これはメソッド連鎖の問題ではありません。親クラスが子クラスのジェネリックを取り込むのではなく、がコンパイルされないため(上記のコードを使用して、 "is_or_extends"を "extends"に置き換えて)、独自のクラスとして使用することはできません

私の目標:

私は達成することを目指しています何を延長する場合、function()は、子クラスのオブジェクトではなく、親クラスを返すことを親クラスです。

私はジェネリック型を使用して親クラスにどの子クラスが関数を呼び出したかを伝えますが、例外が発生することなく親クラスのオブジェクトを使用することはできません。例は次のとおりです。

public static class Parent<T extends Parent<T>> {} 
public static class Child extends Parent<Child> {} 

public static void main(String[] args) { 
    // This will not compile as Parent cannot extend Parent 
    Parent<Parent> parent = new Parent<Parent>(); 

    // This will work as Child extends Parent 
    Child child = new Child(); 
} 

ありがとうございます。

+0

いくつかのより多くを明確にしてください。あなたは 'Parent 'を使うことができますか?私はあなたの目標を理解していません。 –

+0

質問の内線を見てください。 Parentを拡張するので、Childのオブジェクトを作成できますが、Parentのオブジェクトを作成することはできません。 – TheCrazyPhoenix

+0

私が意味するところは、親のは、ジェネリック型が関数で返す子クラスオブジェクトの親クラス情報を与えるということです。 – TheCrazyPhoenix

答えて

4

extends平均は「is or extend」です。あなたの例がコンパイルされない理由は、内部がParentが生の型であるためです。これはT extends Parent<T>の有効な代替ではありません。 「正しい」タイプは、Parent<Parent<Parent<...>>> ad infinitumのようになります。明らかにそのようなタイプは宣言することは不可能です。

Parent<?> parent = new Parent<>(); 
Parent<?> derived = parent.function(); 

コンパイラはすでにTParent<?>のいくつかのサブクラスであることを知っているので、これは動作します:

一つの解決策は、このようにそれをインスタンス化することです。このトリックの1つの欠点は、匿名クラスを使用する場合など、型を推論できない場合は機能しないことです。

もう一つの可能​​なアプローチ - 親/子関係の性質に依存する - ちょうどそのタイプの解決のために、ベースを延長するための追加クラスを作成することです:

// Parent functionality in here 
public static abstract class Base<T extends Base<T>> {} 

// This can be empty, or have just constructors if necessary 
public static class Simple extends Base<Parent> {} 

// Child functionality in here 
public static class Extended extends Base<Extended> {} 
関連する問題