使用 Generics 的接口
假设你要定义一个允许从不同类型的通道(例如 AMQP,JMS 等)发布/使用数据的接口,但你希望能够切换实现细节……
让我们定义一个可以在多个实现中重用的基本 IO 接口:
public interface IO<IncomingType, OutgoingType> {
    void publish(OutgoingType data);
    IncomingType consume();
    IncomingType RPCSubmit(OutgoingType data);
}
现在我可以实例化该接口,但由于我们没有这些方法的默认实现,因此在实例化它时需要实现:
    IO<String, String> mockIO = new IO<String, String>() {
        private String channel = "somechannel";
        @Override
        public void publish(String data) {
            System.out.println("Publishing " + data + " to " + channel);
        }
        @Override
        public String consume() {
            System.out.println("Consuming from " + channel);
            return "some useful data";
        }
        @Override
        public String RPCSubmit(String data) {
            return "received " + data + " just now ";
        }
    };
    mockIO.consume(); // prints: Consuming from somechannel
    mockIO.publish("TestData"); // Publishing TestData to somechannel
    System.out.println(mockIO.RPCSubmit("TestData")); // received TestData just now
我们也可以使用该接口做一些更有用的事情,假设我们想用它来包装一些基本的 RabbitMQ 函数:
public class RabbitMQ implements IO<String, String> {
    private String exchange;
    private String queue;
    public RabbitMQ(String exchange, String queue){
        this.exchange = exchange;
        this.queue = queue;
    }
    @Override
    public void publish(String data) {
        rabbit.basicPublish(exchange, queue, data.getBytes());
    }
    @Override
    public String consume() {
        return rabbit.basicConsume(exchange, queue);
    }
    @Override
    public String RPCSubmit(String data) {
        return rabbit.rpcPublish(exchange, queue, data);
    }
}
假设我现在想要使用这个 IO 界面来计算自上次系统重启以来访问我网站的次数,然后能够显示总访问次数 - 你可以这样做:
import java.util.concurrent.atomic.AtomicLong;
public class VisitCounter implements IO<Long, Integer> {
    private static AtomicLong websiteCounter = new AtomicLong(0);
    
    @Override
    public void publish(Integer count) {
        websiteCounter.addAndGet(count);
    }
    @Override
    public Long consume() {
        return websiteCounter.get();
    }
    @Override
    public Long RPCSubmit(Integer count) {
        return websiteCounter.addAndGet(count);
    }
    
}
现在让我们使用 VisitCounter:
    VisitCounter counter = new VisitCounter();
    // just had 4 visits, yay
    counter.publish(4);
    // just had another visit, yay
    counter.publish(1);
    // get data for stats counter
    System.out.println(counter.consume()); // prints 5
    // show data for stats counter page, but include that as a page view
    System.out.println(counter.RPCSubmit(1)); // prints 6
实现多个接口时,不能两次实现相同的接口。这也适用于通用接口。因此,以下代码无效,并将导致编译错误:
interface Printer<T> {
    void print(T value);
}
// Invalid!
class SystemPrinter implements Printer<Double>, Printer<Integer> {
    @Override public void print(Double d){ System.out.println("Decimal: " + d); }
    @Override public void print(Integer i){ System.out.println("Discrete: " + i); }
}