2017-05-17 9 views
0

私は、次のクラスがありますオーバーライドメソッドは

public class A extends Exception { 
} 

public class B extends Email { 

} 

私の目標は、以下のようなこれらのクラスの両方で動作することが可能であろういくつかの戦略を実装することです。例えば

public enum Strategy { 
    ACTION_1 { 

     @Override 
     public void handleAction(Class<? extends Exception > parameterThatShouldAcceptOnlyA) { 
      throw parameterThatShouldAcceptOnlyA; 
     } 
    }, 
    ACTION_2 { 

     @Override 
     public void handleAction(Class<? extends Email > parameterThatShouldAcceptOnlyB) { 
      parameterThatShouldAcceptOnlyB.send(); 
     } 
    }; 

    public abstract void handleAction(Class<?> parameterThatShouldAcceptBoth); 
} 

これは、オーバーライドされたメソッドでは間違ったジェネリックによってコンパイルされません。

これを実行可能にする方法を提案してください。

+0

のようなあなたのハンドラを実装することができます。.. )? – shmosel

+0

明らかに、問題はあなたが 'Class '型を使っていることです。この型は 'T'型のオブジェクトではなく、Javaクラスに関連するメタ情報です。もう一つの問題は、あなたが 'enum'を生成しようとしていることです。これは不可能です。代わりに 'Strategy 'インタフェースを定義してみてください。 –

答えて

2

ここに戻ってください。あなたの考えは単にLiskov Substitution Principleに違反しています。

基本的には、をメソッドの引数として渡すことができるサブクラスに制限します。

これは、スーパークラスの代わりにサブクラスを使用できるというアイデアを壊してしまいます。今すぐに、そのメソッドを呼び出すコードがにあるので、を呼び出してください。でないことを確認するには、のメソッドを「無効な」パラメータで呼び出します。

他の言葉:の症状としてとしてこのコンパイラエラーを受け取ります。あなたがどうにかして特定の問題を回避する場合でも。言ったように - あなたは一歩前に戻り、あなたの考え全体を再考してください。

1

ヒントClassインスタンスをスローしたり、あなたのパラメータの型を変更する必要があり、最初はそれほどクラスClassによって提供されるよりも、他のメソッドを呼び出すことも可能でもありません。これにより、ワイルドカードを削除することもできます。

スーパークラスはジェネリックで定義できます。 Unfortunatelly列挙型はジェネリックをサポートしていません。しかし、あなたは `` ACTION_1.handleAction(...)を呼び出すことを計画、または `someDynamicStrategy.handleAction(ARE

interface Handler<T> { 
    void handleAction(T t); 
} 

のような汎用的なインタフェースを作成し、

class EmailHandler implements Handler<Email> { 
    void handleAction(Email email) { 
     email.send(); 
    } 

class ExceptionHandler implements Handler<Exception> { 
    void handleAction(Exception e) { 
     // Exception is a checked exception 
     // so we cannot throw it without 'throws' declaration 
     // but we cannt add 'throws Exception' 
     if (e instanceof RuntimeException) 
      throw (RuntimeException) e; 
     else 
      throw new RuntimeException("wrapped", e); 
    } 
+0

'Class 'オブジェクトをメソッドパラメータとして使用すると、 'T'型のメソッドを呼び出す必要がある場合は便利ではありません;) –

+0

OPのパラメータは' Class 'です。しかしあなたは正しい:ほとんどの場合、Tが必要である。 –

+0

答えを訂正し、 'Class 'の使用が無益であると指定してください。 –

関連する問題