Tutorials, extensions, and source files for ActionScript, Flash, and other Adobe products.

 

Pages: 1 | 2 | 3 | 4 | 5

Object Oriented Programming

Object Oriented Programming (OOP) is an object-based style of programming that uses objects to store and work with data. Templates known as classes are used to define the properties and methods that make up objects in code. OOP focuses on some of the following concepts:

  • Encapsulation
  • Polymorphism
  • Abstraction
  • Inheritance
  • Composition

Encapsulation is the idea that object implementation as defined by its class is hidden from and inaccessible to the user of that class. This basically means, given an object, a user should be able to know how to use that object (using its interface) but not know how the object does what it does. That implementation is buried away and cannot (normally) be changed. This idea facilitates robust, reusable and modular code.

Polymorphism is being able to use more than one kind of object in the same context. Objects capable of being interchanged in this manner have the same interface, or the same collection of properties or methods required to satisfy the context in which they are to be used. Interface definitions - class like definitions that outline what properties and methods exist for a certain type of interface - can be implemented by classes to associate them with a type. Types are defined by class definitions and interface definitions and indicate the kind of object based on its available interface.

Abstraction relates to how a single object can be represented as different types based on context. This relates to polymorphism but instead of having one context for many different objects, you have one object fitting into many other contexts. Consider an apple. It is an apple, a fruit, and food - three different contexts which it satisfies. In programming, you have one object able to be used in different places with different types as long as that object represents that type, either through its own class definition, an inherited definition or an interface definition.

Inheritance describes the process by which one object is based on the definition of another. The original class definition is known as the superclass. The definition based off that class is known as the subclass. Subclasses inherit or extend their superclasses. Interfaces (types) and non-private properties and methods are inherited by subclasses.

Composition is the means by which one object acquires another object's functionality by controlling an instance of that object. This is an alternative to inheritance that, though requires a little more effort, is often more flexible and does a better job enforcing encapsulation. Unlike with inheritance, typing through composition can only be made through interfaces since the composed object's type is not inherited by the object controlling it.

ActionScript 3 relies heavily on OOP, more so than ActionScript 1 or ActionScript 2.  Having a clear understanding of and the ability to use OOP in ActionScript will be paramount in being able to lever ActionScript 3 to its fullest potential.

Classes

Classes are predetermined definitions or templates for object instances.  They describe properties an object contains and what methods are used when working with that object.  When you create new objects in ActionScript, you are creating instances of a class. Most everything in OOP revolves around classes as they define the Objects in Object Oriented Programming..

The Flash player has many native ActionScript classes that are defined internally and always available for use to the Flash developer.  These include classes like Object, Array, Bitmap, MovieClip, Event, etc.  Any class within a package starting with flash is most likely native to the Flash player.

Packages represent collections of classes. Packages not only categorize classes but are also part of a class's definition. The ActionScript 3 Tween class available in Flash CS3, for example, is defined within the fl.transitions package. As a result the Tween class source file (Tween.as) is saved in a folder named transitions which is contained within the folder fl.

ActionScript 3 is class-based by nature. An Array object in ActionScript, for example, has a predefined set of properties and methods associated with it; properties like length, and methods like push() and pop().  These are all predetermined by an Array class which is defined internally by Flash.  Should you want to make your own object definitions, you could make your own class to describe your own custom object.  For example, consider the following object created with ActionScript:

// Triangle object represented in code

var rightTriangle:Object = new Object();

rightTriangle.width = 10;

rightTriangle.height = 20;

rightTriangle.area = function():Number {

	return this.width * this.height/2;

}

This example creates an object called rightTriangle which has two variables assigned to it, width and height, as well as a function called area which determines the area of the right triangle based on the values of width and height. In terms of functionality, this does about everything you need it to as far as basic right triangles go.  But, if you want to make more triangles, it would require duplicating this code for each of those triangle instances. And what if you ever wanted to check to see if a certain variable was assigned to have a triangle value?  In this example, the type of object the rightTriangle is, is Object, not something that specifically indicates it as being a triangle.

A better approach would be to define a right triangle class and create new triangle objects by creating new instances of that class.  The definition for rightTriangle as a class could look something like the following in ActionScript 3:

// Defined in an external ActionScript

// file saved as RightTriangle.as

package {

	public class RightTriangle {

		public var width:Number; 

		public var height:Number;

		public function RightTriangle(width:Number = 0, height:Number = 0){

			this.width = width;

			this.height = height;

		}

		public function area():Number {

			return width*height/2;

		}

	}

}

This definition contains all the same content; width, height, and area; only it's given a slightly different format and it's defined within a separate ActionScript file (a text file with an .as extension). Once Flash recognizes this definition, you can create a new rightTriangle object with the easily with the following code:

// Code used in Flash

