How to use interface in ActionScript 3

There are a lot of good ActionScript 3 books out there, but in most of them all the examples about inheritance, composition, interface, polymorphism and more complex object oriented principles are done using data classes. It’s good to explain the principles, but when you are ready to code some actual classes in Flash, some problems start to arise. Most of my problems come from the fact that 90% of the time I am coding classes that are a visual representation of something. So these classes extends the Sprite or MovieClip class.

So I was coding this game class where I have multiple kind of monsters but I want to use the same functions without checking what kind of monster it is. This is a case where polymorphism comes in handy. The thing is I didn’t do my classes of monster using inheritance (which maybe I should have done), so in order to use polymorphism, I have to create an interface with the public methods common to all my monster classes. So I open the Colin Moock book and start looking at how to code interfaces. Here is a list of quick facts that will help you while doing so.

  • You have to list all public methods that will be common for the classes that implements this interface;
  • You do so by writing the definition of the function, its name, its parameters and its return type;
  • You don’t have to open and close curly braces after the method definition
  • You don’t specify if the method is private, public or protected (that’s kind of obvious but I did that mistake)
  • interface can only extend other interfaces
  • a class can implement more than one interface

So here is an example of an interface in As3:

package com.mutantfarm.monster{
  public interface IMonster {
    function getShot(damage:uint):void;
    function getCanShoot():Boolean;
  }
}

Here is how my visual class implements this interface while also extending the MovieClip class:

public class spriteMouton extends MovieClip implements IMonster{

It is important that you put the extend keyword before the implement keyword.

So most of what I just wrote about was details about interfaces, but when you start coding, all these details are important to know.

Here are two more article I wrote about interfaces:

, ,

  1. #1 by yohami - January 2nd, 2008 at 05:36

    Hi Zeh. How does this save time? all the methods in the interface have to be defined again on each class, right?

  2. #2 by dgelineau - January 3rd, 2008 at 01:47

    You use interfaces and polymorphism when you want to code in a way that is more maintainable. If the flash compiler is set to soft (it won’t complain for type error) then you don’t have to bother with that.

    But if your code is going to be used for more than one project or by more than one person, I would advise using this kind of technique. Having your compiler in strict mode is really good for catching error before they arise.

    So in my case, I wanted to check if I could shoot this monster or hurt it. I had to tell the compiler which monster it was in order to use the getShoot method. In a complex game, it could have been one type of monster from a dozen type and I would have to check the current monster against each type. Instead I make sure that every monster implements the IMonster interface and because of that the compiler will throw me an error if I don’t code a getShoot and canGetShoot method with the same definition as in the interface (same parameters and return type).

    When I will shoot a monster, I only have to cast any monster to the IMonster type and I am sure it will have the previously mentionned methods. In time it will save me trouble, which might not be obvious at first.

  3. #3 by yohami - January 3rd, 2008 at 16:26

    Hi dgelineau,

    Thanks. I get it. I thought the interface methods would be inherited or utilized, but they are just a template to make sure a certain class meets the standards. I will probably use it too.

    Cheers,
    Yohami

  4. #4 by Will - December 7th, 2008 at 15:57

    Are you sure this is correct?

    I’m pretty sure you can’t apply an interface to display objects as you will get a type error when you add it to the display list. Take the following for example:

    var myMonster:IMonster = new spriteMouton();
    addChild(myMonster);

    This will throw a type coercion error because as far as IMonster is concerned it know’s nothing about inheriting from a DisplayObject.

  5. #5 by Dan - December 14th, 2008 at 23:54

    Hey Will, you can cast your object to DisplayObject to add it.

    var myMonster:IMonster = new spriteMouton();
    addChild( DisplayObject( myMonster ) );

  6. #6 by g - December 25th, 2008 at 10:22

    thats pretty good explanation in the comment, dgelineau.

  7. #7 by David - February 17th, 2009 at 15:11

