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

时间:2008-08-10 15:05:33

标签: flex actionscript-3 extension-methods

我想做的事情如下:

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

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

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

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

长话短说,我希望道德等同于C#3:AS3的扩展方法。

编辑:我接受了aib的回答,因为它符合我最好的要求 - 虽然经过进一步反思它并没有真正解决我的问题,但这是我提出错误问题的错。 :)此外,upmods提供了很好的建议。

5 个答案:

答案 0 :(得分:3)

@Theo:您如何使用默认的flex-config.xml(< strict> true< / strict>)以及传递给mxmlc的-compiler.strict参数来解释以下在3.0.0.477中工作的内容?

Foo.as:

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

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

footest.as:

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”可能是最简单的解决方案。)

答案 1 :(得分:3)

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

事实上,您的示例非常接近解决方案。

尝试

foo["method"]();

而不是

foo.method();

答案 2 :(得分:2)

根据您班级的方法数量,这可能有效:

实际班级:

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();

答案 3 :(得分:1)

猴子补丁是一种(不优雅的)选择。

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

  1. 创建一个SpriteAsset.as副本并将其添加到项目/mx/core/SpriteAsset.as
  2. 编辑本地副本以解决您发现的任何问题
  3. 运行你的ap
  4. Google“flex monkey patch”了解更多示例和说明。

答案 4 :(得分:1)

@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生成代码的步骤,所以你可以做的就是在那之后添加一个插入你需要的方法的步骤。