var rightTriangle:RightTriangle = new RightTriangle(10, 20);

Here, not only was creating rightTriangle easier, but it also has a unique type associated with it that can be used to check to see if a certain value is in fact of the type (or originating from the class) RightTriangle and use RightTriangle in other typing situations like for variables and parameter lists in functions.

[TODO: do we really want to go this route?]

Breaking down the class we can see what each line represents.

1. package {

This line defines the package block for an ActionScript 3 class. This is a new block that was not present in ActionScript 2. It defines the package path for the class. Since there is no package for this definition of RightTriangle, no path is provided. If the class was defined in the com.senocular.geom package, the line would look like package com.senocular.geom {. In ActionScript 2, the package path would be part of the class name.

2. public class RightTriangle {

Here the class block is being defined. This consists of the class keyword along with the class name. The class name should be the same as the file name of the class file. The public attribute before class indicates that this class is publically accessible to all other scripts. Access attributes in ActionScript 3 include

  • public
  • private
  • protected
  • internal

Public Access: All

If no access attribute is provided, internal is assumed. This is different than ActionScript 2 that used public as the default access operator.

 

ActionScript has supported these classes in some respect all the way back to Flash 5 with ActionScript 1, only with ActionScript 3 are you seeing a more true representation of classes.  And it just isn't a matter of having the option of creating these things called classes.  In ActionScript 3, everything is an instance of a class and all the code you right becomes part of a class definition, even if not written within a separate ActionScript file meant to define a class.

This is important, especially if you are coming from an ActionScript 1 or ActionScript 2 background.  Code written for ActionScript 1 and ActionScript 2 was either timeline based or added to button or movie clip selections. Even when a class was defined in ActionScript 1 or ActionScript 2 it was done so on the timeline – where there was code, there was a timeline.  In ActionScript 3, where there is code, there is a class.

So what does this mean for Flash CS3 and ActionScript 3?  Does all code have to exist as external class files? Can you still write code on the timeline?  What if you don't know, or want to know, anything about classes?

The good news is little has changed in terms of writing code for FLA files in the Flash IDE and you can still write code on the timeline, just as you always have.  The compiler that creates published SWF from your FLA file will be able to handle all the technical issues revolving around this new aspect of ActionScript in the background, much in the same way it handles converting ActionScript 2 classes into ActionScript 1 code in the background without you, the user, really knowing. This means you won't have to know anything about classes nor will you need to mess with external class files if you don't want to when working with ActionScript 3 in Flash.

ActionScript and the Timeline

Timelines in Flash consist of one or more frames that contain graphics associated with visual elements displayed on the screen.  A timeline with multiple frames will run through those frames as a Flash movie is being viewed showing an animation. 

In addition to graphics, timelines can also contain ActionScript (as well as anchors and labels).  More specifically, frames within a timeline can contain ActionScript.  The code placed in each frame of a timeline gets executed when Flash displays that frame on the screen.  With ActionScript 1 and ActionScript 2 Flash was working with a paradigm that depended heavily on the timeline as a foundation for not only animation but also ActionScript.  To make a long story short, this model was limiting.

ActionScript 3 broke away from the timeline and instead isolates ActionScript definitions into separate class definitions that have no dependency on the timeline.  Take the following ActionScript 2 class.

// ActionScript 2 definition in Example.as

class Example {

	public var num:Number;

	private var str:String = "text";

	public function Example(){

		num = 1;

	}

	public function doubleNum():Void {

		num *= 2;

	}

}

A FLA might use this class in frame 1 of the main timeline with the following:

// main timeline of ActionScript 2 FLA

var myExample:Example = new Example();

When compiled and published into a SWF, the SWF gets code that is attached to the timeline and essentially looks like this:

// compiled version

_global.Example = function(){

	this.num = 1;

}

Example.prototype.str = "text";

Example.prototype.doubleNum = function(){

	this.num *= 2;

}

myExample = new Example();

All ActionScript 2 class definitions, when compiled, end up in the main timeline as ActionScript 1 definitions.  And, really, to be more specific, the definitions actually end up in dynamically generated movie clip symbols placed in the library during compile time.  Within these movie clips' timelines, however, the definitions are created within an #initclip/#endinitclip block, which ultimately translates to a main timeline definition.  Either way, the end result is code placed on a timeline which gets run when that frame in the timeline is run.

In ActionScript 3, classes become isolated definitions.  They do not end up in the timeline which requires that the timeline to be executed in order to be defined.  In fact the opposite happens for code placed on the timeline in ActionScript 3.  In that instance, timeline code is ripped out of the timeline and placed in a class definition that is then used to define that timeline instance.  Consider the following ActionScript 3 code placed on the main timeline in Flash.

var num:Number = 10;

function isOdd(num:Number):Boolean {

	return Boolean(num % 2);

}

trace(isOdd(num));

When compiled, this timeline code is removed from the timeline and is instead placed in the class definition used to describe the main timeline.

package {

	public class MainTimeline extends MovieClip {

		public var num:Number;

		public function MainTimeline(){

			super();

			addFrameScript(0, frame1);

		}

		public function isOdd(num:Number):Boolean {

			return Boolean(num % 2);

		}

		public frame1(){

			num = 10;

			trace(isOdd(num));

		}

	}

}

This class is then used when the main timeline is instantiated.  With this in mind, it might be a little easier to see why you cannot define a variable or a function more than once anywhere within the same timeline.  If you did, you would have conflicting definitions in the class that is generated from the code in the timeline.

[TODO: img visual of ActionScript 3 vs ActionScript 2]

Interfaces

Types are not limited by class definitions.  Types can also take the form of interfaces.  Interfaces define what properties and methods are available to a type. 

The term "interface" itself describes the actual collection of accessible (usually public) properties and methods available to an object.  This is the same collection of properties and methods you see when you lookup class definitions in help or an ActionScript language reference.  It's a common term that is used with most all programming.

var myObj:Object = new Object();

myObj.foo = "foo";

myObj.bar = function():String {

	return this.foo;

}

The interface of the above object consists of the property foo, and the method bar.

ActionScript also supports interface definitions.  Interface definitions are class-like definitions (usually starting with a capital "I")  that describe what properties and methods and object has but does not go so far as to provide an implementation for them (which remains the class's job).   When a class implements an interface, it is required to supply the implementation of the properties and methods within the interface(s) being implemented, either explicitly or through inheritance.

The big idea behind having interfaces is to have more type options.  Like classes, interfaces are also types.  A type's purpose, after all, is to describe an object's interface so Flash can recognize when you are using a typed value correctly.  You will get an error when you attempt to access a part of an object's interface that is not described in its type, whether that type is defined by a class type or an interface type.  So why not just use class types?

There are some situations in ActionScript where a certain property can contain more than one kind of instance but requires that each share the same interface (as in properties and methods), even if they are instances of unrelated classes. One example of this is with the BitmapData.draw() method.  The signature or definition for draw() starts off as the following

public function draw(source:IBitmapDrawable, matrix:Matrix = null, …

Notice that the first parameter is typed as IBitmapDrawable.  IBitmapDrawable is an interface that describes objects that can be used with the draw() method.  The classes that implement this interface are BitmapData and DisplayObject so only instances of those classes (or their subclasses) which are of the type IBitmapDrawable can be used in draw().

A better example might be the IEventDispatcher interface. This interface, unlike IBitmapDrawable, actually defines methods associated with the interface itself.  These methods include

  • addEventListener
  • dispatchEvent
  • hasEventListener
  • removeEventListener
  • willTrigger

The EventDispatcher class which implements this interface is required to define and provide an implementation each one of those methods, and it does.  Any other class that also implements the IEventDispatcher interface would also have to do the same.  Currently there are no other native Flash classes that implement IEventDispatcher other than EventDispatcher, though some Flex classes (AbstractService and DataService) do.

The reason EventDispatcher has its own interface is because the functionality of EventDispatcher can be used in classes two ways; one by extending EventDispatcher or a subclass of EventDispatcher (so its methods are inherited) or using an instance of EventDispatcher as a property of a class to funnel event operations through (this is called composition).  If a class is not able to extend EventDispatcher for some reason (for example if it needs to extend Proxy instead) then it would need an EventDispatcher instance to manage events.  In that case, recognizing the class as being the type EventDispatcher would not be possible even though the same functionality is there.  Instead, the class would have to implement IEventDispatcher so values expecting the interface of EventDispatcher can be typed as IEventDispatcher and still work with that class instance.

// any object extending EventDispatcher or

// using EventDispatcher with composition

var dispatcher:IEventDispatcher;

Whenever you require a variable typed as EventDispatcher, you should always use the type IEventDispatcher instead.  This will cover all instances that inherit from EventDispatcher as well as those which use composition to acquire EventDispatcher functionality.

You may also decide to create your own interface definitions that can be used to describe a custom type for custom classes.

Components

Components are pre-built assets available in Flash that allow advanced functionality right "out of the box."  What separates components from other symbols or libraries is that each instance of a component on the screen in Flash is customizable through the Flash interface without the need for ActionScript. 

Components were originally introduced in Flash 5.  Then, they were known simply as smart clips and were limited to simple variable definitions.  Since Flash 5 components have evolved to support other features such as custom interfaces and dynamic previews within the Flash drawing area through live preview.

Different versions of Flash and different versions of ActionScript have different component sets.

[TODO: more on components, creating custom? Where to place in tutorial?]

 

Pages: 1 | 2 | 3 | 4 | 5