我有一个类层次结构,其中表兄弟共享非常相似的功能。例如:
Node
Statement
FunctionCallStatement
Expression
FunctionCallExpression
FunctionCallStatement和FunctionCallExpression共享一个非常相似的API,但我不能用单继承层次结构的纯类术语来表达它。所以,我创建了一个IsFunctionCall接口,这两个接口都实现了。我现在可以声明一个采用FunctionCallStatement或FunctionCallExpression的方法,如下所示:
void <T extends Node & IsFunctionCall> doSomething(T node) { ... }
这一切都非常好。
不幸的是,我现在发现自己面临着一个相当尴尬的问题。我有一个节点;我动态地知道必须是一个FunctionCallStatement或一个FunctionCallExpression;我需要将该节点传递给上面的doSomething()
方法。我无法找到将其转换为合适类型的方法。
现在我正在使用一个instanceof链来确定Node所在的类并将其强制转换为适当的具体类型,但这很难对付。我知道使其工作的唯一另一种方法是创建一个IsNode接口,并拥有当前期望Node期望IsNode的所有内容;这将允许我声明一个实现IsNode和IsFunctionCall的联合接口,让我在没有上面的泛型的情况下离开。但这是一项很多工作,而且还很难看。
有没有其他方法可以做到这一点?
(注意:上面的示例是我实际代码的简化版本。)
更新:我尝试了以下一段邪恶:
@SuppressWarnings("unchecked")
private <S extends Node & IsFunctionCall> S castNode(Node node)
{
return (S) node;
}
然后:
doSomething(castNode(node));
我收到了一些非常奇怪的错误消息。看来用于确定castNode()
的S的类型推断与doSomething()
的声明中的T不匹配;它只使用具体类型并将S设置为Node。这当然与doSomething()
声明的类型不匹配。非常特别。
更新更新:
这似乎与How should I cast for Java generic with multiple bounds?密切相关。我的情况略有不同,因为我的界限包括一个对象和一个接口,而另一个问题中的一个有两个接口,但它仍然适用。
看起来我需要重新设计我的整个应用程序。叹息。
任何管理员,请随意关闭此内容......
答案 0 :(得分:0)
我认为摆脱这种方式,虽然不是很优雅,但是对于doSomething有一些重载:
void doSomething(FunctionCallStatement node) ...
void doSomething(FunctionCallExpression node) ...
答案 1 :(得分:0)
您正在使用接口标记功能,如何将参数传递给FunctionCallInterface
,以提供对函数调用抽象的访问?
doSomething
只要能够访问相关信息并在实现对象上调用相关方法,就不必知道实际的实现类型。
public class FunctionCallStatement extends Statement implements FunctionCallInterface {
}
void doSomething(FunctionCallInterface node) {
}