首页 文章

Scala特征:无法通过传递子元素中的值来获取抽象父特征值

提问于
浏览
0

这个例子是我试图解决的更大问题的模型 . 顶部的层次结构是抽象特征CarFamily,然后从CarFamily延伸出3个抽象特征,即本田,思域和沃尔沃 . 我的目标是能够在从这3个特征扩展的实例中为每个子特征调用carModelStatement .

但是,正如您可以看到结果一样,这些语句都返回“汽车模型为空” . 所以val volvo,honda,civic没有传到我对Scala的新手 . 想知道我错过了什么,或者是否有其他设计可以得到我想要的东西 . 谢谢!

trait CarFamily {
val carModel: String
def carModelStatement: String = s"The model of the car is ${carModel}"
}

trait Honda extends CarFamily {
val honda: String
override val carModel: String = honda
def hondaModelStatement : String = carModelStatement
}

trait Civic extends CarFamily {
val civic: String
override val carModel: String = civic
def civicModelStatement : String = carModelStatement
}

trait Volvo extends CarFamily {
val volvo: String
override val carModel: String = volvo
def volvoModelStatement : String = carModelStatement
}

object allModels extends Volvo with Civic with Honda {
val volvo = "Volvo X3"
val civic = "Civic Family"
val honda = "Honda Extreme"

}

allModels.volvoModelStatement //res1: String = The model of the car is null
allModels.civicModelStatement // res2: String = The model of the car is null
allModels.hondaModelStatement  // res3: String = The model of the car is null

2 回答

  • 0

    所以问题的根本原因是你的根特征中有一个抽象的 val . val s按顺序初始化(不是一次全部),这个顺序有时可能会令人惊讶 - 例如如果你覆盖这些 val 或者从同一个类的任何地方获得前向引用,你会看到 null s你不会指望它们 .

    因此,避免此类问题的经验法则很简单:始终使用 def 作为抽象成员 .

    此规则增加了一个额外的好处,即在用于实现/覆盖这些字段的成员类型中具有灵活性:您可以使用 defvalvarlazy val 扩展 def (后者有时非常有用) .

    此外,我试图了解你认为你对Scala中的多重继承的理解可能是错误的 . [277846]即使你在根特征中使用了 def ,在 allModels 中也只有一个 carModelcarModelStatement 的值 - 为依赖于这个属性的所有内容产生相同的字符串 .

  • 0

    我不认为你可以按照你想要的方式将 Value “存储”在特质成员中 .

    这有效:

    trait CarFamily {
      def carModelStatement(carModel: String): String = s"The model of the car is ${carModel}"
    }
    
    trait Honda extends CarFamily {
      val honda: String
      def hondaModelStatement : String = carModelStatement("honda")
    }
    
    trait Civic extends CarFamily {
      val civic: String
      def civicModelStatement : String = carModelStatement("civic")
    }
    
    trait Volvo extends CarFamily {
      val volvo: String
      def volvoModelStatement : String = carModelStatement("volvo")
    }
    
    object allModels extends Volvo with Civic with Honda {
      val volvo = "Volvo X3"
      val civic = "Civic Family"
      val honda = "Honda Extreme"
    
    }
    
    allModels.volvoModelStatement 
    allModels.civicModelStatement 
    allModels.hondaModelStatement
    

    输出:

    res0: String = The model of the car is volvo
    res1: String = The model of the car is civic
    res2: String = The model of the car is honda
    

相关问题