trait Operation {
def something: Double
}
trait OperationPlus { this: A =>
override def something: Double = x + y
}
trait OperationMinus { this: A =>
override def something: Double = x - y
}
case class A(x: Double, y: Double) { this: Operation =>
}
val a = new A(1.0, 2.0) with OperationPlus
println(a.something)
错误:
class A cannot be instantiated because it does not conform to its self-type A with Operation
而且,我不能实例A.
我尝试多种不同的方法,但没有提供我在找什么。我不想使用案例类继承,或放弃案例类,理想情况下特质/自我类型/其他应该做的伎俩。有任何想法吗?
更新 优选溶液
trait Operation { this: A =>
def something: Double
}
trait OperationPlus extends Operation { this: A =>
override def something: Double = x + y
}
trait OperationMinus extends Operation { this: A =>
override def something: Double = x - y
}
abstract case class A(val x: Double, val y: Double) extends Operation
val a = new A(1.0, 2.0) with OperationPlus
println(a.something)
val b = new A(1.0, 2.0) with OperationMinus
println(b.something)
可能的解决方案1:
trait Operation {
def x:Double
def y:Double
def something: Double
}
trait OperationPlus extends Operation {
override def something: Double = x + y
}
trait OperationMinus extends Operation {
override def something: Double = x - y
}
abstract case class A(val x: Double, val y: Double) extends Operation
通过使用常规类,简单性状遗传和自型中的实际值可以定义它并动态地提供行为。
不幸的是,我不得不重新定义特质中的字段。我想是公平的妥协。会有兴趣知道是否有人知道另一种方法。
感谢
感谢@tenshi,如果我做的情况下抽象类,我将无法进行实例化。我想要做的是一个经典的面向对象的父类,并为每个子类定义一个方法。然而,这些方法可以被不同的层次重复使用,所以我想使它成为一个基本特征。我无法找到如何提取出来。 – fracca
@fracca你仍然可以通过在一些操作中混合实例化:'new A(1.0,2.0)和OperationMinus'。但是在你的示例方法中,'something'是抽象的,所以你需要定义它或者让整个类变得抽象。或者,您可以直接在'A'类中扩展'OperationMinus'或'OperationPlus',并且不要声明它是抽象的。 – tenshi
抽象案例类有效地允许我们保留案例类的好处加上行为混合。但是,因为某些操作是基于A定义的,所以我需要重新定义字段x和y。 – fracca