Using Interfaces with Display List Objects in AS3.0

This is an example illustration of Option 2 from a great post by Mr. Wright.

Project structure:

Create an interface to be implemented by your group of display objects. In this case it’s called IEmployee, since I’ll be using it to call an identically named method on three employees (Developer, Designer, Project Manager):

package com.interfaces
{
	import com.interfaces.ISprite;
	
	public interface IEmployee extends ISprite
	{
		function talk():String;
	}
}

Create an ISprite (or IMovieClip, or IDisplayObjet) interface, since one doesn’t exist in AS3:

package com.interfaces
{
	import flash.display.Sprite;
	
	public interface ISprite
	{
		function get view():Sprite;	
	}
}

Each of the concrete classes below – Developer, Designer, ProjectManager – contains identically named methods “view” & “talk()” which can be called by a user class which doesn’t have to know exactly which class’s instance it’s calling.

Developer class implements IEmployee:

package com.view
{
	import com.interfaces.IEmployee;
	
	import flash.display.Sprite;
	
	public class Developer extends Sprite implements IEmployee
	{
		public function Developer()
		{
			super();
		}
	
		public function get view():Sprite
		{
			return this as Sprite;
		}

		public function talk():String
		{
			return "Code, code, code! Why are the PSD layers not organized? Code, code code!";
		}
	}
}

Designer class also implements IEmployee:

package com.view
{
	import com.interfaces.IEmployee;
	
	import flash.display.Sprite;
	
	public class Designer extends Sprite implements IEmployee
	{
		public function Designer()
		{
			super();
		}
		
		public function get view():Sprite
		{
			return this as Sprite;
		}
		
		public function talk():String
		{
			return "Pantone! CMYK! RGB! What the hell is HEX? Vector Smart Object!";
		}
	}
}

and ProjectManager class implements IEmployee as well:

package com.view
{
	import com.interfaces.IEmployee;
	
	import flash.display.Sprite;
	
	public class ProjectManager extends Sprite implements IEmployee
	{
		public function ProjectManager()
		{
			super();
		}
		
		public function get view():Sprite
		{
			return this as Sprite;
		}
		
		public function talk():String
		{
			return "Meeting! Do you need an LCD spec? Meeting! Can I get an ETA on that? Meeting, meeting.";
		}
	}
}

This is a basic user class, which randomly specifies which employee to use and calls the talk() method on that employee:

package
{
	import com.interfaces.IEmployee;
	import com.view.Designer;
	import com.view.Developer;
	import com.view.ProjectManager;
	
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.utils.getQualifiedClassName;
	
	[SWF (width="964", height="655", backgroundColor="#000000", frameRate="30")]	
	public class DisplayListPolyMorphismByInterface extends Sprite
	{
		private var worker:IEmployee;
		private var employees:Array = [new Developer(), 
                                       new Designer(), 
                                       new ProjectManager()];
		
		public function DisplayListPolyMorphismByInterface()
		{
			initApp();				
		}		
		
		public function initApp():void
		{
			stage.addEventListener(MouseEvent.MOUSE_UP, changeWorker, false, 0, true); 			 
			addWorker();					
		}	
		
		public function addWorker():void 
		{
			worker = employees[ randomInt(0,2) ] as IEmployee;		 			
			addChild( worker.view );
			
			talkTheTalk();			
		}
		
		public function changeWorker(e:MouseEvent):void
		{				
			removeChild( worker.view );
			worker = null; 
			
			addWorker();
		}

		public function talkTheTalk():void 
		{
			trace( "This employee is a " + getQualifiedClassName(worker.view) + " and says '" + worker.talk() + "'" );
		}
		
		public function randomInt(low:Number=0, high:Number=1):int
		{
			return Math.floor(Math.random() * (1+high-low)) + low;
		}				
	}
}