前提:
我想将实例化类所需的信息与“运行”类所需的信息分开。但是,“运行”课程所需的信息可能因课程而异。因此,我想这个类“有”运行它的特定信息,并且两者一起去。
这是我的代码示例:
trait Machine {
type Params <: BaseParams
def start(machineParams: Params): Unit
}
trait BaseParams {
def speed: Int
def power: Int
}
class FlyingMachine() extends Machine {
type Params = FlyingParams
override def start(machineParams: Params): Unit = {
println(s"I'm flying with $machineParams")
}
}
trait FlyingParams extends BaseParams {
def height: Int
}
abstract class MachineOwner{
val machine: Machine
def params: machine.Params
def startMachine(): Unit = {
machine.start(params)
}
}
这编译,通过测试,我很高兴。
问题:我使用val machine: Machine
它来定义def params: machine.Params
. 有人告诉我这样做是def
为了让实施者有更多的自由。如果我这样做,我将无法再参考machine.Params
在这一点上,我不知道如何继续。我一直在想,如果这应该是 adef
并且绝对不是 a val
,那么我的架构是错误的。
所以
- 考虑到我提出的前提,我解决这个问题的方法是错误的吗?
- 如果没有错,有没有办法在使用
def
而不是val
在MachineOwner
课堂上实现这一目标?
编辑 鉴于 Alexey Romanov 的回答,代码的最后一点看起来像这样
abstract class MachineOwner{
type Params1 <: BaseParams
def machine: Machine { type Params = Params1 }
def params: Params1
def startMachine(): Unit = {
machine.start(params)
}
}
class FlyingMachineOwner(
machine: FlyingMachine
) extends MachineOwner {
override type Params1 = FlyingParams
override def params = FlyingParams(1,1,1)
}
但这不会编译,因为它需要专门针对def machine: Machine { type Params = Params1 }
. 如何定义?