2009-09-13 7 views
11
のジェネリック抽象クラスと正しい使用を拡張
public abstract class AbstractTool<AT extends AbstractThing> { 
    protected ArrayList<AT> ledger; 
    public AbstractTool() { 
     ledger = new ArrayList<AT>(); 
    } 

    public AT getToolAt(int i) { 
     return ledger.get(i); 
    } 

    // More code Which operates on Ledger ... 

} 

public class Tool<AT extends AbstractThing> extends AbstractTool { 
    public Tool() { 
     super(); 
    } 
} 

どのように私は正しくAbstractToolコンストラクタにToolのジェネリックATを渡すためにスーパーを呼ぶのですか?スーパー

私がいつも代わりにThingAbstractThingを取り戻すことを、私は私がTool(セイ、Tool<Thing>)を宣言するときであることをATを選ぶどのような関係なく思いません。これはジェネリック医薬品の目的を破るようだ...

ヘルプ?

答えて

19
public class Tool<AT extends AbstractThing> extends AbstractTool<AT> { 

つまり、ジェネリックで何かを拡張または実装する場合は、それらのジェネリック引数を定義することを忘れないでください。

+1

実際、この場合、AbstractToolの汎用パラメータの型制約が継承されるため、 'public class Tool extends AbstractTool 'と書くことができます。これは、AbstractToolの定義が 'AbstractThing'ではないジェネリックパラメータを使用してあなたを止めるので、機能的に同等です。 –

3

むしろ Tool<AT extends...> extends AbstractTool<AT>であってはなりませんか?

0

私はあなたがおそらく必要があると思う:

public abstract class AbstractTool<AT extends AbstractThing> { 
     protected List<AT> ledger = new ArrayList<AT>(); 

     public AT getToolAt(int i) { 
      return ledger.get(i); 
     } 

     // More code Which operates on Ledger ... 

    } 

    public class Tool extends AbstractTool<Thing> { 
     // Tool stuff ... 
    } 

Toolが具象クラスであるので、それ自体をパラメータ化する必要はありません。 List(インターフェイスにプログラムすることを覚えておいてください)を宣言し、保護されているため、サブクラスが直接アクセスできるため、コンストラクタは必要ありません。

+0

実際には、具体的なクラスのパラメータを持つことは非常に便利です。 ArrayList、LinkedList、HashMap、HashSetのすべてがパラメータ化されており、それらのすべてが具象クラスでもあります。 –

+1

私はそこになかったとは言わなかった。しかし、それはあなたがする必要がなければ、クライアントコードを非常に単純化します。コンテナ型のクラスでは、具体的な型がパラメータ化されている必要がありますが、おそらく私は最小限の例を読んでいたかもしれませんが、OPがそれを要求したとは思わなかったでしょう。 – Robert

+0

OK、あなたの意見を理解しています:) –