Можно ли добавить поведение в динамический класс ActionScript 3 без наследования этого класса? - PullRequest
5 голосов
/ 10 августа 2008

Я хотел бы сделать что-то вроде следующего:

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

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

То есть я хотел бы расширить сгенерированный класс одним методом, не с помощью наследования, а с помощью прототипа.

Класс генерируется из WSDL, это не динамический класс, и я не хочу касаться сгенерированного кода, потому что он все равно будет перезаписан.

Короче говоря, я хотел бы иметь моральный эквивалент методов расширения C # 3: s для AS3.

Редактировать: я принял ответ aib, потому что он соответствует тому, что я спрашивал лучше всего - хотя после дальнейшего размышления это не решает мою проблему, но я виноват в том, что задал неправильный вопрос. :) Кроме того, upmods для хороших предложений.

Ответы [ 5 ]

3 голосов
/ 14 августа 2008

@ Тео: Как бы вы объяснили следующую работу в 3.0.0.477 со стандартным flex-config.xml ( true ) и даже с параметром -compiler.strict, переданным в 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"]());
        }
    }
}

Обратите внимание, что OP сказал, что наследование недопустимо, так как изменял сгенерированный код. (Если бы это было не так, добавление «динамического» к определению класса, вероятно, было бы самым простым решением.)

3 голосов
/ 12 августа 2008

Да, такая вещь возможна.

На самом деле, ваш пример очень близок к решению.

Попробуйте

foo["method"]();

вместо

foo.method();
2 голосов
/ 14 августа 2008

В зависимости от того, сколько методов у вашего класса, это может работать:

Фактический класс:

public class SampleClass
{
    public function SampleClass()
    {
    }

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

Quick 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();
1 голос
/ 18 сентября 2008

Исправление обезьян является (не элегантным) вариантом.

Например, предположим, вам не нравится тот факт, что Flex 3 SpriteAsset.as возвращает метрики границы по умолчанию [7,7,7,7] (в отличие от flex 2). Чтобы это исправить, вы можете:

  1. Создайте копию SpriteAsset.as и добавьте ее в свой проект по адресу /mx/core/SpriteAsset.as
  2. Отредактируйте локальную копию, чтобы исправить любые проблемы, которые вы найдете
  3. Запусти свой ап

Google " flex monkey patch " для дополнительных примеров и инструкций.

1 голос
/ 13 августа 2008

@ aib, к сожалению, неверно. Предполагая строгий режим (режим компилятора по умолчанию), невозможно изменить прототип нединамических типов классов в ActionScript 3. Я даже не уверен, что это возможно в нестрогом режиме.

Является ли обертывание опцией? По сути, вы создаете класс, который принимает один из объектов, которые вы получаете от веб-службы, и просто перенаправляет все вызовы методов на него, но также имеет свои собственные методы:

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, так что вы можете добавить шаг после этого, который вставит необходимые вам методы.

...