Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Actionscript 3 获取/设置方法和AS3中的封装_Actionscript 3_Get_Encapsulation_Getter - Fatal编程技术网

Actionscript 3 获取/设置方法和AS3中的封装

Actionscript 3 获取/设置方法和AS3中的封装,actionscript-3,get,encapsulation,getter,Actionscript 3,Get,Encapsulation,Getter,我经常看到以下描述为实现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;

我经常看到以下描述为实现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总是返回对对象类的引用,当我们使用“get”方法时,我们获得了对privatevar=>封装的引用

即使我们没有set方法,我们也可以修改privar! 那么,将其设置为私有的目的是什么

我找到的唯一解决方案是在get方法中返回“\u someVar”的克隆,但我从未在任何示例中看到过这一点。 所以我想我失去了一些东西

您是从getter返回一个克隆对象,还是仅仅接受中断封装

编辑 我了解set和get方法的工作原理,也了解它们的好处。 当我们使用getter byreference返回私有var时,我要求中断私有var中的“private”访问(如果我们的var是Number、String、int等类型,因为3总是通过值而不是引用返回,所以这里没有问题)。 可能不是封装被破坏了,因为没有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方法。

您可以从它所属的类内修改私有变量,但不能从该类外修改它

拥有getter和setter方法可以让您(作为开发人员)在类上拥有更多的能力

您的应用程序将会增长,在某个时候,您可能希望您的类能够在检索或设置某个值之前使用该值执行某些操作。您可能还希望您的类能够在每次设置值时调用方法。诸如此类的事情,当您使用getter/setter方法时,您可以很容易地实现


此外,正如1978年的Dark所说,如果不使用其中一个方法,可能会使变量成为只读或写变量,这对封装有巨大的好处。

如果我需要知道该变量是否已被修改以更改其他内容,我经常使用getter和setter

例如,如果我有:

public var prop : Number;
private var prop2 : Number;
我希望prop2在任何时候=prop+10,我不知道何时更新prop2,但我可以这样做:

private var _prop : Number;
private var _prop2 : Number;

public function set prop(newValue : Number):void {
  _prop = newValue;
  _prop2 = prop + 10;
}
private var _someArray = [true,false];

function get someArray():Array{
    return _someArray.slice(); // Returns a clone of the original array.
}

使用get/set函数时,您控制对成员变量的访问。例如,如果希望变量从外部为“只读”,但从类实例内部可编辑,则可以创建一个get函数,以便可以从外部读取该变量,但不创建set函数。这与使用私有常量不同,因为它必须立即声明,并且不能从任何地方更改

类似地,使用这些函数可以创建设置属性的副作用。例如:

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 _prop : Number;
private var _prop2 : Number;

public function set prop(newValue : Number):void {
  _prop = newValue;
  _prop2 = prop + 10;
}
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); 
}

最后一个很有趣,因为你不需要向世界展示你正在使用某个对象来完成工作。。。你只是在宣传你自己可以做到这一点。

上面的代码与简单地编写以下代码完全相同:

public var someVar:SomeClass;
但是,如果希望使此变量只读仅写,则应分别为私有变量提供公共getter或公共setter

此外,setter和getter函数允许您管理传递的参数、触发事件等。例如,假设您有一个变量
mySmallNumber:Number
,该变量只接受小于10的值:

private var mySmallNumberProperty:Number;

public function set mySmallNumber(value:Number):void
     {
     if     (value < 10)
            mySmallNumberProperty = value;
            else
            throw new ArgumentError("mySmallNumber must be less than 10");
     }

public function get mySmallNumber():Number
     {
     return mySmallNumberProperty;
     }
private var mySmallNumberProperty:Number;
公共函数集mySmallNumber(值:Number):void
{
如果(值<10)
mySmallNumberProperty=值;
其他的
抛出新ArgumentError(“mySmallNumber必须小于10”);
}
公共函数get mySmallNumber():Number
{
返回mySmallNumberProperty;
}
  • 请不要因为我不遵守下划线前缀的用法而责骂我。这是风格的问题。虽然它是“标准”的,但我也认为它超级丑陋

如果要进行封装,则不应提供对复杂对象的直接访问(通过ref传递)。您应该看看您希望其他类能够对您的“SomeClass”做些什么。如果您确实需要传递整个类,并且不希望它是ref,那么添加一个clone方法。如果您只是希望其他类更新属于“SomeClass”的某些数据,那么将为该数据提供setter,并将其直接应用于“SomeClass”实例。它确实需要更多的代码,但将实现封装类的目标。

封装并不会阻止类在private属性上具有引用。它是关于控制其他类可以访问哪些属性。它认为OP并没有真正得到什么,不仅仅是控制其他类可以访问哪些属性。它还涉及控制访问属性的方式。这不是真的,如果我没有setter,只有getter,我可以修改(而不是设置)私有变量,因为我的getter返回的是对该私有成员的引用,而不是副本!所以,我在没有控制的情况下,从类外更改私有变量。也许这个词不是“封装”,但是我们绕过了访问限制。@恩里克:是的,你是对的,C语言、C++、java等都是一样的。你不能做的就是用吸气剂创建一个新的对象,你需要设置它。