Можно ли добавить поведение к нединамическому классу 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: s для AS3.

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

Это было полезно?

Решение

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

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

Попробуй

foo["method"]();

вместо того, чтобы

foo.method();

Другие советы

@Theo:Как бы вы объяснили следующую работу в версии 3.0.0.477 с параметром по умолчанию flex-config.xml (<strict>true</strict>) и даже с параметром -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 наследование было неприемлемо, как и изменение сгенерированного кода.(Если бы это было не так, добавление "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.Я даже не уверен, что это возможно в нестрогом режиме.

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

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 возвращает граничные показатели по умолчанию [7,7,7,7] (в отличие от flex 2).Чтобы исправить это, вы можете:

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

Google "гибкий обезьяний пластырь" для получения дополнительных примеров и инструкций.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top