Get / set methods and encapsulation in AS3

I often saw the following, described as the “right” way to implement get / set methods:

public class Foo { private var _someVar:SomeClass; public function get someVar():SomeClass { return _someVar; } public function set someVar(newValue:SomeClass):void { _someVar = newValue; } } 

Now, since AS3 always returns references to the Object classes when we use the get method, we get a link to our private encapsulation var =>.

Even if we do not have a set method, we can change varar var! What is the purpose to establish it as personal?

The only solution I found was to return the clone "_someVar" in our get method, but I never saw this in any example. So I think I'm losing something here.

Are you returning a cloning object from your getters or just accepting an encapsulation break?

EDIT I understand how methods work and work, and I understand their advantages. I ask for the "private" access denial in our private var when we return it with a getter by reference (if our var is of type Number, String, int, etc. AS3 always returns by value, not a link, so we have no problem here). Perhaps this is not an encapsulation that is broken because we cannot set a property without the setter method. But we can change it!

See this example:

 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' 

So, we change our private var externally and without control, even if we don't have the setter method.

+4
source share
5 answers

You control access to a member variable when using the get / set functions. For example, if you want the variable to be read-only from the outside, but edited from an instance of the class, you make the get function so that it can be read from the outside, but NOT to create a set function. This is different from using private const, because it must be declared immediately and can never be changed anywhere.

Similarly, using these functions allows you to create side effects to set the property. For instance:

 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. } 

EDIT: because you clarified the question to be more specific, here's an update of my own.

Usually you did not. If you try to protect this variable, you will not offer it directly. This violates the "law of Demeter." For your specific example with an array, you can do something like this:

 private var _someArray = [true,false]; function get someArray():Array{ return _someArray.slice(); // Returns a clone of the original array. } 

As another example, using a theoretical complex object ...

 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); } 

This last one is interesting because you don’t have to tell the world that you are using SomeObject to do this work ... you just advertise that you can do it yourself.

+4
source

You can change a private variable from the class to which it belongs, but you cannot change it from outside this class.

Having getter and setter methods gives you more options (as a developer) over the class.

Your application will grow, and at some point you may want your class to do something with a value before it selects it, or before setting it up. You may also want your class to call a method every time it sets a value. Such things can be easily achieved when you have getter / setter methods.

In addition, as TheDarkIn1978 says, leaving one of the methods, you can make the variable write-only or read-only, which will have a huge advantage for encapsulation.

+1
source

I often use getters and setters if I need to know if this variable has been changed to change other things.

For example, if I:

 public var prop : Number; private var prop2 : Number; 

and I want prop2 to be at any time = prop + 10, I would not know when to update prop2, but I could do something like this:

 private var _prop : Number; private var _prop2 : Number; public function set prop(newValue : Number):void { _prop = newValue; _prop2 = prop + 10; } 
0
source

the above code is exactly the same as just writing:

 public var someVar:SomeClass; 

if you want to make this variable read - only or write - only , you must provide a public getter or public setter for the private variable, respectively.

In addition, setters and getter functions allow you to control the passed parameters, disable events, etc., for example, suppose you have a variable mySmallNumber:Number , which should only take values ​​less than 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; } 
  • please don’t pounce on me for not agreeing to use the underscore prefix. it is a matter of style. while this is the "standard", I also find it super ugly.
0
source

If you intend to encapsulate, you should not provide direct access to complex objects (passed by ref). You should see what you expect from other classes that may be relevant to your "SomeClass". If you really need to pass the whole class and don't want it to be ref, add the clone method. If you just expect other classes to update some data owned by SomeClass, provide customization tools for that data and apply it directly to the SomeClass instance. This requires more code, but it will achieve the goal of encapsulating your class.

0
source

All Articles