2011-01-19 9 views
0

列挙型を提供するために抽象クラスAを拡張するクラスが必要です。私は型自体を制約する必要はありません。ただ列挙型を提供したいだけです。たとえば、私は抽象クラスAnimalを持っており、すべてのAnimalに一連の振る舞いがあることを保証したいと思います。私はこれらの振る舞いを制約したり、何らかの形でマスターリストを作成する必要はありません。私はすべての動物が象徴的な行動のリストを返すようにしたい。拡張クラスの列挙を要求する

理想的には、私が言いたい:

public abstract class Animal { 
    public List<Enum> getBehaviors(); 
} 

が、これはきれいにコンパイルされません。

アイデア?ジェネリックスを使ってこれにアプローチする方が良いでしょうか?

+3

どうしてこのようにしたいですか?それは何かが 'enum'であることはしばしば多くの実装の詳細です。 'Animal'クラスがビヘイビアのリストを返すようにしたいのであれば、' List 'を返すべきです、' Behavior'はインターフェースです。 'Behavior'を実装するいくつかの' enum'または 'enum'を持つことができますが、その詳細は重要ではないようです。そして、ビヘイビアのリストに含まれるものに唯一の制限を加えることは、それが何らかの種類の 'enum'であるオブジェクトを含んでいるということだけです。私には分かりません。' DayOfWeek'は恐らく動作ではありません。 – ColinD

+0

あなたがお勧めするものは、私が欲しいものです。ありがとう。あなたの答えは以下の通り、+1と記入してください。 – kvista

答えて

2

私はここで少しコメントを拡大します。

あなたのgetBehaviors()メソッドは、メソッドのシグネチャを作り、特定の動物のための行動のリストを返すようにしたい場合は

が返され List<Enum<?>>はあなたを助けるために 何ももしないことを宣言します。その方法からあなたの List<Enum<?>>を取得したクライアントは、それが何であるかを知っている人には役に立たない何もできません。この制限は、ビヘイビアのリストに含まれるオブジェクトのタイプが実際には "ビヘイビア"であることを保証するのに役立つものではありません。彼らは週の日、年の何ヶ月か、まさに何でもよいでしょう!私は推測している何

は、あなたが(などBARKBITE、のような定数で)DogBehaviorのようないくつかのenum秒を持っているし、あなただけの、そのような行動はリストで許可されていることを確認したいということです。これらの動作がenumに収集されていることは実装の詳細です。あなたがするべきことは、何かをBehaviorとして指定する共通のインターフェースを導入することです。 Behaviorに関連する特定のメソッドがない場合は、メソッドを定義していないマーカーインターフェイスのみになります。

public enum DogBehavior implements Behavior { 
    BARK("Bark") { 
    public void doBehavior() { 
     // bark 
    } 
    }, 
    // etc. 

    private final String name; 

    DogBehavior(String name) { 
    this.name = name; 
    } 

    public String getName() { 
    return name; 
    } 
} 

次に、「動物」のように見えるかもしれません:

public interface Behavior { 
    public String getName(); 
    public void doBehavior(); 
    // etc. 
} 

あなたは、このインタフェースを実装するいくつかのenum Sを持つことができます:それ以外の場合、あなたはそれが、このようなようないくつかの方法を、持っている場合があります

public abstract class Animal { 
    public abstract List<Behavior> getBehaviors(); 
} 

これは、私にはもっと意味があります。

2

私は少し困惑している - あなたは行動のセットをエクスポートするために、すべてのAnimal秒を必要とする場合は、理想的にあなたの目標は、このような何かを書くことができるようにするために、次のようになります。

Animal a = /* .. create some subtype of Animal .. */ 
List</* ?? */> behaviors = a.getBehaviors(); 

問題それぞれAnimalがビヘイビアのために独自の列挙型を作成したければ、それを表現する型を明示的に指定しないかぎり、それらのビヘイビアーについて統一的な方法を話すことはできません。つまり、Animalのインターフェイスで、すべてのAnimalビヘイビアを関連付ける必要がある場合を除き、上記の/* ?? */を入力することはできません。

1つのオプションは、この1のようなクラスを定義するには、次のようになります。

public final class Behavior { 
    private final String name; 

    public Behavior(String name) { 
     this.name = name; 
    } 
    public String getBehaviorName() { 
     return name; 
    } 
    /* ... etc. ... */ 
} 

その後、あなたはそれがBehaviorオブジェクトのリストを返すように、各AnimalタイプがgetBehaviors()を定義する可能性があります。これは、行動を議論するためのタイプセーフなフレームワークを提供し、潜在的にはそれぞれの行動に対してより複雑なアクションを追加する能力を与えます。

1

2つのことが間違っています。

まず、そのメソッド抽象をマークする必要があります。あなたは実装を提供しませんでした。

第2に、警告を必要としない場合は、列挙型をパラメータ化する必要があります。 Enumをさらに制限する必要がない場合は、Enum<?>で十分です。

しかし、他の人が指摘しているように、これはおそらくあなたが望むものではありません。列挙型の「行動」はあなたにとって役に立たない。 getBehaviors()から返された機能は一度もありません。あなたはそれらを繰り返してリストすることができますが、それはList<String>以上の価値があります。

List<Behavior>ここでBehaviorはあなたのために何かを行うインターフェイスです。

EDIT:上記のColinDは、同じ点のパンチに私を打つ。

0
public abstract class Animal { 
    public List<? extends Enum<?>> getBehaviors(); 
} 
関連する問題