将父类强制转换为子类

时间:2014-03-02 23:09:00

标签: oop components haxe

所以我试图在我的框架中为游戏对象添加一个组件系统,我希望能够将所有组件存储在一个数组中(或映射......等),所以他们都可以可以轻松更新,并且类不必使用组件的预定义插槽,因此我创建了一个基本组件类,并创建了类型组件的映射,然后有其他组件扩展基本组件,如果可以正常工作我想要做的只是在所有这些上调用一个更新方法,但我希望他们都能够拥有他们想要的任何方法。当然,这不起作用,因为编译器不知道每个组件可能是哪个类。然后我发现我可以通过使用类似的东西(如果我知道它的类型)将组件强制转换为自己的类型:return cast(components.get("transform"), TransformComponent); 然后访问子功能。这是一种好的做事方式,还是一个可怕的设计决定,我应该重新设计组件的整个结构? 对不起,如果这是一个非常缺乏经验的问题,谢谢, 尼科

(注意我正在使用haxe,但我相信这适用于所有oop语言)

1 个答案:

答案 0 :(得分:2)

我个人认为这很好,只要你绝对确定你正在使用正确的类型 - 我已经看到其他一些Haxe库(例如minject)使用这种方法。

使用Haxe,您可以使用类似参数:

var c:Map<String,BaseComponent>;

public function getComponent<T:BaseComponent>( name:String, type:Class<T> ):T {
    if ( components.exists(name) ) {
        var c = components[name];
        if ( Std.is(c, type) ) {
            return cast c;
        }
    }
    return null; // the component with that name didn't exist, or was the wrong type
}

这样您的用法可以是:

var transform = componentManager.getComponent( "transform", TransformComponent );
if ( transform!=null ) {
    transform.doSomething();
}

在这种情况下,transform将完全输入为“TransformComponent”,编译器将允许您访问所有方法等。

最后一点,如果你只有每种类型组件的一个实例,你可以使这更容易:

public function addComponent<T:BaseComponent>( component:T ) {
    var type = Type.getClass( component );
    var name = Type.getClassName( type );
    components[name] = component;
}

public function getComponent<T:BaseComponent>( type:Class<T> ):T {
    var name = Type.getClassName( type );
    return cast components[name]; // Either the component with the correct type name, or null.
}

componentManager.addComponent( new TransformComponent() );
var t = componentManager.get( TransformComponent );
$type( t ); // TransformComponent, it is correctly typed