    Regarding casting a spriteMouton to Displayobject.
    The IMonster interface could be extended to the interface of the DisplayObject and thereby ensuring that classes implementing the IMonster always must extend DisplayObject hence no need to type cast. Just a thought. :)

  8. #8 by zedia.net - February 17th, 2009 at 16:56

    @David
    In ActionScript, an interface cannot extend another class, it can only implement another interface, so we cannot do what you are saying, but it would be nice to do so.

  9. #9 by Paul - February 22nd, 2009 at 01:43

    Shouldn’t :

    var myMonster:IMonster = new spriteMouton();
    addChild( DisplayObject( myMonster ) );

    be:

    var myMonster:spriteMouton = new spriteMouton();
    addChild( myMonster );

    As mentioned above the Interface is not a Class and therefore will throw type errors because it is not a type. If it is declared correctly there should be no need for coercion / casting.

  10. #10 by zedia.net - February 23rd, 2009 at 15:58

    @Paul
    Yes and No, if what you are looking for is polymorphism then you probably want to cast your object to an interface.

    Now you could just do what you say and later push myMonster into an array and when retrieving it, cast it to the interface and that would work just as good. It all depends of the context of your application.

  11. #11 by steve76 - March 18th, 2009 at 12:02

    @post 10
    I think that You never will do a cast in the Paul code.
    You can use myMonster as MovieClip or implementation of a IMonster interface without casting in every method that receive as parameters or an MovieClip or an IMonster.

    I’m a newbee from the point of view of AS3, but I work with PHP5, C++, Java and so on and that is the main rule ( I suppose so ). am I in fault for AS3?

    Bye,Ste

  12. #12 by red tuttle - March 28th, 2009 at 15:01

    Is there an easy way to check if a particular object implements an interface?

    I have a collection of objects of type IFoo, of which any of them may or may not implement a certain interface, maybe IBar or whatever.

    in C# I would do:

    if (foo.type is IBar)

    But is is not a keyword in CS3

  13. #13 by zedia.net - March 28th, 2009 at 15:50

    You can in Actionscript 3 use the is keyword like this:

    if (entityList[i] is IBar) {

    I have used it and it works perfectly.

  14. #14 by John Giotta - April 16th, 2009 at 09:43

    Interace is useful when dealing with shared asset libraries as well. You may refer to the interface class in the application for general definitions of what implementing class will define. Much like intrinsic did for AS2.

  15. #15 by ad - April 26th, 2009 at 16:34

    Just tried this for the first time and found no need for casting.

  16. #16 by Fraanske - July 14th, 2009 at 14:53

    if (monsterInstance as IMonster)
    {
    // monsterInstance implements IMonster
    } else {
    // monsterInstance does not implement IMonster
    }

    trace(monsterInstance as IMonster)
    // Traces either a monsterInstance or null

    This is the simplest Interface check I could come up with.

  17. #17 by Joshua - August 19th, 2009 at 18:12

    You can also use the “as” parameter.

    var newMonster:IMonster = new ScaryMonster ();
    addChild (newMonster as DisplayObject);

  18. #18 by brecht - August 28th, 2009 at 06:38

    this doesn’t work because you can’t call the displayObject specific parameters like x, y, addEventListener and so on. There has to be another way to make movieclips subject to an interface without losing it’s displayObject specific methods and params. Anyone?

  19. #19 by brecht - August 28th, 2009 at 06:42

    Well i guess you can just cast to DisplayObject everytime you need a property but still…

  20. #20 by Weeble - December 15th, 2009 at 10:31

    very usefull explanation, I’ve struggled to get my head round this for a while now and you helped clear it up. Thanks!

  21. #21 by ayu - March 27th, 2010 at 18:34

    hi, how do we have public variables in interfaces?

  22. #22 by zedia.net - March 28th, 2010 at 15:08

    You don’t need to say variables and methods are public in an interface because it is implicit. An interface is a minimum list of public variables or methods that a class must have in order to implement it.

  23. #23 by Gena - April 14th, 2010 at 15:27

    I’m very confused with interfaces because i do a lot of elearning and i’ve never seen an example similar to what i do. Can you please give me an example of using interfaces in elearning CBTs? I make a lot of templates and they all have data loaded from xml and back, next, and help buttons and a review quiz at the end. Then a results screen telling you what you missed(your score) and what the right answer was and it’s printable. Thanks!

  24. #24 by Andre - April 14th, 2010 at 23:53

    An interface is an abstract class it cannot be instantiated. That means you cannot do this : im:IMonster=new IMonster();. To find an interface useful you have to understand polymorphism.A simple definition of Ploymorphism is from Generalisation to specialisation.Ex: You have fruits you want to know how many vitamins they contain and display it. Here is some code in ActionScript:
    //(Generalisation)
    public interface Ifruit
    {
    function getVitamins():string
    }
    //(Specialisation)
    public Class Apple implements Ifruit
    {
    private number_of_vitamins_:string;
    //some code
    function getVitamins ():string
    {
    return number_of_vitamins;
    }
    };

    public class FruitDisplayer extends Sprite
    {
    displayedtext_:Label;
    //Constructor plus more code
    function DisplayFruitVitamins(IFruit fruit):void
    {
    displayedtext_.Text=fruit.getVitamins ():
    }
    };

    You see DisplayFruitVitamins can receive any IFruit like apple,orange banana…

    P.S.(1) For the purpose of simplifying things i used string but it’s more logical to use an integer for number_of_viatmins_ and the getVitamins() function. Cast it into string before displaying.

    P.S.(2) I am a C++ and C# coder, i just started with ActionScript so if there is something more suitable than a label just to display text (no user input) well be free to “tell” me thx.

  25. #25 by Good Question - April 27th, 2010 at 07:16

    ayu : hi, how do we have public variables in interfaces?

    I believe they were asking about using an interface to require the presence of EITHER an explicit setter/getter or an implicit setter/getter. Explicit works, but implict does not…

    Unless there is some way around it that I am not aware of, interfaces prevent you from using implicit getters and setters – that’s bad!

  26. #26 by Neus - June 2nd, 2010 at 08:29

    @Good Question

    If you declare your implementation variables as bindable (or the whole class), the compiler will accept…

    This is because the compiler change the variable in two getter and setter, a mimick of the interface implementation…

  27. #27 by roee - June 30th, 2010 at 04:22

    thanks

  28. #28 by Kawika - August 25th, 2010 at 23:54

    This helps with learning interfaces, thanks.

  29. #29 by Chris - August 28th, 2010 at 11:30

    Hehe, it’s this short intros that saves the average AS3 starter a lot og “head against the wall/desk” time.

  30. #30 by Quakeboy - November 24th, 2010 at 13:00

    Thanks for the quick tutorial.. apt length and to the point explanations.

  31. #31 by northmantif - December 6th, 2010 at 06:34

    and what’s the difference between making an Interface, and extending class from a Fruit class i.e. like in the example above, but to pass to the:
    function DisplayFruitVitamins(fruit:Fruit):void
    {
    displayedtext_.Text=fruit.getVitamins ():
    }

    DisplayFruitVitamins(banana);
    ??

  32. #32 by asciiman - December 17th, 2010 at 15:42

    @northmantif
    An interface is a signature, while if you extend from a Fruit class you must actually implement the fruit class. How would you implement the getVitamins() function for a Fruit? You can’t, because generic fruits don’t have vitamins. A generic fruit is just a generalization, not actually real.

    So interfaces are good for when you need to generalize something that is in common with multiple real things, and you want to create a binding signature for those things.

  33. #33 by jack - January 17th, 2011 at 13:01

    @ brecht

    But still what?

  34. #34 by max - January 18th, 2011 at 21:28

    For those struggling about the fact that once an interface is implemented you lose for example the displayobject inheritance (because you cannot extend your interface to a class,) .. the solution is the other way around… you shouldn’t cast to a displayobject but have your object already as displayobject and then eventually cast to your interface when you need specifc stuff from there (isn’t that the meaning of an interface.. ;-) ). If I have a base class Page (which may or may not implement an interface) but for sure will extend a displayobject and other subpages like Homepage, Contactpage and so on which implement an interface.. when I create an Homepage instance I create it as a Page(displayobject) so I can move it, attach listerners and add it to stage.. only when I need to call a specific method from the interface I cast it to the interface and for example call an initPage() …

  35. #35 by Tim - June 6th, 2011 at 10:27

    @ yohami
    In addition, this will allow your code to be dynamic down the road. Think of an interface as a way of building functions that can be variable within a class. If you create an interface, then you can create several classes that implement that interface. In this way, those classes define a behavior (functionality) described in the interface. Then you can create an instance of these classes within your main object, and change it over time to basic render all the functions within the interface as ‘variable’ functions.

    The short and easy description is that using interfaces allows you to add dynamic behavior (functionality) to your classes, as opposed to hard coding it.

  36. #36 by steve - June 15th, 2011 at 19:17

    I’m building a game with this sort of class hierarchy:

    Class Entity extends Sprite
    Class Player extends Entity
    Class Platform extends Entity
    Class Monster extends Entity

    These are the main classes, but within class player and class monster I have a reference for a settings object:

    Interface EntitySetting
    public get…set…
    public methods….
    abstract methods… (implemented by specific child class)
    Class MonsterSetting implements EntitySetting
    Class PlayerSetting implements EntitySetting
    Class PlatformSetting implements EntitySetting
    So in the Specific class settings objects, each using the function headers from the EntitySetting class.

    So then I can just have an array of Entity objects in my main game driver class. You can easily perform operations on all objects at once by calling them all Entities, then any specific code will filter through their Settings object. If it is Melee dps monster or a ranged caster monster, or a tall platform, short platform with spikes, w/e.

  37. #37 by Daniel - August 3rd, 2011 at 22:59

    For instance

    you can use in the interface

    function get displayObject():DisplayObject;

    in the spriteMount class

    public function get displayObject():DisplayObject
    {
    return this;
    }

    and in another class

    var see:Imonster;

    and then

    see = new spriteMount();

    and then

    see.displayObject.x = 100;
    see.displayObject.y = 100;

  38. #38 by encoder - November 28th, 2011 at 08:25

    @ yohami

    by letting you focus on architecture and not the algorithms that actually control the “monster” for example.

(will not be published)
Subscribe to comments feed