Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache flex 如何解决将接口对象强制转换回其基类的需要?_Apache Flex_Actionscript 3_Interface - Fatal编程技术网

Apache flex 如何解决将接口对象强制转换回其基类的需要?

Apache flex 如何解决将接口对象强制转换回其基类的需要?,apache-flex,actionscript-3,interface,Apache Flex,Actionscript 3,Interface,这个问题一般适用于接口,但我将使用AS3/Flex作为我的语言。如何在不同的语言中应用它应该是显而易见的 如果我创建了一个基类,它扩展了一个接口,那么就定义了一个显式契约:对于接口中的每个方法,基类都必须实现该方法 这很容易。但我不明白为什么您有能力将接口实例转换回其原始基类。当然,我已经做过几次了(下面的例子非常接近我所面临的情况),但这并不意味着我理解它:^) 下面是一个示例界面: public interface IFooable extends IUIComponent { fu

这个问题一般适用于接口,但我将使用AS3/Flex作为我的语言。如何在不同的语言中应用它应该是显而易见的

如果我创建了一个基类,它扩展了一个接口,那么就定义了一个显式契约:对于接口中的每个方法,基类都必须实现该方法

这很容易。但我不明白为什么您有能力将接口实例转换回其原始基类。当然,我已经做过几次了(下面的例子非常接近我所面临的情况),但这并不意味着我理解它:^)

下面是一个示例界面:

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 patch
UIComponent
,这样它就可以使用一个接口,或者添加另一个方法,比如
addIChild(IUIComponent)
。但那太乱了。所以我推荐你。

我认为这是Flex/Flash API不正确的地方。我认为
addChild
应该采用接口而不是类。然而,既然不是这样,你就必须投下它。另一个选项是使用monkey patch
UIComponent
,这样它就可以使用一个接口,或者添加另一个方法,比如
addIChild(IUIComponent)
。但那太乱了。所以我向您推荐。

@James Ward,这绝对是我所希望的语言,可能是一个接口IDisplayObject。这将解决AS3中OOP显示编程中的许多问题

关于原问题,高级官员