クラスを継承せずに、非動的 ActionScript 3 クラスに動作を追加することはできますか?

StackOverflow https://stackoverflow.com/questions/7212

質問

私がやりたいことは次のようなことです。

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

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

つまり、継承ではなくプロトタイプを介して、単一のメソッドで生成されたクラスを拡張したいと考えています。

このクラスは WSDL から生成され、動的クラスではありません。生成されたコードはいずれにせよ上書きされるため、触りたくないのです。

簡単に言うと、私は C# 3: AS3 用の拡張メソッドと道徳的に同等のものを持ちたいと考えています。

編集:私は aib の答えを受け入れました。それが私が求めていたことに最もよく合っていたからです。ただし、よく考えてみると、それは実際には私の問題を解決しませんでしたが、間違った質問をした私の責任です。:) また、良い提案に対する upmod もお願いします。

役に立ちましたか?

解決

はい、そのようなことは可能です。

実際、あなたの例は解決策に非常に近いです。

試す

foo["method"]();

の代わりに

foo.method();

他のヒント

@テオ:デフォルトの flex-config.xml (<strict>true</strict>) と -compiler.strict パラメータが mxmlc に渡された場合の 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」を追加するのがおそらく最も簡単な解決策でしょう。)

クラスにあるメソッドの数によっては、これが機能する場合があります。

実際のクラス:

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

@aib は残念ながら間違っています。厳密モード(デフォルトのコンパイラモード)を想定すると、ActionScript 3 で非動的クラスタイプのプロトタイプを変更することはできません。非厳密モードでそれが可能かどうかさえわかりません。

ラッピングはオプションでしょうか?基本的には、Web サービスから取得したオブジェクトの 1 つを取得し、すべてのメソッド呼び出しをそれに転送するクラスを作成しますが、独自のメソッドも持ちます。

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 からコードを生成するステップがすでにあると仮定します。そのため、その後に必要なメソッドを挿入するステップを追加することができます。

モンキーパッチは(エレガントではない)オプションです。

たとえば、Flex 3 SpriteAsset.as が (flex 2 とは異なり) デフォルトの境界メトリック [7,7,7,7] を返すという事実が気に入らないとします。これを修正するには、次のことができます。

  1. SpriteAsset.as のコピーを作成し、/mx/core/SpriteAsset.as にあるプロジェクトに追加します。
  2. ローカル コピーを編集して、見つかった問題を修正します
  3. アプリを実行する

グーグル "フレックスモンキーパッチ詳しい例と手順については、「」を参照してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top