Est-il possible d'ajouter un comportement à une classe ActionScript 3 non dynamique sans hériter de la classe ?

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

Question

Ce que j'aimerais faire, c'est quelque chose comme ce qui suit :

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

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

C'est-à-dire que j'aimerais étendre une classe générée avec une seule méthode, non pas via l'héritage mais via le prototype.

La classe est générée à partir d'un WSDL, ce n'est pas une classe dynamique, et je ne veux pas toucher au code généré car il sera de toute façon écrasé.

Pour faire court, j'aimerais avoir l'équivalent moral des méthodes d'extension C# 3:s pour AS3.

Modifier:J'ai accepté la réponse d'aib, car elle correspond le mieux à ce que je demandais - même si après réflexion, cela ne résout pas vraiment mon problème, mais c'est de ma faute si j'ai posé la mauvaise question.:) Aussi, upmods pour les bonnes suggestions.

Était-ce utile?

La solution

Oui, une telle chose est possible.

En fait, votre exemple est très proche de la solution.

Essayer

foo["method"]();

au lieu de

foo.method();

Autres conseils

@Théo :Comment expliqueriez-vous ce qui suit en travaillant dans la version 3.0.0.477 avec le fichier flex-config.xml par défaut (<strict>true</strict>) et même un paramètre -compiler.strict passé à 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"]());
        }
    }
}

Notez que l'OP a déclaré que l'héritage était inacceptable, tout comme la modification du code généré.(Si ce n'était pas le cas, ajouter « dynamique » à la définition de classe serait probablement la solution la plus simple.)

Selon le nombre de méthodes dont dispose votre classe, cela peut fonctionner :

Classe réelle :

public class SampleClass
{
    public function SampleClass()
    {
    }

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

Emballage rapide :

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 est malheureusement incorrect.En supposant le mode strict (le mode de compilation par défaut), il n'est pas possible de modifier le prototype des types de classes non dynamiques dans ActionScript 3.Je ne suis même pas sûr que ce soit possible en mode non strict.

L'emballage est-il une option ?Fondamentalement, vous créez une classe qui prend l'un des objets que vous obtenez du service Web et lui transmet simplement tous les appels de méthode, mais qui possède également ses propres méthodes :

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

}

Lorsque vous souhaitez travailler avec un Foo, mais vous disposez également de la méthode supplémentaire dont vous avez besoin pour envelopper le Foo exemple dans un FooWrapper et travaillez plutôt avec cet objet.

Ce n'est pas la solution la plus pratique, il y a beaucoup de saisie et si le code généré change il faut changer le FooWrapper classe à la main, mais à moins que vous ne puissiez modifier le code généré soit pour inclure la méthode souhaitée, soit pour rendre la classe dynamique, je ne vois pas comment cela peut être fait.

Une autre solution consiste à ajouter une étape à votre processus de build qui modifie la source des classes générées.Je suppose que vous disposez déjà d'une étape qui génère le code à partir d'un WSDL, vous pouvez donc ajouter une étape après cela qui insère les méthodes dont vous avez besoin.

Le patching Monkey est une option (peu élégante).

Par exemple, supposons que vous n'aimez pas le fait que Flex 3 SpriteAsset.as renvoie une métrique de bordure par défaut de [7,7,7,7] (contrairement à flex 2).Pour résoudre ce problème, vous pouvez :

  1. Créez une copie de SpriteAsset.as et ajoutez-la à votre projet dans /mx/core/SpriteAsset.as
  2. Modifiez votre copie locale pour résoudre les problèmes que vous rencontrez
  3. Exécutez votre application

Google "patch de singe flexible" pour plus d'exemples et d'instructions.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top