1

これは、私が持っていた以前の質問からのフォローアップです。

動物の抽象親クラスがあるとしましょう。同じ種類の動物でも気質が異なり、さまざまな種類のショーで演じることができます。したがって、私の動物の定義は次のようになります。

public abstract class Animal<T extends Temperament, S extends Show>{...}

動物の種類、気質、動物が演じるショーの種類を認識し、トレーナーがその動物に教えることができる一連のトリックを定義する、さまざまな動物のトレーナーが必要です。特定の動物に対してトリックのセットを定義したいので、次のような enum インターフェースを用意します。

public interface TrainingActions<T extends Animal<?,?>>{...}

そのインターフェイスを実装するすべての列挙型は、気質や実行できるショーに関係なく、特定の動物のトレーニング アクションのセットを定義します。

これらを念頭に置いて、トレーナーの親クラスの私の定義は次のとおりです。

public abstract class Trainer
  <A extends Animal<?,?>, 
   E extends Enum<E> & TrainingActions<A>,
   T extends Temperament,
   S extends Show>{
...}

今、私は次のように具体的なトレーナーを作成しようとしていましたが、エラーが発生しました:

public class DogTrainer
  <T extends Temperament,
   S extends Show> extends Trainer
     <Dog<T,S>, DogTrainer.Trainables, T, S>{//error right here 

  public enum Trainables implements TrainingActions<Dog<?,?>>{
     FETCH, GROWL, SIT, HEEL;
  }
  ...
}

の定義でDogTrainer.Trainablesのパラメータとして使用しようとすると、次のエラーが発生します。TrainerDogTrainer

Bound mismatch: The type DogTrainer.Trainables is not a valid substitute 
for the bounded parameter <E extends Enum<E> & TrainingActions<A>> of the type 
Trainer<A,E,T,S>

誰かが私が間違っていることを理解するのを手伝ってくれますか?

4

2 に答える 2

1

一般的な署名に多くの制約を追加することで、解決できない問題を作成しました。あなたの現在の解決策は、(想定された) 意図に比べて緩すぎます。次の宣言を見てください。

public abstract class Trainer
  <A extends Animal<?,?>, // <- here you are not enforcing the right bounds
   E extends Enum<E> & TrainingActions<A>,
   T extends Temperament,
   S extends Show>{
  …
}

この宣言により、間違った動物を特定のインスタンスに渡すことがTemperamentできShowますTrainer。おそらく最も必要なのは次のとおりです。

public abstract class Trainer
<A extends Animal<T,S>, 
 E extends Enum<E> & TrainingActions<A>,
 T extends Temperament,
 S extends Show> {
 …
}

しかし、その後、ソリューションは機能しなくなります。この宣言では、適切なandを持つ動物のみを訓練する必要があるため、意図したとおりに訓練された動物を宣言せずに、DogTrainer型パラメータを持つTemperamentandを作成することはできません (そうでない場合は、型パラメータを作成する必要はありません)。ShowDog<T,S>TrainerTemperamentShow

DogTrainerしかし、 をasと宣言すると、権利がなく、 を にしたいため、意図したものDogTrainer<T extends Temperament, S extends Show> extends Trainer<Dog<T,S>, DogTrainer.Trainables, T, S>を指定できません。これを修正することは不可能です。そして、あなたが行ったようにワイルドカードを使用するか、特定の型を1つだけ使用してのみ宣言できます。内部は常に外部クラスの型パラメーターを参照できます。TrainingActionTemperamentShowTrainingActionenumenumsenum Trainables implements TrainingActions<Dog<?,?>>enumstatic

したがって、これは要約された制約の組み合わせです。

  1. Trainerには、動物Aと気質T、ショーSとトレーニング アクションのパラメータがあります。E
  2. Aトレーナーの権利を持っている必要がありTますS
  3. EAトレーナーの権利を持っている必要があります
  4. Eであるenum
  5. Tとには異なるタイプの異なるトレーナーが必要ですSが、 には一定のタイプが必要ですE(これは であるためenum)

不可能だよ。現在の解決策は制約2を無視しますが、少なくとも 1 つの制約を削除しないと解決策はありません

于 2013-10-18T09:01:34.847 に答える
0

問題を理解しました。具体的なトレーナーは次のように定義する必要がありました。

public class DogTrainer
  <T extends Temperament,
   S extends Show> extends Trainer
     <Dog<?,?>, DogTrainer.Trainables, T, S>{// changed line

  public enum Trainables implements TrainingActions<Dog<?,?>>{
     FETCH, GROWL, SIT, HEEL;
  }
  ...
}
于 2013-10-17T01:13:13.220 に答える