【问题标题】:trait implementation特征实现
【发布时间】:2010-04-29 01:42:44
【问题描述】:

如果我有一些特征,例如:

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

哪种变体更好(高效)?

【问题讨论】:

  • 如果 C1 和 C2 添加相同的功能,为什么要分开?
  • 方法调用的运行时效率?程序员的可读性效率?
  • @Mitch Blevins 方法调用的运行时效率(我正在考虑具体的{1,2} 实例化时间)@继承中的差异 - 扩展了不同的类但具有相同的 f 功能

标签: scala traits


【解决方案1】:

它们在性能方面是相同的。如果你写一个这样的测试:

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 { }
}

查看DessertSalad 的字节码

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

如果您接着查看 C1C2 的初始化程序,它们都是空的。如果您再次查看c 的方法调用,它是对C1C2 中定义的方法的引用。

这是因为分层特征的解释方式。您可以将它们视为一个堆栈:每次添加“with”时,整个继承层次结构都会被推入堆栈除了,已经存在的任何内容都不会再次添加。所以C2 是否有B 并不重要,因为Salad 类已经选择了B,因为它扩展了B

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-08
    • 2021-11-14
    • 2017-09-14
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 2021-07-18
    • 1970-01-01
    相关资源
    最近更新 更多