1. ホーム
  2. java

[解決済み] 2つの汎用型と1つのインタフェースを実装したJavaクラスを作るには?

2022-04-22 03:53:35

質問

一般的なインターフェイスがあります

public interface Consumer<E> {
    public void consume(E e);
}

2種類のオブジェクトを消費するクラスがあるので、次のようなことをしたいと思います。

public class TwoTypesConsumer implements Consumer<Tomato>, Consumer<Apple>
{
   public void consume(Tomato t) {  .....  }
   public void consume(Apple a) { ...... }
}

どうやら私には無理なようです。

もちろん、ディスパッチを自分で実装することは可能です。

public class TwoTypesConsumer implements Consumer<Object> {
   public void consume(Object o) {
      if (o instanceof Tomato) { ..... }
      else if (o instanceof Apple) { ..... }
      else { throw new IllegalArgumentException(...) }
   }
}

しかし、私はジェネリックが提供するコンパイル時の型チェックとディスパッチの解決策を探しているのです。

私が思いつく最良の解決策は、例えば、別々のインターフェイスを定義することです。

public interface AppleConsumer {
   public void consume(Apple a);
}

機能的には、この解決策でOKだと思います。ただ、冗長で醜いだけです。

何かアイデアはありますか?

解決方法は?

カプセル化を検討する。

public class TwoTypesConsumer {
    private TomatoConsumer tomatoConsumer = new TomatoConsumer();
    private AppleConsumer appleConsumer = new AppleConsumer();

    public void consume(Tomato t) { 
        tomatoConsumer.consume(t);
    }

    public void consume(Apple a) { 
        appleConsumer.consume(a);
    }

    public static class TomatoConsumer implements Consumer<Tomato> {
        public void consume(Tomato t) {  .....  }
    }

    public static class AppleConsumer implements Consumer<Apple> {
        public void consume(Apple a) {  .....  }
    }
}

これらの静的な内部クラスを作成するのが面倒な場合は、匿名クラスを使用することができます。

public class TwoTypesConsumer {
    private Consumer<Tomato> tomatoConsumer = new Consumer<Tomato>() {
        public void consume(Tomato t) {
        }
    };

    private Consumer<Apple> appleConsumer = new Consumer<Apple>() {
        public void consume(Apple a) {
        }
    };

    public void consume(Tomato t) {
        tomatoConsumer.consume(t);
    }

    public void consume(Apple a) {
        appleConsumer.consume(a);
    }
}