Object Orientation

Here’s another post that I originally wrote way back in 2006, when object oriented development was a newer concept to client-side web applications. Again, this post is still very relevant with Flex, AIR & ActionScript for mobile/web/desktop, so I decided to resurrect it from the old blog archive as well. Enjoy…

Understanding of OOP (Object Oriented Programming) is fundamental in being successful with the Flex framework and being able to get the most out of it. Developers who do not possess a computer science-related background may not be aware of the fundamental concepts that comprise OOP and how to apply them correctly, so here is a quick piece to help you out.

First, object oriented programming is a programming paradigm where your code is organized into logical objects, and each object has properties and methods. Each object contains similar and/or related functionality, and is organized into classes that logically represent and logically organize it’s functionality.

For Example:
Let’s say that we have a class “Automobile”. This class would contain the information and functions necessary for our application to use the Automobile class. We could have a numeric property for the number of wheels, the speed, and the direction (degrees on a compass). This class would also contain methods that control the actions of the Automobile object: accelerate, decelerate(break), turn, start engine, stop engine, etc… Our class would look something like this…

[as3]public class Automobile
{
public var speed : Number;
public var direction : Number;
public var numWheels : Number;

public function Automobile()
{ /* constructor */ }

public function accelerate() : void
{ /* speed up the automobile */ }

public function decelerate() : void
{ /* slow down the automobile */ }

public function turn( direction : Number ) : void
{ /* turn the automobile */ }

public function startEngine() : void
{ /* start the automobile engine */ }

public function stopEngine() : void
{ /* stop the automobile engine */ }
}[/as3]

Ok, now that we have a brief explanation of what object oriented programming is, we can get into some more aspects of OOP: inheritance and interfaces.

Inheritance is a way to form new objects based on existing objects. When a class inherits from a base class, the new class extends the functionality of the base class, and can utilize public and protected properties and methods from that base class. Inheritance can be used to create different objects that utilize functions within the base class, so that the child classes all utilize the same code base. Inheritance can be used to extend the functionality of existing objects, and inheritance can also be used to override and/ or change functionality from the base class.

In Actionscript 3, you can access the parent class of your class by using the “super” keyword. For instance, calling the constructor of the parent class would use “super()”, where accessing a method of the parent class would use something like: “super.myMethodName()”. If a property of the parent class is created with public or protected access, you can access that property in the child class directly by the property name (you would use this.propertyName, not super.propertyName).

Now, Lets take our Automobile example and apply object-oriented inheritance. We already have a base Automobile class that covers the basic functionality. We can create child classes that extend the functionality of the Automobile.

[as3]public class SportsCar extends Automobile
{
public function SportsCar()
{
super();
}

override public function accelerate():void
{
/* we can override the accelerate function
so that it accelerates faster than the base
Automobile */
}
}[/as3]

and…

[as3]public class Truck extends Automobile
{
public function Truck()
{
super();
}

public function tow() : void
{
/* we can add a tow function that
allows the Automobile class to tow
items. */
}
}[/as3]

These classes extend the base functionality of the Automobile class, and therefore are instances of the Automobile class. If we have a function outside of the Automobile class, which takes an automobile as the parameter, both a SportsCar and Truck will work since they are both Automobiles. We could have a function such as the following: If we pass in a Truck Instance, and a SportsCar instance, both will work, and each will use the functionality of their specific class instead of the base Automobile class.

[as3]public function race( auto1 : Automobile, auto2 : Automobile ) : void
{
auto1.accelerate();
auto2.accelerate();
}[/as3]

I’ll get into some more fine-grain details about inheritance later in this post… now, lets move on to interfaces…

Interfaces are slightly different than inheritance. An interface is a set of “rules” which an object must adhere to. The “rules” are actually method signatures that your class must implement. When we define an interface, we define method signatures that are required for classes that implement that interface. There is no actual code in an interface; it simply defines methods that must exist within your class. Your class that implements the interface must implement the code for the actual function. If you have multiple classes that implement an interface, those classes must have the same functions (only the ones required by the interface), but that is where the similarities of the two classes may stop. They could have completely different logic and properties within them… this is where inheritance and interfaces differ. Two objects that inherit from the same base class have a lot in common (properties and methods): two objects that implement the same interface only have those interface method signatures in common.

