假设您要定义一个接口,以允许在不同类型的通道(例如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("从消费 " + channel);
return "some useful data";
}
@Override
public String RPCSubmit(String data) {
return "received " + data + " just now ";
}
};
mockIO.consume(); // prints: 从消费 somechannel
mockIO.publish("TestData"); // 将TestData发布到某个频道
System.out.println(mockIO.RPCSubmit("TestData")); // 刚收到TestData我们还可以对该接口做一些更有用的事情,假设我们想用它包装一些基本的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(); // 刚来过4次 counter.publish(4); // 刚再来一次,是的 counter.publish(1); // 获取统计计数器的数据 System.out.println(counter.consume()); // 版画5 // 显示统计信息计数器页面的数据,但将其作为页面视图包含在内 System.out.println(counter.RPCSubmit(1)); // 版画6
实现多个接口时,不能两次实现相同的接口。这也适用于通用接口。因此,以下代码无效,并会导致编译错误:
interface Printer<T> {
void print(T value);
}
// 无效!
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); }
}