如何使用泛型设计多态类

时间:2016-12-23 04:51:15

标签: scala

我尝试用通用多态性设计api

trait GameState {
  def doIt(): Unit
}

trait GameMechanics[T <: GameState] {
  def stateHolder: StateHolder[T]
}

abstract class AbsGameMechanics[T <: GameState](sh: StateHolder[T]) extends GameMechanics[T] {
  override def stateHolder: StateHolder[T] = sh
}

class StateHolder[T <: GameState](var state: T) {
  def get: T = state
  def set(_state: T): Unit = state = _state
}

因此,用户应该扩展GameStateAbsGameMechanicsGameMechanics应具有特定类型GameStateDominoMechanics =&gt; DominoGameState

用户介绍新游戏:

class DominoGameState extends GameState {
  override def doIt(): Unit = println("domino working!")
}

class DominoMechanics(sh: StateHolder[DominoGameState]) extends AbsGameMechanics[DominoGameState](sh)

val domino = new DominoMechanics(new StateHolder[DominoGameState](new DominoGameState))

在我的系统中,我应该对状态进行多态调用

def internal(gm: GameMechanics[GameState]): Unit = {
  gm.stateHolder.get.doIt()
}

它没有编译,我无法理解它是什么意思:

internal(domino)
  

错误:(41,11)类型不匹配;发现:A $ A133.this.DominoMechanics   必需:A $ A133.this.GameMechanics [A $ A133.this.GameState]注:   A $ A133.this.DominoStarting&lt ;: A $ A133.this.GameState(和   A $ A133.this.DominoMechanics&lt;:   A $ A133.this.AbsGameMechanics [A $ A133.this.DominoStarting]),但特质   GameMechanics在类型T中是不变的。您可能希望将T定义为+ T   代替。 (SLS 4.5)内部(多米诺骨牌)            ^

我做错了什么。什么?

1 个答案:

答案 0 :(得分:0)

您的方法document.getElementById('IdOfElement').value仅接受internal,但您尝试传入GameMechanics[GameState],这不是GameMechanics[DominoStarting]的子类型,因为GameMechanics[GameState]是类型GameMechanics中的不变量。您可能想要查找有关不变性和协方差的其他一些问题,因为有很多。

但我认为代码中的问题不一定是协方差或不变性。你不应该要求T。您已将GameMechanics[GameState]定义为必须是T的子类型...如果您接受任何类型的GameState,您应该怎么做:

GameMechanics

或者当您不关心确切的类型时:

def internal[S <: GameState](gm: GameMechanics[S]): Unit = {
  gm.stateHolder.get.doIt()
}
相关问题