【问题标题】:Using traits with the same fileds name and declaration使用具有相同文件名和声明的特征
【发布时间】:2020-04-30 18:08:52
【问题描述】:

我有抽象类 Person 和两个特征 Employee 和 Student

abstract class Person(val name: String) {
  val tax: Double
}

trait Employee {
  val salary: Double;
  lazy val tax: Double = salary * 0.1;
}

trait Student {
  val tax: Double = 0.0;
}

我需要使用这两个特征创建 2 个实例

studentEmployee = new Person("John") with Student with Employee {override var salary: Double = 1000};
employeeStudent = new Person("Mike") with Employee with Student {override var salary: Double = 1000};

我得到错误:

...继承冲突的成员:Double 类型的 trait Employee 中的惰性值税和 Double 类型的 trait Student 中的值税 ...

如何在同名字段中使用两个特征?

【问题讨论】:

  • 定义返回值的抽象方法时,不要使用val。使用def tax: Double

标签: scala traits


【解决方案1】:

理想的方法是为税收创建一个名为Tax 的单独特征,并从这个基本特征扩展EmployeeStudent。理想情况下,特征应该像一个接口一样,不应该有实际的实现。实现应该是扩展此特征的类的一部分。

下面的实现解决了这个问题

abstract class Person(val name: String) {
}

trait Tax {
    val tax: Double

}
trait Employee extends Tax {
  val salary : Double;
  override val tax : Double ;
}

trait Student extends Tax {
  override val tax : Double;
}

var studentEmployee = new Person("John") with Student with Employee {
                   override val salary: Double = 1000;
                   override val tax = salary * 0.1};


var employeeStudent = new Person("Mike") with Employee with Student {
                  override val salary: Double = 1000 ;
                  override val tax = 0.0};

scala> studentEmployee.tax
res42: Double = 100.0

scala> employeeStudent.tax
res43: Double = 0.0

【讨论】:

  • 我选择这个稍加修改。我仍然在 Traits 中声明税收价值,并且在创建对象实例时不要覆盖它们
【解决方案2】:

第一个问题是您试图用var 覆盖val,第二个问题称为菱形问题。问题可以解决如下:

abstract class Person(val name: String) {
  val tax: Double
}

trait Employee {
  var salary: Double
  val tax: Double = salary * 0.1
}

trait Student {
  val tax: Double = 0.0
}


val studentEmployee = new Person("John") with Student with Employee {
override val tax = 2.0
  override var salary: Double = 1000
}
val employeeStudent = new Person("Mike") with Employee with Student {
  override val tax = 2.0
  override var salary: Double = 1000
}

你可以在这里找到类似的问题解决方案:http://eed3si9n.com/curious-case-of-putting-override-modifier

您可以在此处阅读有关线性化的更多信息:http://eed3si9n.com/constraining-class-linearization-in-Scala 在这里:https://www.artima.com/scalazine/articles/stackable_trait_pattern.html

【讨论】:

  • 我在手机上写的无法隐藏链接,稍后会编辑
  • 我相信在这种情况下,studentEmployeeemployeeStudent 的税值将保持为 2.0
  • 这只是一个示例案例如何消除错误,您可以乘以工资值。但是,如果您想获得动态结果,您可以使用 def/closure(方法)进行税收,并且不需要将薪水字段定义为可变变量
  • 这个用 var 覆盖的 val 这只是一个错字。感谢您的回答,但这是压倒性税收的问题,所以我没有特质税。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多