使用具有相同文件名和声明的特征
Using traits with the same fileds name and declaration
我有抽象的 class 人和两个特征 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};
我收到错误:
...inherits conflicting members: lazy value tax in trait Employee of type Double and value tax in trait Student of type Double ...
如何在同名字段中使用两个特征?
第一个问题是您试图用 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
理想的方法是为税收创建一个名为 Tax
的单独特征,并从该基本特征扩展 Employee
和 Student
。理想情况下,特征应该像接口一样工作,不应该有实际的实现。实现应该是扩展此特征的 class 的一部分。
下面的实现解决了这个问题
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
我有抽象的 class 人和两个特征 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};
我收到错误:
...inherits conflicting members: lazy value tax in trait Employee of type Double and value tax in trait Student of type Double ...
如何在同名字段中使用两个特征?
第一个问题是您试图用 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
理想的方法是为税收创建一个名为 Tax
的单独特征,并从该基本特征扩展 Employee
和 Student
。理想情况下,特征应该像接口一样工作,不应该有实际的实现。实现应该是扩展此特征的 class 的一部分。
下面的实现解决了这个问题
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