user3240131
user3240131

Reputation: 207

In actionscript 3, what is the difference between using get and set for a variable and just making it public?

My question is specific to as3. When I use this language, it seems to me that any variable with a getter and setter should be made public instead. Whether you do this :

public class Test
{
    private var _foo:String;

    public function Test() 
    {
        foo = "";
    }

    public function get foo():String 
    {
        return _foo;
    }

    public function set foo(value:String):void 
    {
        _foo = value;
    }
}

or this :

public class Test
{
    public var foo:String;

    public function Test() 
    {
        foo = "";
    }
}

you will end up doing this eventually (to get or set your foo variable from another class) :

testObject.foo

And using a public variable looks much cleaner to me. I know that I am missing something. Could you please show me what it is?

Upvotes: 1

Views: 267

Answers (2)

Marty
Marty

Reputation: 39456

Before we continue, understand that when you define getters and setters, they don't actually need to be associated with a property defined within the class. Getters simply have to return a value, and setters have to accept a value (but can do absolutely nothing if you wish).

Now to answer the question:

The most simple reason is that you can make properties read or write only, by declaring one without the other. In regards to read only, take a moment to consider the benefits of having a class expose a value without other parts of your application being able to modify it. As an example:

public class Person
{
    public var firstName:String = "Marty";
    public var lastName:String = "Wallace";

    public function get fullName():String
    {
        return firstName + " " + lastName;
    }
}

Notice that the property fullName is the result of firstName and lastName. This gives a consistent, accurate value that you would expect if firstName or lastName were to be modified:

person.firstName = "Daniel";
trace(person.fullName); // Daniel Wallace

If fullName was actually a public variable alongside the other two, you would end up with unexpected results like:

person.fullName = "Daniel Wallace";
trace(person.firstName); // Marty - Wait, what?

With that out of the way, notice that getters and setters are functions. Realize that a function can contain more than one line of code. This means that your getters and setters can actually do a lot of things on top of simply getting and setting a value - like validation, updating other values, etc. For example:

public class Slideshow
{
    private var _currentSlide:int = 0;
    private var _slides:Vector.<Sprite> = new <Sprite>[];

    public function set currentSlide(value:int):void
    {
        _currentSlide = value;

        if(_currentSlide < 0) _currentSlide = _slides.length - 1;
        if(_currentSlide >= _slides.length) _currentSlide = 0;

        var slide:Sprite = _slides[_currentSlide];

        // Do something with the new slide, like transition to it.
        //
    }

    public function get currentSlide():int
    {
        return _currentSlide;
    }
}

Now we can transition between slides in the slideshow with a simple:

slideshow.currentSlide = 4;

And even continuously loop the slideshow with consistent use of:

slideshow.currentSlide ++;

Upvotes: 7

gabriel
gabriel

Reputation: 2359

There are actually many good reasons to consider using accessors rather than directly exposing fields of a class - beyond just the argument of encapsulation and making future changes easier.

Here are some of the reasons:

  • Encapsulation of behavior associated with getting or setting the property this allows additional functionality (like validation) to be added more easily later.
  • Hiding the internal representation of the property while exposing a property using an alternative representation.
  • Insulating your public interface from change allowing the public interface to remain constant while the implementation changes without affecting existing consumers.
  • Controlling the lifetime and memory management (disposal) semantics of the property particularly important in non-managed memory environments (like C++ or Objective-C).
  • Providing a debugging interception point for when a property changes at runtime - debugging when and where a property changed to a particular value can be quite difficult without this in some languages.
  • Improved interoperability with libraries that are designed to operate against property getter/settersMocking, Serialization, and WPF come to mind.
  • Allowing inheritors to change the semantics of how the property behaves and is exposed by overriding the getter/setter methods.
  • Allowing the getter/setter to be passed around as lambda expressions rather than values.
  • Getters and setters can allow different access levels for example the get may be public, but the set could be protected.

Upvotes: 0

Related Questions