2015-10-26 3 views
2

Предположим, что у меня есть два класса:Haxe - Как объявить переменную быть экземпляром родительского или дочернего класса

class PlayerManagerParent { 
    public function new(){ 
    } 
} 

class GameManagerParent { 
    public var playerManager:PlayerManagerParent(); 

    public function new(){ 
    } 
} 

который я подклассы, как

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.playerManager - тип playerManager:PlayerManagerParent, который не определяет someMethod(), а компилятор/typechecker дает мне ошибку.

Как я могу решить эту проблему без объявления someMethod() в родительском классе, или установка playerManager типа в Dynamic (который был бы вариант, но тогда я не могу перебрать Iterable полей в playerManager, например)?

ответ

4

Вы можете использовать ограниченного параметризированный типа этого:

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

Смотрите также:
http://haxe.org/manual/type-system-type-parameters.html

Protip: Можно даже пометить его как @:generic, который может быть получить дополнительную производительность на некоторых платформах: http://haxe.org/manual/type-system-generic.html

+0

Meh, ваш документирован больше :) – clemos

+0

Ну, это частично решает мою проблему, но когда я пытаюсь сделать это в вашем примере Класс тестирования: 'var child2: GameManagerParent = child;', т работы. – wildfireheart

+0

Это правильно, но я думаю, что это тоже точно ожидается, потому что у родителя нет этой функции, верно? –

3

Вы должны вероятно, используйте параметры типа, например:

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

class GameManagerChild 
extends GameManagerParent<PlayerManagerChild> { 
    public function new() { 
     playerManager = new PlayerManagerChild(); 
    } 
} 
Смежные вопросы