如何创建一个实现具有两个泛型类型的接口的Java类?

问题

我有一个通用的界面

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

我有一个类消耗两种类型的对象,所以我想做类似的事情:

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);
}

从功能上讲,这个解决方案是可以的,我想。这只是冗长而丑陋。

有任何想法吗?


#1 热门回答(68 赞)

考虑封装:

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);
    }
}

#2 热门回答(31 赞)

由于类型擦除,你无法两次实现相同的接口(具有不同的类型参数)。


#3 热门回答(9 赞)

这是一个基于Steve McLeod's one的可能解决方案:

public class TwoTypesConsumer {
    public void consumeTomato(Tomato t) {...}
    public void consumeApple(Apple a) {...}

    public Consumer<Tomato> getTomatoConsumer() {
        return new Consumer<Tomato>() {
            public void consume(Tomato t) {
                consumeTomato(t);
            }
        }
    }

    public Consumer<Apple> getAppleConsumer() {
        return new Consumer<Apple>() {
            public void consume(Apple a) {
                consumeApple(t);
            }
        }
    }
}

问题的隐含要求是共享状态的Consumer<Tomato>Consumer<Apple>对象。对Consumer<Tomato>, Consumer<Apple>对象的需求来自其他期望这些作为参数的方法。我需要一个类来实现它们以便共享状态。

史蒂夫的想法是使用两个内部类,每个类实现不同的泛型类型。

此版本为实现Consumer接口的对象添加了getter,然后可以将其传递给期望它们的其他方法。