我有一个抽象的类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的Employee和类型为Double的Student的trait中的懒惰值税 ...
我如何使用两个具有相同名称的字段的traits?
理想的方法是为tax创建一个单独的Trait,称为 Tax
并延长 Employee
和 Student
从这个Base trait中获取。特质最好是像一个接口一样,不应该有实际的实现。实现应该是扩展这个traits的类的一部分。
下面的实现就解决了这个问题
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
第一个问题是,你在这里试图覆盖 val
与 var
而第二个问题称为钻石问题。这个问题可以用如下方法解决。
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.comcurious-case-of-putting-over-modifier...
而你可以在这里阅读更多关于线性化的内容。http:/eed3si9n.comconstraining class-linearization-in-Scala。还有这里。https:/www.artima.comscalazinearticlesstackable_trait_pattern.html