0

定义 AS3 类时,您可以使用隐式 getter 和 setter 调用函数以进行简单的属性获取/设置操作。例如,我可以像这样创建一个温度类:

public var celsius:Number;

public function get fahrenheit():Number {
    return 9/5 * celsius + 32;
}

public function set fahrenheit(fahrenheit:Number):void {
    celsius = 5/9 * (fahrenheit - 32);
}

然后,我可以像任何其他属性一样获取/设置华氏温度:

temperature.fahrenheit = 69.2;

这真的很有用,但据我所知,它只适用于类定义中声明的属性。但是,我发现能够在动态创建的属性上定义 getter 和 setter 非常有用。像这样的东西:

var obj:Object = new Object();
obj._foo = "bar";
obj.foo = function get () { return this._foo; };
obj.foo = function set (foo:String) { this._foo = foo; };

不幸的是,这样的语法不存在,所以我的问题是:是否可以在 AS3 中动态创建属性 getter 和 setter?

4

3 回答 3

7

就像一个练习一样,还有另一种方法可以完成类似的事情——尽管不是直接等效的——还有一个“间接”。考虑以下代码

class DynamicProperty {

    private var _getter:Function, _setter:Function;
    private var _source:*, _prop:String;

    public function DynamicProperty(source:*, prop:String, getter:Function, setter:Function):void {
        _getter = getter;
        _setter = setter;
        _source = source;
        _prop = prop;
    }

    public function get value():* {
        return _getter(_source[_prop]);
    }

    public function set value(val:*):void {
        _source[_prop] = _setter(val);
    }
}

这个小类接受一个实例、一个属性的名称,然后是两个函数(一个 getter 和一个 setter)。它只提供一个名为“value”的公共属性。公共 getter 和 setter 由传入的函数支持。

然后要使用它们,您可以执行以下操作:

       var data:Object = {
           celsius: 0
       };

       data.kelvin = new DynamicProperty(data,"celsius", 
           function(v:Number):Number { return v + 273.15; }, 
           function(v:Number):Number { return v - 273.15; });

然后访问kelvin,你会使用:

data.kelvin.value

data.kelvin.value = 0; // absolute zero

现在,我并不是建议它是一种很好的方法,但它是我能想到的在语言限制范围内最接近的方法。可以进行一些明显的改进,即将传入的 getter 和 setter 抽象为静态方法以供重用。另一件可能受益的事情是,由于 ActionScript 不支持用户泛型,因此创建特定类来强类型化value.

于 2012-12-23T17:12:33.260 回答
2

您可以查看 Proxy 类 (http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Proxy.html) 来实现这一点。当然,这样的 getter 和 setter 没有智能感知。此外,您需要扩展 Proxy 类,因此任何其他适合该设计的继承都无法使用此类。

于 2012-12-24T21:01:29.003 回答
1

不幸的是,这是不可能的。仅使用自定义的旧式设置器和获取器,例如setFahrenheit(value:int)getFahrenheit():int

于 2012-12-23T09:51:17.210 回答