是否可以在不继承该类的情况下向非动态ActionScript 3类添加行为?

时间:2020-03-05 18:38:50  来源:igfitidea点击:

我想做的事情如下:

FooClass.prototype.method = function():String
{
    return "Something";
}

var foo:FooClass = new FooClass();
foo.method();

也就是说,我想用一种方法扩展生成的类,而不是通过继承,而是通过原型。

该类是从WSDL生成的,它不是动态类,并且我也不想触摸所生成的代码,因为无论如何它将被覆盖。

长话短说,我想在道德上等同于AS3的C3:s扩展方法。

编辑:我接受了aib的回答,因为它符合我的要求,尽管经过进一步思考,它并不能真正解决我的问题,但这是我提出错误问题的错。 :)另外,upmods提供了很好的建议。

解决方案

回答

是的,这样的事情是可能的。

实际上,示例非常接近解决方案。

尝试

foo["method"]();

代替

foo.method();

回答

不幸的是,@ aib是不正确的。假设采用严格模式(默认的编译器模式),则无法在ActionScript 3中修改非动态类类型的原型。我什至不能确定是否可以在非严格模式下进行修改。

是否包装选项?基本上,我们创建一个类,该类采用从Web服务获取的对象之一,并将所有方法调用转发给该对象,但也具有自己的方法:

public class FooWrapper extends Foo {

    private var wrappedFoo : Foo;

    public function FooWrapper( foo : Foo ) {
        wrappedFoo = foo;
    }

    override public function methodFromFoo( ) : void {
        wrappedFoo.methodFromFoo();
    }

    override public function anotherMethodFromFoo( ) : void {
        wrappedFoo.anotherMethodFromFoo();
    }

    public function newMethodNotOnFoo( ) : String {
        return "Hello world!"
    }

}

当我们想使用Foo,但又需要额外的方法时,我们需要将Foo实例包装在FooWrapper中,然后使用该对象。

这不是最方便的解决方案,要进行大量输入,如果生成的代码发生更改,则必须手动更改FooWrapper类,但是除非我们可以修改生成的代码以包含所需的方法或者创建该类,否则动态的,我不知道该怎么做。

另一个解决方案是在构建过程中添加一个步骤,以修改生成的类的源。我假设我们已经有一个从WSDL生成代码的步骤,因此我们可以做的是在此之后添加一个步骤,以插入所需的方法。

回答

@Theo:我们如何解释在3.0.0.477中使用默认的flex-config.xml(<strict> true </ strict>)甚至是传递给mxmlc的-compiler.strict参数来执行以下操作?

Foo.as:

package
{
    public class Foo
    {
        public var foo:String;

        public function Foo()
        {
            foo = "foo!";
        }
    }
}

脚注:

package
{
    import flash.display.Sprite;

    public class footest extends Sprite
    {
        public function footest()
        {
            Foo.prototype.method = function():String
            {
                return "Something";
            }

            var foo:Foo = new Foo();
            trace(foo["method"]());
        }
    }
}

请注意,OP表示继承是不可接受的,修改生成的代码也是如此。 (如果不是这种情况,则在类定义中添加" dynamic"可能是最简单的解决方案。)

回答

根据类有多少种方法,这可能会起作用:

实际班级:

public class SampleClass
{
    public function SampleClass()
    {
    }

    public function method1():void {
        Alert.show("Hi");
    }

快速包装:

var actualClass:SampleClass = new SampleClass();

var QuickWrapper:Object = {
    ref: actualClass,
    method1: function():void {
        this.ref.method1();
    },
    method2: function():void {
        Alert.show("Hello!");
    }   
};

QuickWrapper.method1();
QuickWrapper.method2();

回答

猴子修补是一个(模糊的)选项。

例如,假设我们不喜欢Flex 3 SpriteAsset.as返回默认边框度量标准[7,7,7,7](与flex 2不同)的事实。要解决此问题,我们可以:

  • 创建SpriteAsset.as的副本并将其添加到项目中,位于/mx/core/SpriteAsset.as
  • 编辑本地副本以解决我们发现的任何问题
  • 运行你的ap

谷歌" flex猴子补丁"获得更多示例和说明。