Actionscript 3 面向对象编程在AS3中正确使用接口

Actionscript 3 面向对象编程在AS3中正确使用接口,actionscript-3,oop,Actionscript 3,Oop,我正在设计一个框架,在这个过程中我遇到了一个有趣但很可能是基本问题。我有一个名为CoreEngine的基类,还有另外两个扩展它的类:CoreEngine1和CoreEngine2。我创建了一个接口,每个类都将实现该接口,以增加项目的灵活性。然而,我有一个问题。。。接口中我的方法的定义与每个继承类中的定义不匹配!每个类必须实现以下方法: 函数get avatar():AvatarBase 问题在于CoreEngine1和CoreEngine2期望不同类型的化身: CoreEngine1 函数get

我正在设计一个框架,在这个过程中我遇到了一个有趣但很可能是基本问题。我有一个名为CoreEngine的基类,还有另外两个扩展它的类:CoreEngine1CoreEngine2。我创建了一个接口,每个类都将实现该接口,以增加项目的灵活性。然而,我有一个问题。。。接口中我的方法的定义与每个继承类中的定义不匹配!每个类必须实现以下方法:

函数get avatar():AvatarBase

问题在于CoreEngine1和CoreEngine2期望不同类型的化身:

CoreEngine1

函数get avatar():AvatarScaling

CoreEngine2

函数get avatar():AvatarPlatform

如您所见,CoreEngine1和CoreEngine2中化身的返回类型与界面中指定的类型不匹配。我希望,既然avatascaling和AvatarPlatform都继承了AvatarBase,我就不会有编译问题了。然而,情况并非如此。根据Adobe的文档,类型必须与接口匹配。我试图遵循面向对象编程的一个核心概念来扩展我的框架的灵活性:“编程到接口而不是实现”。我想到的第一件事是访问器方法的返回类型应该是接口类型(也许我刚才回答了我自己的问题)

我相信这是其他人以前遇到过的常见问题。在架构上,您认为解决这个问题的最佳方法是什么?提前谢谢

问候,


威尔

我想你回答了你自己的问题。。。返回类型仍然是AvatarBase,您需要遵循在接口中指定的签名。。。但从技术上讲,您可以在该函数中返回AvatarBase的任何后代。所以做一些类似于

return new AvatarScaling();
在CoreEngine1中,这是完全可以接受的

当然,在您的调用函数中,您将返回一个avatabase实例,并且您必须知道这是什么,以便强制转换到特定的子类

CoreEngine1 ce1 = new CoreEngine1();
AvatarScaling avatar = ce1.avatar() as AvatarScaling; 

这是对接口工作方式和声明方式的限制


如果返回类型存在继承,正如您在
AvatarBase
和子类中所描述的那样,那么我认为正确的方法是将返回类型设置为最低公分母,并在另一端处理结果对象。因此,如果您正在处理
CoreEngine1
对象,您知道可以将结果从
AvatarBase
转换为
AvatarScaling
。或者,如果您不知道正在调用的对象类型
get avatar()
,则可以键入检查返回值。只有当您希望调用
AvatarScaling
上存在但不在
AvatarBase
上的方法时,才需要进行类型检查。我认为在这种情况下,返回一个接口类型不会给你带来太多好处,因为接口可以实现的唯一东西是所有形式的化身共享的东西,这与
AvatarBase

中的方法没有什么不同,就像霍顿和丁科提到的那样,最好允许
get Avatar()
始终返回avatabase,然后将返回的对象转换为具体的子类

CoreEngine1 ce1 = new CoreEngine1();
AvatarScaling avatar = ce1.avatar() as AvatarScaling; 
以丁科为例:

public /* abstract */ class CoreEngine
{ 
   public /* abstract */ function get avatar():AvatarBase {}
}

public function CoreEngine1 extends CoreEngine
{
   override public function get avatar():AvatarBase { return new AvatarScaling(); }
}

public function CoreEngine2 extends CoreEngine
{
   override public function get avatar():AvatarBase { return new AvatarPlatform(); }
}

public /* abstract */ class AvatarBase {}

public class AvatarScaling extends AvatarBase 
{ 
   public function someAvatarScalingMethod():void {}
}

public class AvatarPlatform extends AvatarBase 
{ 
   public function someAvatarPlatformMethod():void {}
}
要使用来自AvatarScaling的方法,请强制转换返回的对象:

var c1:CoreEngine1 = new CoreEngine1();
var avatarScaling:AvatarScaling = AvatarScaling(c1.avatar());
avatarScaling.someAvatarScalingMethod();

hth

同意。我确保保留基本类型,并在必要时进行类型转换。我的希望是,如果我在CoreEngine2中声明avatar为AvatarPlatform类型,我就可以返回该类型而不必放弃。但这似乎是正确的方法。谢谢你的反馈。谢谢你的回复。看起来我必须使用typecast方法。这就是你应该做的。那代码不是AS3,你的意思是
var ce1:CoreEngine=new CoreEngine1();变量为:AvaterScaling=ce1.avatar()作为AvatarScaling
(AvatarScaling)(ce1.avatar())
AvatarScaling(ce1.avatar())