реализация черты - PullRequest
       6

реализация черты

3 голосов
/ 28 апреля 2010

Если у меня есть такие черты, как:

trait A {...}
trait B extends A{...}
trait C1 extends B{...}
trait C2 extends A{...}

Я могу написать класс двумя способами (C1 и C2 добавляют одинаковую функциональность)

class Concrete1 extends B with C1
class Concrete2 extends B with C2

Какой вариант лучше (эффективнее)?

1 Ответ

4 голосов
/ 28 апреля 2010

Они идентичны с точки зрения производительности. Если вы напишите такой тест:

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.

Это происходит из-за способа интерпретации слоистых признаков. Вы можете думать о них как о стеке: каждый раз, когда вы добавляете «с», вся иерархия наследования помещается в стек за исключением , что все, что уже есть, не добавляется снова. Поэтому не имеет значения, имеет ли C2 значение B или нет, поскольку класс Salad уже поднял B, поскольку он расширяется B.

...