如何让具有相同基本特征的多个特征实现相同的方法
How to have multiple traits of same base trait implement the same method
我有一个场景,其中多个特征继承自一个固定的基本特征。基本特征有一个抽象方法,每个都需要实现。使用这些traits的class也需要实现这个方法:
trait A {
def f: Any
}
trait B1 extends A {
val i: Int
override def f: Any = println("B1: " + i)
}
trait B2 extends A {
val j: Int
override def f: Any = println("B2: " + j)
}
class C extends A with B1 with B2 {
val i = 1
val j = 2
override def f: Any = {
super.f
println("C::f")
}
}
然后当我做一个
new C().f
只输出"B1: 1"不输出"B2: 2"
有没有一种方法可以定义 B1、B2 和 C,以便可以调用 f 的所有实现?
这是 diamond problem 的一个例子,Scala 通过 线性化 的过程解决了这个问题:
Scala resolves
method names using a right-first depth-first search of extended
'traits', before eliminating all but the last occurrence of each
module in the resulting list. So, the resolution order is: [D, C, A,
B, A], which reduces down to [D, C, B, A].
所以输出应该符合你的情况
B2: 2
C::f
所以似乎无法在 B1
和 B2
中调用所有 f
覆盖,而只有 B2.f
被解析。
你知道你混合了哪两个钻石特征,你可以调用两个 super 实现并指定你想要调用每个 super 的特征 实施。
所以,您可以这样实现 C
:
class C extends A with B1 with B2 {
val i = 1
val j = 2
override def f: Any = {
super[B1].f
super[B2].f
println("C::f")
}
}
并且会得到输出:
B1: 1
B2: 2
C::f
我有一个场景,其中多个特征继承自一个固定的基本特征。基本特征有一个抽象方法,每个都需要实现。使用这些traits的class也需要实现这个方法:
trait A {
def f: Any
}
trait B1 extends A {
val i: Int
override def f: Any = println("B1: " + i)
}
trait B2 extends A {
val j: Int
override def f: Any = println("B2: " + j)
}
class C extends A with B1 with B2 {
val i = 1
val j = 2
override def f: Any = {
super.f
println("C::f")
}
}
然后当我做一个
new C().f
只输出"B1: 1"不输出"B2: 2"
有没有一种方法可以定义 B1、B2 和 C,以便可以调用 f 的所有实现?
这是 diamond problem 的一个例子,Scala 通过 线性化 的过程解决了这个问题:
Scala resolves method names using a right-first depth-first search of extended 'traits', before eliminating all but the last occurrence of each module in the resulting list. So, the resolution order is: [D, C, A, B, A], which reduces down to [D, C, B, A].
所以输出应该符合你的情况
B2: 2
C::f
所以似乎无法在 B1
和 B2
中调用所有 f
覆盖,而只有 B2.f
被解析。
你知道你混合了哪两个钻石特征,你可以调用两个 super 实现并指定你想要调用每个 super 的特征 实施。
所以,您可以这样实现 C
:
class C extends A with B1 with B2 {
val i = 1
val j = 2
override def f: Any = {
super[B1].f
super[B2].f
println("C::f")
}
}
并且会得到输出:
B1: 1
B2: 2
C::f