Apache flex 如何解决将接口对象强制转换回其基类的需要?
这个问题一般适用于接口,但我将使用AS3/Flex作为我的语言。如何在不同的语言中应用它应该是显而易见的 如果我创建了一个基类,它扩展了一个接口,那么就定义了一个显式契约:对于接口中的每个方法,基类都必须实现该方法 这很容易。但我不明白为什么您有能力将接口实例转换回其原始基类。当然,我已经做过几次了(下面的例子非常接近我所面临的情况),但这并不意味着我理解它:^) 下面是一个示例界面:Apache flex 如何解决将接口对象强制转换回其基类的需要?,apache-flex,actionscript-3,interface,Apache Flex,Actionscript 3,Interface,这个问题一般适用于接口,但我将使用AS3/Flex作为我的语言。如何在不同的语言中应用它应该是显而易见的 如果我创建了一个基类,它扩展了一个接口,那么就定义了一个显式契约:对于接口中的每个方法,基类都必须实现该方法 这很容易。但我不明白为什么您有能力将接口实例转换回其原始基类。当然,我已经做过几次了(下面的例子非常接近我所面临的情况),但这并不意味着我理解它:^) 下面是一个示例界面: public interface IFooable extends IUIComponent { fu
public interface IFooable extends IUIComponent {
function runFoo():void;
}
public class Foo extends VBox implements IFooable {
public Foo() {
super();
//stuff here to create Foo..blah blah
}
public function runFoo():void {
// do something to run foo
}
}
public function init():void {
var foo:IFooable = new Foo();
foo.percentHeight = 100; //works because of IUIComponent
}
假设我创建了一个基类,它扩展了VBox并实现了接口:
public interface IFooable extends IUIComponent {
function runFoo():void;
}
public class Foo extends VBox implements IFooable {
public Foo() {
super();
//stuff here to create Foo..blah blah
}
public function runFoo():void {
// do something to run foo
}
}
public function init():void {
var foo:IFooable = new Foo();
foo.percentHeight = 100; //works because of IUIComponent
}
现在,我之所以使用这个接口,是因为我想保证“runFoo”总是实现的。这是我所有的类都应该拥有的一项公共功能,不管它们是如何实现的。因此,我的父类(应用程序)将通过其接口实例化Foo:
public interface IFooable extends IUIComponent {
function runFoo():void;
}
public class Foo extends VBox implements IFooable {
public Foo() {
super();
//stuff here to create Foo..blah blah
}
public function runFoo():void {
// do something to run foo
}
}
public function init():void {
var foo:IFooable = new Foo();
foo.percentHeight = 100; //works because of IUIComponent
}
但是,如果我想将Foo添加到应用程序容器中,我现在必须将其转换回基类(或其他基类):
最初的意图不是隐藏Foo的实现吗?仍然有一种假设,即Foo是一个DisplayObject。不幸的是,如果不强制转换,将自定义对象添加到容器中似乎是不可能的
我完全错过了什么吗?这真的只是Flex/AS3中的一种现象吗?如果您在一种语言的基本API中有一个容器,并且它只允许您添加特定类类型的子类,那么如何抽象出实现
作为记录,它似乎询问这种操作是否可行,但它并没有真正说明为什么它可能是糟糕的设计(以及如何修复它)
第二个想法: 抽象类: 正如Matthew指出的,抽象类有助于解决其中的一些问题:我可以创建一个从DisplayObject继承的基本抽象类(或者,在我的例子中,VBox,因为它是DisplayObject的子类),并让基类实现接口。因此,任何扩展抽象类的类都需要实现其中的方法 好主意——但是AS3没有抽象类(据我所知) 所以,我可以创建一个基类来实现接口和扩展VBox,并从中继承,我可以在需要扩展的方法中插入代码;如果基类是执行器,这样的代码将抛出错误。不幸的是,这是运行时检查,而不是编译时强制 不过,这仍然是一个解决方案
上下文: 一些上下文可能会有所帮助: 我有一个应用程序,可以有任何数量的子容器。每个子容器都有各自的配置选项、参数等。但是,应用程序本身有一个全局应用程序控制栏,其中包含用于访问这些配置选项的入口点菜单。因此,每当我向主应用程序添加子组件时(通过“addChild”),它也会使用ApplicationControl Bar菜单“注册”自己的配置选项。这保留了容器本身的可配置性知识,同时允许使用更统一的方法访问它们
因此,当我创建每个容器时,我希望通过它们的接口实例化它们,这样我可以保证它们可以注册到ApplicationControlBar。但是,当我将它们添加到应用程序中时,它们需要是基类。好的,我通常会回答,因为你说,“这真的只是Flex/AS3中的一种现象吗?” 在init方法中,显然您总是使用foo调用addChild。这意味着foo必须始终是DisplayObject的实例。您还希望它是IFooable的一个实例(尽管这里不清楚为什么)。因为DeStaseObjor是一个类,所以您将考虑使用DePosiObjor(例如FooBabeDePosiObjor)的子类,它实现了IFOOOLE。在Java中,这将如下所示。我不熟悉AS,但我认为这表明这里的接口没有任何一般性缺陷
interface IFooable
{
public void runFoo();
}
class DisplayObject
{
}
abstract class FooableDisplayObject extends DisplayObject implements IFooable
{
}
class Foo extends FooableDisplayObject
{
public void runFoo()
{
}
}
public void init()
{
FooableDisplayObject foo = new Foo();
foo.percentHeight = 100;
addChild(foo);
}
好吧,我一般都会这么说,因为你说,“这真的只是Flex/AS3中的一种现象吗?” 在init方法中,显然您总是使用foo调用addChild。这意味着foo必须始终是DisplayObject的实例。您还希望它是IFooable的一个实例(尽管这里不清楚为什么)。因为DeStaseObjor是一个类,所以您将考虑使用DePosiObjor(例如FooBabeDePosiObjor)的子类,它实现了IFOOOLE。在Java中,这将如下所示。我不熟悉AS,但我认为这表明这里的接口没有任何一般性缺陷
interface IFooable
{
public void runFoo();
}
class DisplayObject
{
}
abstract class FooableDisplayObject extends DisplayObject implements IFooable
{
}
class Foo extends FooableDisplayObject
{
public void runFoo()
{
}
}
public void init()
{
FooableDisplayObject foo = new Foo();
foo.percentHeight = 100;
addChild(foo);
}
我认为这是Flex/Flash的API不正确的地方。我认为
addChild
应该采用接口而不是类。然而,既然不是这样,你就必须投下它。另一个选项是使用monkey patchUIComponent
,这样它就可以使用一个接口,或者添加另一个方法,比如addIChild(IUIComponent)
。但那太乱了。所以我推荐你。我认为这是Flex/Flash API不正确的地方。我认为addChild
应该采用接口而不是类。然而,既然不是这样,你就必须投下它。另一个选项是使用monkey patchUIComponent
,这样它就可以使用一个接口,或者添加另一个方法,比如addIChild(IUIComponent)
。但那太乱了。所以我向您推荐。@James Ward,这绝对是我所希望的语言,可能是一个接口IDisplayObject。这将解决AS3中OOP显示编程中的许多问题
关于原问题,高级官员