0

前提:

我想将实例化类所需的信息与“运行”类所需的信息分开。但是,“运行”课程所需的信息可能因课程而异。因此,我想这个类“有”运行它的特定信息,并且两者一起去。

这是我的代码示例:

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,那么我的架构是错误的。

所以

  1. 考虑到我提出的前提,我解决这个问题的方法是错误的吗?
  2. 如果没有错,有没有办法在使用def而不是valMachineOwner课堂上实现这一目标?

编辑 鉴于 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 }. 如何定义?

4

1 回答 1

1

如果不知道所需的语义,它真的无法回答。

如果MachineOwner应该拥有一台机器,那么“让它成为一个让实现者有更多自由的定义”是一个糟糕的建议:它提供的自由正是从不同的调用返回不同的机器def machine而不是保存对它的机器的引用分发。

如果它应该有多台机器,它们应该都具有相同的Params类型吗?然后你会做类似的事情

abstract class MachineOwner{

  type Params1 <: BaseParams

  def machine: Machine { type Params = Params1 }

  def params: Params1

  def startMachine(): Unit = {
    machine.start(params)
  }
}

或者,如果没有,那么您可能需要再次使用不同的设计def params(machine: Machine): machine.Params。等等等等。

对于编辑:你可以

class FlyingMachineOwner(
  _machine: FlyingMachine
) extends MachineOwner {

  override type Params1 = FlyingParams

  override def params = FlyingParams(1,1,1)

  override def machine = _machine
}

但与使用类型参数得到的相比,它确实看起来不必要地复杂。

于 2018-07-05T06:46:12.063 回答