AS3 101: Quick Tip – Use Access Modifiers Effectively
basix

AS3 101: Quick Tip – Use Access Modifiers Effectively

Tutorial Details
  • Difficulty: Basix
  • Platform: Flash Player 9+
  • Language: AS3
  • Software used: Any AS3 compiler
  • Estimated Completion Time: 5 mins
This entry is part 10 of 18 in the AS3 101 Session
« PreviousNext »

There are four access modifiers you can choose from when declaring properties and methods: private, protected, internal, and public. How do you know which one to use?

Before I answer that question, let’s consider why we’d bother with private (and protected and internal) and not just make everything public? Well, there’s a little thing called encapsulation in Object-Oriented Programming. The idea behind it is the “black box” design of classes. You don’t need to know how the box works for it to do its job. Take a car, for instance. You don’t need to know the first thing about how an engine works for you to sit in the driver’s seat and make the car move. The inner workings of the car are encapsulated, and all you need to be familiar with is what can you do from the outside (such as work the pedals and turn the wheel; who cares how the wheels turn when you hit the gas, just so long as they do?).

In fact, making the engine more public could lead to problems; if someone who doesn’t really know what they’re doing starts messing around, we might have a broken car on our hands. With that in mind, let us consider…


The First Rule

It’s more of a guideline than a rule, but you should make properties and methods as inaccessible as you can. It’s much easier to change your mind later and provide expanded access than it is to go the other direction.

For example, imagine a class that has a “foo()” method. If we start out making foo() public, then any other object can call it. Now, we decide that, for whatever reason, foo() really should only be called under controlled circumstances, so we want to make it private. At the point of changing “public” to “private,” there could be any number of other objects already calling foo(), because it’s public. Once we make the switch, we run the risk of breaking existing code.

On the other hand, suppose there was a “bar()” method that we originally wrote as private, and the only place where we can call bar() is from within the object itself. But we have since decided that bar() is really the heart and soul of this object, and we could really make things wonderful by making it public. As we make the change, we know that the only code that could previously call bar() will still be able to call it after the change.


The Other Rule

This one is probably more steadfast than the first one, but again, there’s no rulebook out there, nor is there an enforcement agency that will bust you should break these “rules.” However, it’s a good idea to always always always make your properties private, or at the most protected. Never make a public property.

Why? In a nutshell, because you don’t want some other bit of code changing the value of your properties without you knowing about it. This isn’t some paranoid, “Big Brother is always watching” approach to programming. But it is about control.

This is not to say that there should never be public access to the value. Instead, it’s to say that we should control public access to the value. Consider: what if your object had a String property that held one of three possible values, and the object behaved slightly differently depending on the state of that property? For instance:

public var state:String;
public function foo():void {
    switch (state) {
        case "A":
            trace("foo - a");
            break;
        case "B":
            trace("foo - b");
            break;
        case "C":
            trace("foo - c");
            break;
    }
}

And in using it:

myObject.state = "A";
myObject.foo() // traces "foo - a";
myObject.state = "B";
myObject.foo() // traces "foo - b";

Now, if you happened to write:

myObject.state = "a";
myObject.foo() // nothing happens!

Then the state is never matched. Sure, you can add a default to the switch statement, and even perform a toUppercase() on the state property when evaluating it, but it would be better to simply validate the value as it’s being set.

Writing a public setter for the property allows you the opportunity to examine the incoming value and react accordingly.

private var _state:String;
public function set state(value:String):void {
    if (value == "A" || value == "B" || value == "C") {
        _state == value;
    } else {
        throw new Error("Invalid value set for state: " + value);
    }
}

Of course, you can handle that however you want, and that’s the beauty of private properties combined with public setters and getters.

And, to tie back to the first rule, it’s a “safe” change to have a private property for which you later add public setters and getters.

See my quick tip on Setters and Getters for more information.

