我经常看到以下描述为实现 get/set 方法的“正确”方式:
public class Foo {
private var _someVar:SomeClass;
public function get someVar():SomeClass {
return _someVar;
}
public function set someVar(newValue:SomeClass):void {
_someVar = newValue;
}
}
现在,因为 AS3 总是返回对 Object 类的引用,所以当我们使用“get”方法时,我们获得了对 的引用。私有(private) var => 封装被破坏。
即使我们没有 set 方法,我们也可以修改 privar var !
那么将其设置为私有(private)的目的是什么?
我发现的唯一解决方案是在我们的 get 方法中返回“_someVar”的克隆,但我从未在任何示例中看到过这种情况。
所以我想我在这里失去了一些东西。
你是从你的 setter/getter 返回一个克隆对象,还是你只是接受封装中断?
编辑
我了解 set 和 get 方法的工作原理,也了解它们的好处。
当我们用 的 setter/getter 返回它时,我要求在我们的私有(private) var 中中断“私有(private)”访问。引用 (如果我们的 var 是 Number、String、int 等类型,AS3 总是按值返回,而不是引用,所以我们在这里没有问题)。
也许不是封装被破坏了,因为没有setter方法我们无法设置属性。但是我们可以修改它!
看这个例子:
public class Foo {
private var _someVar:Array; // note that this is a Object (not Number, String, etc)
public function Foo(){
_someVar = ['don't touch this!'];
}
public function get someVar():SomeClass {
return _someVar;
}
// note that we don't have a setter
}
var f:Foo = new Foo();
var a:Array = f.someVar;
trace(a[0]); // 'don't touch this!'
a[0] = 'why not?';
trace(f.someVar[0]); // 'why not'
因此,即使我们没有 setter 方法,我们也在不受控制地从外部更改我们的私有(private) var。
最佳答案
当您使用 get/set 函数时,您正在控制对成员变量的访问。例如,如果您希望变量从外部“只读”,但可以在类实例中编辑,您可以创建一个 get 函数,以便可以从外部读取它,但不要创建 set 函数。这与使用私有(private) const 不同,因为它必须立即声明并且永远不能从任何地方更改。
同样,使用这些函数可以让您创 build 置属性的副作用。例如:
public function set foo(value:*):void{
_foo = value;
this.dispatchEvent(new Event("fooSet"));
// setting foo alerts interested parties
// that the value of foo has changed
// without them having to poll foo.
}
编辑:因为您已将问题更新为更具体,所以这是我自己的更新。
你通常不会那样做。如果您试图保护变量本身,那么您将不会直接提供对它的访问。这样做违反了“得墨忒耳法则”。对于您使用数组的特定示例,您可能会执行以下操作:
private var _someArray = [true,false];
function get someArray():Array{
return _someArray.slice(); // Returns a clone of the original array.
}
作为一个不同的例子,使用一个理论上的复杂对象......
private var _someObject:SomeObject;
function get someObject():SomeObject{
return _someObject; // "Wrong." It breaks the law of demeter.
}
////// instead, you would do this.....
function get getSomeObjectsInt():int{
return _someObject.foo; // where .foo is an int
}
////// or this....
function doStuffWithFooObject():Boolean{
return _someObject.doSomething(); // where doSomething returns a boolean;
}
///// or this.....
function performActionOnData(pData:String):String{
return _someObject.someActionWithString(pData);
}
最后一个很有趣,因为您不需要向世界展示您正在使用 SomeObject 来完成工作……您只是在宣传您自己可以做到。
关于actionscript-3 - AS3 中的 get/set 方法和封装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6388325/