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