Aar*_*lla 10 java generics interface
我有一个情况,我有很多模型类(~1000)实现任意数量的5个接口.所以我有一些实现一个的类和一个实现四个或五个的类.
这意味着我可以对这五个接口进行任何排列.在经典模型中,我必须实现32-5 = 27"元接口",它们"捆绑"接口中的接口.通常,这不是问题,因为IB通常是扩展IA等,但在我的情况下,五个接口是正交/独立的.
在我的框架代码中,我有一些方法需要实现任意数量的接口的实例.所以,让我们假设我们有类X和接口IA,IB,IC,ID和IE.X实现IA,ID和IE.
情况变得更糟,因为其中一些接口具有正式的类型参数.
我现在有两个选择:
我可以定义一个界面IADE(或者更确切地说IPersistable_MasterSlaveCapable_XmlIdentifierProvider;下划线只是为了您的阅读乐趣)
我可以定义一个泛型类型,<T extends IPersistable & IMasterSlaveCapable & IXmlIdentifierProvider>这将为我提供一个方便的方法来混合和匹配接口,因为我需要它们.
我可以使用这样的代码:IA a = ...; ID d = (ID)a; IE e = (IE)e然后使用具有正确类型的局部变量来调用方法,即使所有三个都在同一个实例上工作.或者在每个第二个方法调用中使用强制转换.
第一个解决方案意味着我得到了很多名称非常难以理解的空接口.
第二种使用一种"临时"打字.javac当Eclipse正确的时候,Oracle 有时会绊倒他们.
最后一个解决方案使用演员表.努夫说.
问题:
是否有更好的解决方案来混合任意数量的接口?
有没有理由避免解决#2为我提供的临时类型(除了Oracle的缺点javac)?
注意:我知道编写不能用Oracle编译的代码javac是一种风险.我们知道我们可以应对这种风险.
[编辑]我试图尝试在这里似乎有些困惑.我的模型实例可以具有以下特征之一:
现在我有支持代码在树上运行.树木的延伸是树木修改.但我也没有树木的修改.
当我在代码中添加修订树管理器中的子代时,我知道每个实例都必须实现ITtree,IRevisionable但两者都没有通用接口,因为这些是完全独立的问题.
但是在实现中,我需要在树的节点上调用方法:
public void addChild( T parent, T child ) {
T newRev = parent.createNewRevision();
newRev.addChild( foo );
... possibly more method calls to other interfaces ...
}
Run Code Online (Sandbox Code Playgroud)
如果createNewRevision在界面中IRevisionable并且addChild在界面中ITree,我可以选择定义T什么?
注意:假设我有几个其他接口以类似的方式工作:有许多地方它们是独立的,但有些代码需要看到它们的混合.IRevisionableTree不是解决方案,而是另一个问题.
我可以为每个电话投出类型,但这看起来很笨拙.创建接口的所有排列都很无聊,似乎没有合理的模式来压缩巨大的接口名称.泛型提供了一个很好的出路:
public
<T extends IRevisionable & ITree>
void addChild( T parent, T child ) { ... }
Run Code Online (Sandbox Code Playgroud)
这并不总是适用于Oracle,javac但它似乎紧凑而有用.还有其他选择/评论吗?
松散耦合的功能可能会很有趣。这里有一个例子。这是一种完全不同的方法;解耦事物而不是打字。基本上接口是隐藏的,作为委托字段实现。
IA ia = x.lookupCapability(IA.class);
if (ia != null) {
ia.a();
}
Run Code Online (Sandbox Code Playgroud)
它适合这里,就像许多接口一样,解耦的愿望会增加,并且您可以更轻松地组合相互依赖的接口的情况 ( if (ia != null && ib != null) ...)。