代码之家  ›  专栏  ›  技术社区  ›  AZ_

scala traits-如何多次扩展一个traits?

  •  0
  • AZ_  · 技术社区  · 6 年前

    我不想去斯卡拉,请看下面的代码。

    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 = ()
    

    如何多次添加装饰?例如,一份披萨配双芝士?(如线性化顺序所示 trait Cheese 延长一次)

    1 回复  |  直到 6 年前
        1
  •  4
  •   Dmytro Mitin    6 年前

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

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

    C 做一个有模板的班级 C1 with ... with Cn { stats } 是的。线性化 C类 ,请 L(C) 定义如下:

    L(C) = C, L(Cn) +⃗ … +⃗ L(C1)

    在这里 +⃗ 表示右操作数元素替换的级联 左操作数的相同元素:

    a, A +⃗ B = a, (A +⃗ B)  if a ∉ B
             = A +⃗ B       if a ∈ B
    

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

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