Tags: BasixTips
  • http://active.tutsplus.com/author/konstantin-serov/ Konstantin Serov

    To say the truth, not very informative. Nothing about internal properties or protected. If I was a newbie, I bet I wouldn’t understand anything of this, and of course I wouldn’t understand why I should use, e.g. internal variables or classes

  • Jason

    Great article, but no discussion on protected or internal. That’s why I read the article. Seems this is only half of what needs to be discussed.

  • http://ForTheLoss.org Ralph

    Yeah, what about internal and protected? Those were the two I was most interested in and there was nothing about them.

    Also, I have somewhat of a question, I’m in the process of created an InputManager class (tracks keyboard and mouse actions for my game).

    I have a bunch of public variables in that class for easy referencing later on:
    public var wKeyDown:Boolean = false;
    public var aKeyDown:Boolean = false;
    public var sKeyDown:Boolean = false;
    public var dKeyDown:Boolean = false;

    Then to check if a key is down, all I have to do is:
    if (inputManager.wKeyDown)
    {
    // W key is down
    }

    Is this an exception to the “make every variable private” rule?

  • http://michaeljameswilliams.com/ Michael Williams

    Hey guys, sorry for the confusion on this. The internal and protected namespaces will be covered in the next part of Dru’s AS3:101 — OOP series.

  • http://tuckinteractiv.com Justin Tucker

    I’d like to see a post about using interface in actionscript 3. Pros, cons, general usage. Keep these 101 post coming though, Dru. They definitely clear up some foggy areas for me.

  • pepperpunk

    Sorry, you lost me at the foos and the bars. They looked incredibly weird and I started off thinking that they were some sort of crazy obscure AS functions I’d never seen before. “Property1″ and “Property2″ would have been much easier to follow.

    I read that paragraph quite a few times but I’m still not understanding how it adds to the first sentence.

    Also, If I’m reading this right, the first rule is the same as the other rule?

    rule 1: make properties as inaccessible as you can.
    rule 2: make properties private whenever you can.

    Unless there’s some sort of difference between those two?

    I think a lot of these quick articles would be better served by a single longer article on the subject of OOP theory and technique (with briefer summaries of points like these), that way you can reference stuff within the same article.

    Advanced OOP is something I’d like to learn but I’ve never been able to find a book or site that made any sense to me.. even the highly recommended ‘moock book’ simply has hundreds of pages of unapproachable “wall of text” on the subject (written mostly in programmer jargon) that I find very hard to extract key bits of relevant information from to cache in my 256 bytes of short term memory. :P

    • http://twitter.com/codetonowhere Rich

      foo and bar are pretty standard example variable names that you will come across in most programming books. I appreciate that OOP isn’t the easiest concept to comprehend, but you’re probably going to have to get used to ‘programmer jargon’ if you want to learn it.

    • http://michaeljameswilliams.com/ Michael Williams

      Thanks for mentioning foo and bar. As Rich says, they’re pretty common — it just never occurred to me that they might seem strange and unfamiliar to readers, and I bet Dru felt the same. I’ll have to keep an eye on things like that for the future.

      Re. your point on a longer OOP article: that’s sort of what we’re doing. Check out the base page for AS3:101; there will be a few long posts on OOP, and they’ll refer you to these shorter posts for more details as necessary.

      -Michael (tech editor)

  • http://www.greensock.com Jack Doyle

    One caveat I’d mention is that public properties are much faster to get/set than using functions or getters/setters. If raw performance is critical (in most cases it’s not, but for stuff like tweening engines it is), the 800%+ performance improvement is probably worth the risk you take in terms of someone editing the public property inappropriately.

    • Dru Kepple
      Author

      And you know a thing or two about tweening engines, eh, Jack? (If anyone reading this thinks I’m being mean, Jack is the guy behind Greensock, makers of TweenMax. He really does know a thing or two)

      Yes, absolutely. I agree with the way you put that, too: “If raw performance is critical (in most cases it’s not…” It’s good to know the ins and outs of the various options. My point was, as you may have guessed, all about the encapsulation side of things, and “proper” Object-Oriented technique.

      I definitely had a destination in mind with this article, the previous quick tip on setters and getters, and the second part of the OOP tutorial. I now feel like I’ve done a major disservice by failing to mention when public properties are appropriate.

      Everyone, take note. The next time I write a multipart Object-Oriented Programming tutorial series using ActionScript 3, I’ll make sure to mention both sides of the story!