Scala Traits - 如何多次扩展一个特征?

AZ_*_*AZ_ 0 scala decorator traits

我是Scala菜鸟,请看下面的代码。

abstract class Pizza() {
  def toppings: List[String]
  def price: BigDecimal
}
trait Large extends Pizza {
  abstract override def price: BigDecimal = super.price * 2
}
trait Cheese extends Pizza {
  abstract override def toppings: List[String] = "Cheese" :: super.toppings
  abstract override def price: BigDecimal = super.price + 0.5
}
trait Salami extends Pizza {
  abstract override def toppings: List[String] = "Salami" :: super.toppings
  abstract override def price: BigDecimal = super.price + 1.0
}
class BasePizza extends Pizza {
  def toppings = List("Tomato Sauce")
  def price = 5.0
}
class MargheritaPizza extends BasePizza with Cheese
class LargeMargheritaPizza extends MargheritaPizza with Large
class SalamiPizza extends MargheritaPizza with Salami
class DoubleCheeseSalamiPizza extends MargheritaPizza with Salami with Cheese


println(reflect.runtime.universe.typeOf[DoubleCheeseSalamiPizza].baseClasses)
// List(class DoubleCheeseSalamiPizza, trait Salami, class MargheritaPizza, trait Cheese, class BasePizza, class Pizza, class Object, class Any) res0: Unit = ()
Run Code Online (Sandbox Code Playgroud)

如何多次添加装饰?例如双奶酪披萨?(如您所见,线性化顺序trait Cheese延长了一倍)

Dmy*_*tin 5

基类只能在线性化中出现一次:

\n\n

https://www.scala-lang.org/files/archive/spec/2.12/05-classes-and-objects.html#class-线性化

\n\n
\n

让我们C成为一个带有 template 的类C1 with ... with Cn { stats }。的线性化C定义L(C)如下:

\n\n

L(C) = C, L(Cn) +\xe2\x83\x97 \xe2\x80\xa6 +\xe2\x83\x97 L(C1)

\n\n

这里+\xe2\x83\x97表示右操作数的元素替换左操作数的相同元素的串联:

\n\n
a, A +\xe2\x83\x97 B = a, (A +\xe2\x83\x97 B)  if a \xe2\x88\x89 B\n         = A +\xe2\x83\x97 B       if a \xe2\x88\x88 B\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n

https://github.com/scala/scala/blob/2.13.x/src/reflect/scala/reflect/api/Types.scala#L176-L180

\n\n
\n
/** The list of all base classes of this type (including its own typeSymbol)\n *  in linearization order, starting with the class itself and ending\n *  in class Any.\n */ def baseClasses: List[Symbol]\n
Run Code Online (Sandbox Code Playgroud)\n
\n