使用特征时遇到了问题。以下代码使用特征覆盖newEdge。
#!/usr/bin/env groovy
class Edge {}
trait DirectedEdge {}
class Graph {
def edge() {
newEdge()
}
def newEdge() {
return new Edge()
}
}
trait DirectedGraph {
def newEdge() {
return new Edge().withTraits(DirectedEdge)
}
}
def graph = new Graph()
assert graph.newEdge() instanceof Edge : 'newEdge returns Edge'
assert graph.edge() instanceof Edge : 'edge returns an Edge'
def dgraph = new Graph() as DirectedGraph
assert dgraph.newEdge() instanceof DirectedEdge : 'newEdge returns DirectedEdge'
assert dgraph.edge() instanceof DirectedEdge : 'edge returns DirectedEdge'
前两个断言显示没有DirectedGraph特征的行为。下一个特征显示了DirectedGraph的预期行为,但特征的方法似乎没有在最后一个断言中使用。
最后一个断言失败了。
Caught: java.lang.AssertionError: edge returns DirectedEdge. Expression: (dgraph.edge() instanceof DirectedEdge)
java.lang.AssertionError: edge returns DirectedEdge. Expression: (dgraph.edge() instanceof DirectedEdge)
我想知道如何解决这个问题,以便最后一个断言可以通过。
答案 0 :(得分:0)
以下是def dgraph = new Graph() as DirectedGraph
语义上发生的事情:
class MyProxy implements DirectedGraph {
Graph myGraph
MyProxy(Graph graph) {
myGraph = graph
}
def invokeMethod(String name, Object args) {
myGraph.invokeMethod(name, args)
}
}
def dgraph = new MyProxy(new Graph())
此类对象实现了一个特征,并将所有未定义的调用委托给原始对象,即Graph
实例。
assert dgraph.newEdge() instanceof DirectedEdge
有效,因为newEdge
方法是从特征中派生出来的
assert dgraph.edge() instanceof DirectedEdge
失败,因为没有edge
方法,此调用被委托给原始Graph
实例,后者又不了解代理包装器。
这可以使用纯类继承来实现:
class Edge {}
class DirectedEdge extends Edge {}
class Graph {
def edge() { newEdge() }
def newEdge() { new Edge() }
}
class DirectedGraph extends Graph {
def newEdge() { new DirectedEdge() }
}
def graph = new Graph()
assert graph.newEdge() instanceof Edge
assert graph.edge() instanceof Edge
def dgraph = new DirectedGraph()
assert dgraph.newEdge() instanceof DirectedEdge
assert dgraph.edge() instanceof DirectedEdge