在接口中引用抽象类是否可以?

时间:2013-09-02 09:37:23

标签: actionscript-3 oop components starling-framework

我正在尝试为自己编写一个基于实体组件的游戏框架。我刚刚遇到基类系统的逻辑问题。

问题是我有两件事,实体(可以包含其他实体和组件)和组件(它们附加到某个实体)。

所以我做了两个接口:

interface IEntity
interface IComponent

我为每个

制作了一个抽象类
public class Component implements IComponent
public class Entity extends Sprite implements IEntity, IComponent

问题是在IEntity界面中我有一个函数:

function addComponent( e:Entity )

参数类型i Entity的原因是因为然后在Component I中需要引用它从Sprite继承的实体函数(我不能用IEntity类型那样做)。

但似乎Flash Develop将其视为错误(在Entity类中实现此功能)。我做错了吗?

编辑:

这是接口:

public interface IComponent
{
    function get parentGameObject() : IEntity;
    function set parentGameObject( v:IEntity ) : void;
    function init() : void;
    function dispose() : void;
}

public interface IEntity
{
    function addComponent( c:IComponent ) : IComponent;
    function removeComponent( c:IComponent ) : Boolean;
    function getComponent( type:Class ) : IComponent;
    function hasComponentOfType( type:Class ) : Boolean;
    function addGameObject( child:Entity ) : void;  
}

然后我的抽象Entity类实现了这两个接口+从DisplayObjectContainer扩展,因为每个Entity都需要渲染自身及其子实体的功能。

问题在于:

public function addGameObject( e:Entity ) : void {
    m_components.push( v );

    this.addChild( v );
    v.gameObject = this;
    v.init();
}

似乎无效,错误是:接口IEntity中的接口方法addGameObject是使用类Entity 中的不兼容签名实现的。

我之所以要使用e:Entity而不是e:IEntity是因为我使用的是this.addChild(v),它属于DisplayObjectContainer。

希望能解决我的问题。

2 个答案:

答案 0 :(得分:0)

我仍然无法理解为什么会抛出此错误,到目前为止addGameObject的实现看起来还不错(我假设v的使用是一个问题,只是在示例代码中存在?)虽然参数名称与接口定义的不同之处在于child而不是e,但AFAIK在AS3中有效,但尝试使用界面中定义的名称。

关于实际问题,当然答案取决于。通常,您可以在界面中引用您喜欢的任何类,这里唯一的问题应该是设计模式。

如果你想继续对接口进行编程,那么你可以简单地创建一个强制实现addChild方法的游戏对象接口,如下所示:

import flash.display.DisplayObject;

public interface IGameObject extends IComponent, IEntity
{
    function addChild(child:DisplayObject):DisplayObject;
}

相应地更改您的IEntity界面,addGameObjectEntity实施,您应该好好去:

public interface IEntity
{
    ...
    function addGameObject( child:IGameObject ) : void;  
}
public function addGameObject( child:IGameObject ) : void {
    ...
}
public class Entity extends Sprite implements IGameObject 

虽然您可能希望将Entity重命名为GameObject,以避免混淆。

答案 1 :(得分:0)

这就是我现在解决这个问题的方法:

每个GameObject功能的三个基本接口:

public interface IComponent
{
    function get gameObject() : IGameObject;
    function set gameObject( v:IGameObject ) : void;
    function init() : void;
    function dispose() : void;  
}

public interface IDisplayObjectContainer
{
    function get displayContainer() : DisplayObjectContainer;
}

public interface IEntity
{
    function addComponent( c:IComponent ) : IComponent;
    function removeComponent( c:IComponent ) : Boolean;
    function getComponent( type:Class ) : IComponent;
    function hasComponentOfType( type:Class ) : Boolean;    
}

现在我的复合GameObject接口正在扩展所有这些功能:

public interface IGameObject extends IEntity, IComponent, IDisplayObjectContainer
{
        function addGameObject( g:IGameObject ) : void;
}