关于scala特性和子类重写如何组合的澄清

时间:2014-09-22 15:43:44

标签: scala

有人可以确认我理解下面的测试吗?似乎当您在Scala中向类中添加特征时,如果您引用super,该特征将成为该类的super.symbol_defined_in_trait。如果特征本身扩展了基类,则特征super成为原始实现。我搞砸了还是错过了什么大事?

class Base {
  def doStuff = println("Base did stuff")
}

trait WrapBase extends Base {
  override def doStuff = {
    println("WrapBase did stuff"); 
    super.doStuff
  }
}

class Sub1 extends Base

class Sub2 extends Base with WrapBase

class Sub3 extends Base {
  override def doStuff = {
    println("Sub3 did stuff"); 
    super.doStuff
  }
}

class Sub4 extends Base with WrapBase {
  override def doStuff = {
    println("Sub4 did stuff"); 
    super.doStuff
  }
}

class Sub5 extends Base with WrapBase {
  override def doStuff = {
    println("Sub5 did stuff"); 
  }
}

此测试打印出来:

scala> (new Sub1).doStuff
Base did stuff

scala> (new Sub2).doStuff
WrapBase did stuff
Base did stuff

scala> (new Sub3).doStuff
Sub3 did stuff
Base did stuff

scala> (new Sub4).doStuff
Sub4 did stuff
WrapBase did stuff
Base did stuff

scala> (new Sub5).doStuff
Sub5 did stuff

1 个答案:

答案 0 :(得分:0)

Scala中的继承包括晶格导向的非循环图。可以实例化的终极类构造成一个馅饼:底部总是一些类,然后有一些特征。特征的顺序由属性决定 - 任何特征都不依赖于其上的其他特征。或者,等效地,特征可以仅在其所有依赖性之上混合。

UPD:以下提示完全错误

一个类的主体也是一个“特征”,可以在顶部而不是在中间混合:

object Sub6 extends Base with {
  override def doStuff = {
    println("Sub6 did stuff")
    super.doStuff
  }       
} with WrapBase

结果将是

scala> Sub6.doStuff
WrapBase did stuff
Sub6 did stuff
Base did stuff

其实我误解了“早期会员定义”功能(http://www.scala-lang.org/old/sites/default/files/sids/nielsen/Tue,%202009-06-02,%2013:16/early-defs.pdf)。

此语法仅适用于初始化val

示例应该看起来:

trait Sub6Changed extends Base {
  override def doStuff = {
    println("Sub6Changed did stuff") 
    super.doStuff
  }       
} 

object Sub6 extends Base with Sub6Changed with WrapBase

P.S。感谢Cloud tech