Ist es möglich, Verhalten zu einer nicht dynamischen ActionScript 3-Klasse hinzuzufügen, ohne die Klasse zu erben?

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

Frage

Was ich gerne tun würde, ist etwa Folgendes:

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

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

Das heißt, ich möchte eine generierte Klasse mit einer einzigen Methode erweitern, nicht über Vererbung, sondern über den Prototyp.

Die Klasse wird aus einer WSDL generiert, es ist keine dynamische Klasse und ich möchte den generierten Code nicht anfassen, da er sowieso überschrieben wird.

Um es kurz zu machen: Ich hätte gerne das moralische Äquivalent der Erweiterungsmethoden von C# 3 für AS3.

Bearbeiten:Ich habe die Antwort von aib akzeptiert, weil sie am besten zu dem passt, was ich gefragt habe – auch wenn sie bei näherem Nachdenken mein Problem nicht wirklich löst, aber das ist meine Schuld, weil ich die falsche Frage gestellt habe.:) Außerdem Upmods für die guten Vorschläge.

War es hilfreich?

Lösung

Ja, so etwas ist möglich.

Tatsächlich kommt Ihr Beispiel der Lösung sehr nahe.

Versuchen

foo["method"]();

anstatt

foo.method();

Andere Tipps

@Das Ö:Wie würden Sie die folgende Arbeit in 3.0.0.477 mit der Standardeinstellung „flex-config.xml“ (<strict>true</strict>) und sogar einem an mxmlc übergebenen Parameter „-compiler.strict“ erklären?

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"]());
        }
    }
}

Beachten Sie, dass das OP sagte, die Vererbung sei inakzeptabel, ebenso wie die Änderung des generierten Codes.(Wenn das nicht der Fall wäre, wäre das Hinzufügen von „dynamic“ zur Klassendefinition wahrscheinlich die einfachste Lösung.)

Abhängig davon, wie viele Methoden Ihre Klasse hat, könnte dies funktionieren:

Tatsächliche Klasse:

public class SampleClass
{
    public function SampleClass()
    {
    }

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

Schneller Wrapper:

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 ist leider falsch.Unter der Annahme des strikten Modus (dem Standard-Compilermodus) ist es nicht möglich, den Prototyp nicht dynamischer Klassentypen in ActionScript 3 zu ändern.Ich bin mir nicht einmal sicher, ob es im nicht strengen Modus möglich ist.

Ist das Verpacken eine Option?Im Grunde erstellen Sie eine Klasse, die eines der Objekte, die Sie vom Webdienst erhalten, übernimmt und einfach alle Methodenaufrufe an dieses weiterleitet, aber auch über eigene Methoden verfügt:

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!"
    }

}

Wenn Sie mit einem arbeiten möchten Foo, sondern haben auch die zusätzliche Methode, die Sie zum Einwickeln benötigen Foo Beispiel in a FooWrapper und stattdessen mit diesem Objekt arbeiten.

Es ist nicht die bequemste Lösung, da viel Tipparbeit anfällt und wenn sich der generierte Code ändert, müssen Sie ihn ändern FooWrapper Wenn Sie den generierten Code jedoch nicht so ändern können, dass er die gewünschte Methode enthält oder die Klasse dynamisch macht, sehe ich keine Möglichkeit, dies zu bewerkstelligen.

Eine andere Lösung besteht darin, Ihrem Build-Prozess einen Schritt hinzuzufügen, der die Quelle der generierten Klassen ändert.Ich gehe davon aus, dass Sie bereits über einen Schritt verfügen, der den Code aus einer WSDL generiert. Sie könnten also danach einen Schritt hinzufügen, der die von Ihnen benötigten Methoden einfügt.

Monkey Patching ist eine (unelegante) Option.

Angenommen, Ihnen gefällt die Tatsache nicht, dass Flex 3 SpriteAsset.as eine Standardgrenzmetrik von [7,7,7,7] zurückgibt (im Gegensatz zu Flex 2).Um dies zu beheben, können Sie:

  1. Erstellen Sie eine Kopie von SpriteAsset.as und fügen Sie sie Ihrem Projekt unter /mx/core/SpriteAsset.as hinzu
  2. Bearbeiten Sie Ihre lokale Kopie, um alle gefundenen Probleme zu beheben
  3. Führen Sie Ihre App aus

Google "Flex-Affen-Patch" für weitere Beispiele und Anleitungen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top