【问题标题】:Is it ok to reference an abstract class in interface?在接口中引用抽象类可以吗?
【发布时间】:2013-09-02 09:37:23
【问题描述】:

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

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

于是我做了两个接口:

interface IEntity
interface IComponent

我为每个类做了一个抽象类

public class Component implements IComponent
public class Entity extends Sprite implements IEntity, IComponent

问题是在 IEntity 接口中我有一个函数:

function addComponent( e:Entity )

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

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

编辑:

这是接口:

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;  
}

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

问题是:

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。

希望这能解决我的问题。

【问题讨论】:

  • 如果您收到错误,请发布确切的错误信息!您还确定您的设置看起来像您描述的那样吗?这听起来有点奇怪,你在谈论 Entity 中的一个函数,然后你正在切换到“然后在组件中我需要引用实体”,Entity 也是IEntityIComponent 的混合体,现在我终于对你到底在哪里做什么感到困惑。
  • 是的,我的帖子有点乱,我下班后会发布更多代码
  • 我更新了我的帖子,希望现在更清楚
  • 是的,现在看起来完全不同了:)

标签: actionscript-3 oop components starling-framework


【解决方案1】:

我仍然不明白为什么会抛出这个错误,到目前为止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 之类的名称以避免混淆。

【讨论】:

  • 我也想过在接口中加入addChild,但是不知道你的接口可以扩展其他接口(这很整洁)。无论如何感谢您的回答,下班后会搞砸。
【解决方案2】:

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

每个 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-22
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    • 2013-07-11
    • 1970-01-01
    相关资源
    最近更新 更多