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

问题描述:

我想要做的是类似如下:是否可以在不继承类的情况下将行为添加到非动态ActionScript 3类?

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

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

这就是说,我想扩展生成的类与单一的方法,而不是通过继承,但通过原型。

从WSDL生成的类别,它不是一个动态类的,我不想碰生成的代码,因为它总要被改写。

长话短说,我想有C#3道德等价的:扩建方法AS3。

编辑:我接受了AIB的答案,因为它符合我问最好的 - 尽管在进一步思考它并没有真正解决我的问题,但是这是我的问错了问题故障。 :)另外,upmods的好建议。

+0

@aib是对的,我在测试时犯了一个错误。我忘了原型只能在类*问,而不能在每个对象*问,所以对我来说,我得到了运行时错误。但是,我的包装解决方案不是子类,它是包装。包装类只扩展原始的,以便它具有相同的类型。 – Theo 2008-08-14 20:39:16

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

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

尝试的

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中(<严格>真正< /严格>),甚至传递到MXMLC一个-compiler.strict参数?

Foo.as:

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

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

footest。如:

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表示继承是不可接受的,正如修改生成的代码。 (如果不将“动态”类定义的情况下,很可能是最简单的解决方案)

根据你们班有多少方法了,这可能工作:

实际类:

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不同)的事实。为了解决这个问题,您可以:

  1. 创建SpriteAsset.as的副本,并将其在/mx/core/SpriteAsset.as添加到您的项目
  2. 编辑您的本地副本来解决任何问题,你会发现
  3. 运行你的ap

谷歌“flex monkey patch”的更多的例子和说明。