Haxe - 如何将变量声明为父实例或子实例 class

Haxe - How to declare variable to be either instance of parent or child class

假设我有两个 classes:

class PlayerManagerParent {
   public function new(){
   }  
}

class GameManagerParent {
   public var playerManager:PlayerManagerParent();

   public function new(){
   }  
}

然后我将class分

class PlayerManagerChild extends PlayerManagerParent {
   public function new(){
      super();
   }  

   public function someMethod(){
   }
}

class GameManagerChild extends GameManagerParent {

   public function new(){
      super();
      this.playerManager = new PlayerManagerChild();
   }  
}

然后我创建 GameManagerChild 的实例并想要访问 someMethod():

var gameManager:GameManagerChild = new GameManagerChild();
gameManager.playerManager.someMethod();

我当然不能这样做,因为 gameManager.playerManagerplayerManager:PlayerManagerParent 的类型,没有定义 someMethod() 并且编译器/类型检查器给我错误。

如何在不在父 class 中声明 someMethod() 或将 playerManager 类型设置为 Dynamic 的情况下解决此问题(这是一个选项,但我不能遍历 playerManager 中的可迭代字段,例如)?

您可以为此使用受约束的参数化类型:

class PlayerManagerParent {
   public function new(){
   }  
}

class GameManagerParent<T:PlayerManagerParent> {
   public var playerManager:T;

   public function new(){
   }  
}

有了这个,你可以像这样扩展:

class PlayerManagerChild extends PlayerManagerParent {
   public function new(){
      super();
   }  

   public function someMethod(){
   }
}

class GameManagerChild extends GameManagerParent<PlayerManagerChild> {

   public function new(){
      super();
      this.playerManager = new PlayerManagerChild();
   }  
}

这允许你这样做:

var child = new GameManagerChild();
child.playerManager.someMethod();

实例:
http://try.haxe.org/#21bfC

See also:
http://haxe.org/manual/type-system-type-parameters.html

Protip: You could even mark it as @:generic, which might be gain extra performance at some platforms: http://haxe.org/manual/type-system-generic.html

您可能应该使用类型参数,例如:

class GameManagerParent<PM:PlayerManagerParent> {
     public var playerManager : PM;
}

class GameManagerChild 
extends GameManagerParent<PlayerManagerChild> {
     public function new() {
         playerManager = new PlayerManagerChild();
     }
}