Java与泛型一起使用接口
示例
假设您要定义一个接口,以允许在不同类型的通道(例如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); } }