2016-11-29 18 views
0

これを行うより良い方法があるのだろうかと思います。私が望むのは、抽象クラスに具体的なメソッドを持たせることです。抽象クラスを拡張する具体的なインスタンスを返します。ここで抽象親クラスのメソッドから具体的な子クラスのインスタンスを返す

は私が今やっているものです:

abstract class ParentClass<T extends ParentClass> extends RelativeLayout { 
    ... 
    public T aMethod(){ 
     return (T)this; 
    } 
} 

class ChildClass1 extends ParentClass<ChildClass1>{ 
... 
} 

を、私は、これは常にTのインスタンスであるため、私はTにこれをキャストする必要がありますとは思わない

+4

これを行うことにした場合、 'class ChildClass2 extends ParentClass 'になります。 ここでは、達成したいこと、または達成したい理由について完全にはっきりしていません。それに応じてあなたの質問を更新したいのであれば、私は答えを出すことができるかもしれません。 –

+0

@JoeC私はうまくいきましたが、親クラスの 'this'をTにキャストする必要があります。既に 'this'がTのインスタンスであることを知っているはずです。より洗練されたソリューションがあるかどうかは疑問でしたそれはちょうど思考するほどスマートではなかった。私がキャストする必要のないもの、またはジェネリックスをまったく使用せずに子供のインスタンスを返したもの。 –

+0

私が提案したサブクラスで何を持っているのか試してみましょう。 –

答えて

0

"this very class"の型を参照する方法がないという問題があります。このため、abstract class Base<T extends Base<T>>のような構文を使用する必要があります。しかし、多くの人がコメントで述べたように、Subclass1 extends <Subclass2>を定義することを禁止するものはありません。 Tが "this very class"であることを保証する文法的な方法があります。

ただし、実行時にこの保証を適用することはできます。 TypeToolsなどの方法を使用して、使用されている汎用タイプを抽出し、現在のインスタンスにこのタイプがあることを確認できます。このクラスはインスタンス化することができる

public abstract class Base<T extends Base<T>> { 

    protected Base() { 
     final Class<?> t = (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()) 
       .getActualTypeArguments()[0]; 
     if (!t.isInstance(this)) { 
      throw new IllegalArgumentException(); 
     } 
    } 

    public T getInstance() { 
     @SuppressWarnings("unchecked") 
     T thisIsT = (T) this; 
     return thisIsT; 
    } 
} 

:これはおそらくのようなものになるでしょう

public class Extension1 extends Base<Extension1> {} 

しかし、これではない:thisTのインスタンスであること

public class Extension2 extends Base<Extension1> {} 

Baseコンストラクタ保証したがって、thisTのキャストは安全です。

関連する問題