Let’s now make an Automobile Interface that defines the functions required to create an IAutomobile object (note the “I” stands for “interface”):

[as3]public interface IAutomobile
{
function accelerate() : void;
function decelerate() : void;
function turn( direction : Number ) : void;
}[/as3]

We can use the IAutomobile interface to create objects (classes) that behave as Automobile objects. These classes do not necessarily inherit from each other and do not necessarily share any common properties.

[as3]public class Car implements IAutomobile
{
private var direction:Number;
private var speed:Number;

public function turn(direction:Number):void
{
this.direction = direction;
}

public function decelerate():void
{
this.speed++;
}

public function accelerate():void
{
this.speed–;
}
}[/as3]

[as3]<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas implements="IAutomobile"
xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[

private var direction:Number;
private var speed:Number;

public function turn(direction:Number):void
{
this.direction = direction;
}

public function decellerate():void
{
this.speed++;
}

public function accellerate():void
{
this.speed–;
}
]]>
</mx:Script>
</mx:Canvas>[/as3]

The previous two components both implement the IAutomobile interface, but have nothing else in common. One is simply a class that implements the interface, the other is a mxml component that implements the interface. The mxml component example extends the mx:Canvas component (the same thing could be done by creating an AS class that extends mx.containers.Canvas). Now, lets look at a function similar to the “race” function from earlier…

[as3]public function race( auto1 : IAutomobile, auto2 : IAutomobile ) : void
{
auto1.accelerate();
auto2.accelerate();
}[/as3]

This example will work with either object that I have created because both objects implement the IAutomobile interface. They do not rely upon functions in the class hierarchy, just those that were implemented for this interface. You can also use multiple interfaces on classes that you create. Implementing multiple interfaces basically means that you are adding more required method signatures to your class, and you will have to implement these methods to satisfy each interface.

On the other hand, you cannot inherit from multiple classes. Some programming languages allow for multiple inheritance… ActionScript 3 does not support multiple inheritance (so i’ll stop there).

OK… enough of this rambling… What does this have to do with Flex?
Inheritance and interfaces are used extensively in AS3 to create the flex framework. All flex framework components that are rendered to the screen extend from the UIComponent class. AbstractService, DataSerice or EventDispatcher object implements the IEventDispatcher Interface. You may be using these concepts every day, but weren’t aware of them. Inheritance seems easier to take advanatage of at first… Lets say that you want to create several objects, all of which will have identical functions and variables. It is easy to see that you can create a base class that encapsulates all of the common functionality. You can then create a sub-classes that implement the differing functionality for each class.

When putting these concepts into real-world Flex applications you’ll need to get familiar with the following keywords:

extends
This is used when defining a child class from a parent class.
[as3]public class MyImage extends Image[/as3]

implements
This is used when implementing an interface.
[as3]public class MyClass implements MyInterface[/as3]

final
Classes and methods implented with “final” cannot be overridden.
[as3]final function myFunction() : void[/as3]

static
The static keyword is used when creating variables or functions in a class that are specific to the class, not an instance. Static properties and methods do not require variable instantiation to be executed.
[as3]public static function myStaticFunction(): void
//to use it call it directly from ClassMyClass.myStaticFunction()[/as3]

internal
This is used when creating a method or property that can be accessed by any object within the same package (namespace)
[as3]internal var foo : String;[/as3]

override
This is used when creating a function that overrides another function from a parent class.
[as3]override public function myFunction() : void[/as3]

private
This is used when creating methods or properties that are only available to the class where it is defined. A private variable cannot be accessed by outside classes or from descendant classes.
[as3]private var myPrivateValue : String;[/as3]

protected
This is used when creating methods or properties that are only available to the class where it is defined and descendant classes. A protected variable cannot be accessed by outside classes.
[as3]protected var myProtectedValue : String;[/as3]

public
This is used when creating properties and methods that are available to any class.
[as3]public var myPublicValue : String;[/as3]