Получить ссылку на метод экземпляра AS3 из объекта класса


class Foo {
   public function bar():void { ... }
}

var clazz:Class = Foo;

// ...enter the function (no Foo literal here)
var fun:Function = clazz["bar"]; // PROBLEM: returns null

// later
fun.call(new Foo(), ...);

Как правильно сделать все вышесказанное? Эквивалент Java того, что я хочу сделать, это:

Method m = Foo.class.getMethod("bar", ...);
m.invoke(new Foo(), ...);

Фактический код (с обходным путем):

class SerClass {

    public var className:String;
    public var name:String;
    private var ser:String = null;
    private var unser:Function = null;

    public function SerClass(clazz:Class):void {

        var type:XML = describeType(clazz);

        className = type.@name;

        // determine name
        name = type.factory.metadata.(@name=="CompactType").arg.(@key=="name").@value;

        // find unserializer
        var mdesc:XML = XML(type.method.metadata.(@name=="Unserialize")).parent();
        if (mdesc is XML) {
            unser = clazz[mdesc.@name];
        }

        // find serializer
        var sdesc:XML = XML(type.factory.method.metadata.(@name=="Serialize")).parent();
        if (sdesc is XML) {
            ser = sdesc.@name;
        }


    }
    public function serialize(obj:Object, ous:ByteArray):void {
        if (ser == null) throw new Error(name + " is not serializable");
        obj[ser](ous);
    }
    public function unserialize(ins:ByteArray):Object {
        if (unser == null) throw new Error(name + " is not unserializable");
        return unser.call(null, ins);
    }
}
4 6

4 ответа:

Здесь панель функций существует только при создании экземпляра класса:

var foo:Foo = new Foo()
var fun:Function = foo.bar // <-- here you can get the function from the new instance

Если вы хотите получить к нему прямой доступ, вы должны сделать его статическим:

class Foo {
 public static function bar():void{ ... }
}

Теперь вы можете получить доступ к своей функции из класса Foo:

var fun:Function = Foo.bar

Или

var clazz:Class = Foo
var fun:Function = clazz["bar"]

Я не уверен в том, что вы собираетесь делать.

Однако AS3Commons , особенно пакет reflect имеют API, которые позволяют работать с методами, экземплярами и свойствами класса.

Существуют также методы API для создания экземпляров определенных типов классов на лету и вызова соответствующих методов.

Ура

Это не

 fun.call(new Foo(), ...);

Используйте вместо этого, так как никакие параметры не требуются для функции

fun.call(clazz);

Первый параметр, указанный в adobe docs.
Объект, задающий значение этого объекта в теле функции.


[EDIT]
Забыл указать, что вы должны создать экземпляр нестатического класса с ключевым словом "new".

var clazz:Class = new Foo();

[EDIT2]
Ладно, я поиграл и думаю, что получил то, что ты хочешь.

Base.as

package{
  public class Base {
    public function Base() {
      trace('Base constructor')
    }
    public function someFunc( ){
      trace('worked');
    }
  }
}



//called with 
var b:Base = new Base( );// note I am not type casting to Class
var func:Function = b.someFunc;
func.call( );

Мой обходной путь состоит в том, чтобы сохранить имя функции вместо объекта Function.

var fun:String = "bar";

// later...
new Foo()[fun](...);