它们在性能上是相同的。如果你写这样一个测试:
object Traits {
trait A { def a = "apple" }
trait B extends A { def b = "blueberry" }
trait C1 extends B { def c = "cherry" }
trait C2 extends A { def c = "chard" }
class Dessert extends B with C1 { }
class Salad extends B with C2 { }
}
,并期待在字节码Dessert
和Salad
你看到
public Traits$Dessert();
Code:
0: aload_0
1: invokespecial #29; //Method java/lang/Object."<init>":()V
4: aload_0
5: invokestatic #33; //Method Traits$A$class.$init$:(LTraits$A;)V
8: aload_0
9: invokestatic #36; //Method Traits$B$class.$init$:(LTraits$B;)V
12: aload_0
13: invokestatic #39; //Method Traits$C1$class.$init$:(LTraits$C1;)V
16: return
public Traits$Salad();
Code:
0: aload_0
1: invokespecial #29; //Method java/lang/Object."<init>":()V
4: aload_0
5: invokestatic #33; //Method Traits$A$class.$init$:(LTraits$A;)V
8: aload_0
9: invokestatic #36; //Method Traits$B$class.$init$:(LTraits$B;)V
12: aload_0
13: invokestatic #39; //Method Traits$C2$class.$init$:(LTraits$C2;)V
16: return
如果随后去看看初始化为C1
和C2
,他们都是空的。如果您再次查看c
的方法调用,则可以参考C1
或C2
中定义的方法。
这是因为分层特征被解释的方式。你可以将它们看作一个堆栈:每次添加“with”时,整个继承层次被压入堆栈,除了之外,任何已经存在的东西都不会再次添加。所以C2
是否有B
并不重要,因为Salad
类已经选取了B
,因为它扩展了B
。
如果C1和C2添加相同的功能,他们为什么分开? – RoToRa 2010-04-28 12:31:55
方法调用的运行时效率?程序员效率的可读性? – 2010-04-28 13:51:07
@Mitch Blevins方法调用的运行时效率(我正在考虑具体的{1,2}实例化时间) @继承中的差异 - 它扩展了不同的类,但具有相同的f功能 – Jeriho 2010-04-28 14:22:46