假设您有两个接口:
interface Readable {
public void read();
}
interface Writable {
public void write();
}
在某些情况下,实现对象只能支持其中之一,但在很多情况下,实现将支持两个接口。使用界面的人员将必须执行以下操作:
// can't write to it without explicit casting
Readable myObject = new MyObject();
// can't read from it without explicit casting
Writable myObject = new MyObject();
// tight coupling to actual implementation
MyObject myObject = new MyObject();
这些选项都不是十分方便,甚至在考虑将其作为方法参数时更是如此。
一种解决方案是声明一个包装接口:
interface TheWholeShabam extends Readable, Writable {}
但这有一个特定的问题:同时支持Readable和Writable的所有实现都必须实现TheWholeShabam,以使其与使用该界面的人员兼容。即使除了保证两个接口的存在之外,它什么也没有提供。
有没有解决此问题的解决方案,还是应该使用包装器接口?
更新
实际上,经常需要使对象既可读又可写,因此仅将参数中的关注点分开并不总是一个干净的解决方案。
更新2
(被提取为答案,因此更易于评论)
更新3
请注意,此操作的主要用例不是流(尽管也必须支持它们)。流在输入和输出之间做出了非常具体的区分,并且职责之间有明确的区分。而是想像一个字节缓冲区,您需要一个可以写入和读取的对象,一个附加了非常特定状态的对象。存在这些对象是因为它们对于异步I / O,编码,
更新4
我尝试的第一件事与以下建议相同(请检查接受的答案),但事实证明它太脆弱了。
假设您有一个必须返回类型的类:
public <RW extends Readable & Writable> RW getItAll();
如果调用此方法,则常规RW由接收对象的变量确定,因此您需要一种描述此var的方法。
MyObject myObject = someInstance.getItAll();
这将起作用,但是再次将其与实现联系在一起,并且实际上可能在运行时抛出classcastexceptions(取决于返回的内容)。
另外,如果要使用RW类型的类变量,则需要在类级别定义泛型。