È possibile aggiungere un comportamento a una classe ActionScript 3 non dinamica senza ereditare la classe?

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

Domanda

Quello che mi piacerebbe fare è qualcosa di simile al seguente:

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

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

Vale a dire, mi piacerebbe estendere una classe generata con un unico metodo, non tramite ereditarietà ma tramite il prototipo.

La classe è generata da un WSDL, non è una classe dinamica, e non voglio toccare il codice generato perché verrà comunque sovrascritto.

Per farla breve, mi piacerebbe avere l'equivalente morale dei metodi di estensione C# 3:s per AS3.

Modificare:Ho accettato la risposta di Aib, perché si adatta meglio a ciò che chiedevo, anche se dopo un'ulteriore riflessione non risolve realmente il mio problema, ma è colpa mia se ho posto la domanda sbagliata.:) Inoltre, aggiornamenti per i buoni suggerimenti.

È stato utile?

Soluzione

Sì, una cosa del genere è possibile.

In effetti, il tuo esempio è molto vicino alla soluzione.

Tentativo

foo["method"]();

invece di

foo.method();

Altri suggerimenti

@Teo:Come spiegheresti il ​​seguente funzionamento in 3.0.0.477 con il file flex-config.xml predefinito (<strict>true</strict>) e persino un parametro -compiler.strict passato a mxmlc?

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

Si noti che l'OP ha affermato che l'ereditarietà era inaccettabile, così come la modifica del codice generato.(Se così non fosse, aggiungere "dinamico" alla definizione della classe sarebbe probabilmente la soluzione più semplice.)

A seconda di quanti metodi ha la tua classe, questo potrebbe funzionare:

Classe effettiva:

public class SampleClass
{
    public function SampleClass()
    {
    }

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

Avvolgitore rapido:

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 purtroppo non è corretto.Supponendo la modalità rigorosa (la modalità predefinita del compilatore) non è possibile modificare il prototipo dei tipi di classe non dinamici in ActionScript 3.Non sono nemmeno sicuro che sia possibile in modalità non rigorosa.

Il confezionamento è un'opzione?Fondamentalmente crei una classe che prende uno degli oggetti che ottieni dal servizio web e gli inoltra semplicemente tutte le chiamate ai metodi, ma ha anche metodi propri:

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

}

Quando vuoi lavorare con a Foo, ma hai anche il metodo extra di cui hai bisogno per avvolgere il file Foo istanza in a FooWrapper e lavorare invece con quell'oggetto.

Non è la soluzione più comoda, c'è molta digitazione e se il codice generato cambia bisogna cambiare il file FooWrapper class a mano, ma a meno che tu non possa modificare il codice generato per includere il metodo che desideri o per rendere dinamica la classe, non vedo come sia possibile farlo.

Un'altra soluzione è aggiungere un passaggio al processo di compilazione che modifica l'origine delle classi generate.Presumo che tu abbia già un passaggio che genera il codice da un WSDL, quindi quello che potresti fare è aggiungere un passaggio successivo che inserisca i metodi necessari.

Il patching delle scimmie è un'opzione (poco elegante).

Ad esempio, supponiamo che non ti piaccia il fatto che Flex 3 SpriteAsset.as restituisca una metrica del bordo predefinita di [7,7,7,7] (a differenza di flex 2).Per risolvere questo problema, puoi:

  1. Crea una copia di SpriteAsset.as e aggiungila al tuo progetto su /mx/core/SpriteAsset.as
  2. Modifica la tua copia locale per risolvere eventuali problemi riscontrati
  3. Esegui il tuo ap

Google "toppa flessibile con scimmia" per ulteriori esempi e istruzioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top