« Enumerated Types in ActionScript Happy Birthday... to me! »

March 15, 2004

Something you may not know...

The private keyword is meant to keep users of your class from accessing the class internals. Trying to access private variables and methods in an instance will result in compilation failure. By now we should all know that that "private" is actually "protected", that private visibility is only checked at compile-time, and that there are ways to bypass the compiler's visibility checking since the keyword has no affect at run-time.

So private data really isn't private, and you have it engrained in your head that anytime you mark something as private you can no longer access it through an instance unless you trick the compiler. As it turns out.. compiler trickery is not always necessary.

What I'm about to show you is generally regarded as well known to those with experience in C++, Java, etc. It's not something that jumps out as obvious to those without a programming background, and it doesn't seem to be documented anywhere in Macromedia's documentation (private, controlling member access). Without further ado, here's a simple demonstration class.

class com.darronschall.weblog.PrivateAccessDemo {
 	private var n:Number;
 	private var creation_date:Date;
 	
 	public function PrivateAccessDemo(n:Number, d:Date) {
  		this.n = n;
  		this.creation_date = d;
  	}
 	
 	/**
 	 * Returns true if the current instance has the same internal
 	 * data as the instance passed in.  Note that n and creation_date
 	 * are both private, but because we're inside the PrivateAccessDemo
 	 * class file, we're able to access p's internal data.
 	 */
 	public function equals(p:PrivateAccessDemo) {
  		return (this.n == p.n && this.creation_date.toString() == p.creation_date.toString());
  	}
}

Usage is simple in a .fla file:

import com.darronschall.weblog.PrivateAccessDemo;

var p1:PrivateAccessDemo = new PrivateAccessDemo(3, new Date(2004, 2, 15));
var p2:PrivateAccessDemo = new PrivateAccessDemo(7, new Date());
var p3:PrivateAccessDemo = new PrivateAccessDemo(3, new Date(2004, 2, 15));

trace(p1.equals(p2)); // false
trace(p1.equals(p3)); // true
trace(p2.equals(p3)); // false

All the above code does is create 3 instances of my PrivateAccessDemo class, and compare some of them to each other. I've defined one class being equal to another as "each instance needs to have the same date and number value internally." The only way we can check this is by accessing the private variables directly in the instance passed into the equals method.

Normally, when you try to access a private variable or method of an instance, you get a compile error. In this case, we don't. So what happened?

It's simple really. Because we're inside of the PrivateAccessDemo.as class file, the compiler knows that we're the creator of that class. As such, it allows us access to any of the private data in a PrivateAccessDemo instance simply because it assumes that we know what we're doing (we're the creators of the data type, after all).

While this is obvious to a lot of you out there, I'm sure there are some who haven't even given this subject any thought. Because of that, I wanted to just demonstrate an exception to the rule when it comes to accessing private data and generating compile errors. Anytime you pass in an instance of the class who's .as file you're currently working in, you have free reign to access that instance's private data.

Have fun!

Comments