Flex and Java Differences: Getters & Setters

In Java it has become a standard practice to use a getter & setter notation to provide a consistent interface to an object’s properties. There is a reason why we don’t do the following in Java:

public String fullName;

The code above essentially creates an interface (or contract) between the class and the implementors of this class that does not allow us to change the underlying implementation of what gets returned when the fullName property is accessed on an instance of the class. So if someone has Java code that accesses the fullName property:

blah = obj.fullName;

Or sets the fullName property:

obj.fullName = "blah";

Then in Java there is no way to change the behavior of getting or setting the fullName property. If the author of the class wanted to change the underlying behavior of the getting or setting they would have to change how the implementors of the class interact with the class. That is obviously not ideal so in Java we typically hide properties with get and set functions. The Java language doesn’t yet have Java properties so we use methods to hide the implementation. So our Java class instead would be:

private String fullName;
 
public String getFullName() {
    return fullName;
}
 
public void setFullName(String fullName) {
    this.fullName = fullName;
}

This allows the class author to change the behavior of getting and setting the fullName property without changing the external interface.

In Flex it is not usually necessary to create the wrapper getter and setting functions on an object because ActionScript supports properties. This means that you can usually just create public properties like:

public var fullName:String;

If the internal implementation of getting or setting the fullName property needs to change, then the class can be adapted to have getter and setter functions without changing the external interface of the class:

private var _fullName:String;
 
public function get fullName():String {
    return _fullName;
}
 
public function set fullName(_fullName:String):void {
    this._fullName = _fullName;
}

To the class implementor the property fullName could still be get and set through the normal notations:

// getters
blah = obj.fullName;
blah = obj['fullName'];
// setters
obj.fullName = "blah";
obj['fullName'] = "blah";

Getting or setting the property would call the getter and setter functions instead of accessing the property directly. This allows the interface of the object to stay the same even if the underlying implementation of getting and setting the property changes. This also allows a class to dispatch events when properties change (this is how Data Binding works internally in Flex).

I see a lot of Java developers who are wary of public properties on ActionScript classes. Don’t be! ActionScript supports real properties so you shouldn’t ever need property getters and setters unless you are doing something out of the ordinary. And you can switch to getters and setters without changing the interface to the object.

If you would like to learn more about the differences between ActionScript and Java check out my AS34J: ActionScript 3 for Java Developers eSeminar next week!

UPDATE: Watch the recording of my eSeminar presentation.

Query the Loaded Classes in Flex / AS3

One of the things I love most about programming is running into walls and then finding creative ways to get over (or through) them. The most recent wall I ran into with Flex was that I wanted to be able to find classes at runtime that either implement a given interface or have specific metadata on them. Flash Player doesn’t provide an API to do this directly so I went searching for a workaround. Christophe Herreman tipped me off to a few great utilities for doing this:

A Flex application (using the Flex framework or AS3 only) can use getDefinitionNames to query any loaded SWF file (Application, Module, etc) for its class definitions. The getDefinitionNames utility just parses through the loaded bytecode and finds the class definitions. Then the as3-commons-reflect library can help determine which of those classes implement a given interface or have specific metadata on them. Here is an example:

(source code)

Here is how it works:

    var a:Array = getDefinitionNames(systemManager.loaderInfo);
 
    allClasses.dataProvider = a;
 
    ifooClasses.dataProvider = new ArrayCollection();
    metafooClasses.dataProvider = new ArrayCollection();
 
    for each (var cn:String in a)
    {
      var t:Type = Type.forName(cn);
      for each (var md:MetaData in t.metaData)
      {
        if (md.name == "MetaFoo")
        {
          metafooClasses.dataProvider.addItem(cn);
          break;
        }
      }
 
      if (ClassUtils.getImplementedInterfaceNames(t.clazz).indexOf("IFoo") >= 0)
      {
        ifooClasses.dataProvider.addItem(cn);
      }
    }

Pretty cool! There are a number of fun uses for this kind of thing… Modular IOC containers, client-side plugins, etc.

Getting over this wall was pretty easy thanks to Denis and Christophe. The Flex / AS3 community rocks!