Scala中的线性化顺序
在使用特征时,我难以理解Scala中的线性化顺序:
class A { def foo() = "A" } trait B extends A { override def foo() = "B" + super.foo() } trait C extends B { override def foo() = "C" + super.foo() } trait D extends A { override def foo() = "D" + super.foo() } object LinearizationPlayground { def main(args: Array[String]) { var d = new A with D with C with B; println(d.foo) // CBDA???? } } 它打印CBDA,但我不知道为什么。特征的顺序如何确定? 谢谢 解决方法
对线性化进行推理的直观方法是参考施工顺序和可视化线性层次结构。
你可以这样想:先建立基础类;特征是从左到右构建的,因为右侧的特征被添加“稍后”,因此“覆盖”先前的特征。然而,要构建一个特征,其基本特征必须首先构建(明显);当然,如果一个特征被构建,不再重建。现在,施工顺序与线性化相反。认为“基本”特征/类在线性层次结构中较高,并且层次结构中的特征较低,更接近作为线性化对象的类/对象。 从而: var d = new A with D with C with B; A与D与C与B的线性化 >(层次结构顶部)A(首先构建为基类) > A(以前不认为A) > C的线性化 > A(以前不认为A) > B的线性化 > A(以前不认为A) 所以线性化是:A-D-B-C。 给定这些直观的规则,d.foo调用C.foo,它返回一个“C”,后面是在B上解析的super.foo()(B的左边的特征,即线性化中的更高/之前),它返回一个“B”,然后是在D上解析的super.foo(),它返回一个“D”,后面是在A上解析的super.foo(),最后返回“A”。所以你有“CBDA”。 另一个例子,我准备了以下一个: class A { print("A") } trait H { print("H") } trait S extends H { print("S") } trait R { print("R ") } trait T extends R with H { print("T") } class B extends A with T with S { print("B") } new B // A R H T S B // linearization as in reverse of construction order and thus rightmost "H" wins // lin(B) = B >> lin(S) >> lin(T) >> lin(A) // = B >> (S >> H) >> (T >> H >> R) >> A // = B >> S >> T >> H >> R >> A (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |