免责声明:这个问题不是关于我是否应该这样做,或者它是一个好的设计还是任何相关的推理。问题是如何做到这一点。我在后面解释原因只是为了澄清。
我可以参数化Scala特征吗?我知道他们不能有构造函数参数 - 有不同的方法吗?对于某些事情(当然这只是一个例子)
case class MyMachine(myDouble: Double) {
def methodEveryMachineHas(): Double = 2 * myDouble
}
trait Drivable {
this: MyMachine =>
def drive(x: Double): Double = HowToDriveFunction(x) * myDouble
}
object HowToDriveFunction extends (Double => Double) {
def apply(x:Double): Double = x + 6.0
}
val myMachine1 = new MyMachine(3.0)
myMachine1.methodEveryMachineHas // 6.0
myMachine1.drive(4.0) // error
val myMachine2 = new MyMachine(3.0) with Drivable
myClass1.methodEveryMachineHas // 6.0
myClass1.drive(4.0) // 30.0 = (4.0 + 6.0) * 3.0
如何将HowToDriveFunction
传递给drive
?
函数应该固定在对象(=实例化类)本身中。因此,我希望在创作过程中给予它。但是并非所有MyMachine
都具有驱动能力。
想象一下MyMachine
成为一台机器,并Drivable
说它是可驾驶的 - 如果某些东西不能通过逻辑驱动,我认为它也不应该在技术上能够驱动,因此特点。但是我仍然需要解释(通过HowToDriveFunction
)这种特定机器(可能是汽车或飞机)的驾驶方式。但是,为什么我能够解释每台机器如何驾驶?这是没有意义的。我只想向那些可以开车的人解释一下。因此,我想给HowToDriveFunction
提供特性(表示机器可以驱动,因此应该能够首先驱动)。 如何驾驶工作不是一种能力(=特质),而是对力学的描述,应该由我认为的一个功能来表示。如果它在逻辑上是不同的,那么如果用不同的编程结构表示它会很好。
当然,我的实际内容与机器无关 - 这只是一个例子。
如果我的功能是通过其他特性给出的,我可以写
trait HowToDriveFunction {
this: Drivable =>
???
}
确保只有那些Drivable
获得HowToDriveFunction
的子类,但由于原因的解释,这对我来说似乎并不那么美好。
最后但并非最不重要的是,我觉得拥有composition over inheritance很好,因为我觉得它更容易推理代码。
答案 0 :(得分:3)
我不确定我是否完全理解这个问题,但似乎归结为
如何将
HowToDriveFunction
传递给drive
?
能够在不可驾驶的情况下定义MyMachine
。
为此,您只需在Drivable
中定义一个抽象成员。
case class MyMachine(myDouble: Double) {
def methodEveryMachineHas: Double = 2 * myDouble
}
trait Drivable {
this: MyMachine =>
protected def driveFunction: Double => Double
def drive(x: Double): Double = driveFunction(x) * myDouble
}
object HowToDriveFunction extends (Double => Double) {
def apply(x: Double): Double = x + 6.0
}
val myMachine1 = new MyMachine(3.0)
myMachine1.methodEveryMachineHas // 6.0
myMachine1.drive(4.0) // error
val myMachine2 = new MyMachine(3.0) with Drivable {
val driveFunction = HowToDriveFunction
}
myMachine2.methodEveryMachineHas // 6.0
myMachine2.drive(4.0) // 30.0 = (4.0 + 6.0) * 3.0