它們在性能上是相同的。如果你寫這樣一個測試:
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