flash oop_inheritance

Inheritance

The idea of inheritance is a key concept of object oriented programming taken directly from the world around us. All things from the real world inherit from another by specializing, as human beings we inherit all our characteristics from mammals just as a fruit inherits its characteristics from fruit.

Inheritance is used when a relation type “is one” is possible. We can consider that an administrator “is one” type of player and doesn’t have all its capacities, and others make it a moderator.

When this relation is not verified, inheritance doesn’t have to be considered, in this case we generally prefer composition. We look at the difference between inheritance and composition in later articles and see that inheritance can prove to be rigid and difficult to maintain in certain situations.

In the context of inheritance, child classes automatically inherit functionailities from their parent classes. In this case we will create an Administrator class inheriting all of the functionailities of the player class. The parent class is generally called super-class and the chid is called the sub-class.

We will define an administrator class alongside the player class in order to trigger the inheritance we will use the keyword extends:

package
{
// the inheritance is translated by the keyword extends
public class Administrator extends Player
{
public function Administrator ( )
{
}
}
}

Then we instantiate an administrator object:

var myModo:Administrator = new Administrator();

On compilation the following error is generated:

1203: No default constructor found in base class player.

When a child class extends a parent class we have to pass a parent constructor the necessary parameters for the initialisation of the parent class, to trigger the parent constructor we use the keyword super:

package
{
// the inheritance is translated by the keyword extends
public class Administrator extends Player
{
public function Administrator ( pName:String, pSurname:String,
pAge:int, pTown:String )
{
super ( pName, pSurname, pAge, pTown );
}
}
}

The value of inheritance resides in the reuse of code:

8.6.1.jpg

Without inheritance we have to redefine the bunch of methods of the player class in the administrator class.

Thanks to the inheritance triggered by the keyword extends, the child class administrator inherits all of the functionalities of the parent class player:

// 
we create an administrator object
var myModo:Administrator = new Administrator("Michael", "Jackson", 48,
"Los Angeles");
// the moderator has all the capacities of a player
// displays : My name is Michael, I am 48 years old.
myModo.present();
// displays : Jackson
trace( myModo.Surname );
// displays : Michael
trace( myModo.Name );
// displays : 48
trace( myModo.age );
// displays : Los Angeles
trace( myModo.Town );

There are many exceptions to inheritance, the methods and static properties aren’t inherited. The static method getNumberPlayers defined in the Player class is not available in the administrator class:

// instancing of an administrator
var myModo:Administrator = new Administrator("Michael", "Jackson", 48,
"Los Angeles");
// the static method Player.getNumberPlayers is not inherited
myModo.getNumberPlayers();

The following compilation error is generated:

1061: Call to a possibly undefined method getNumberPlayers through a reference with static type Administrator.

Note that multiple inheritance is not generated in ActionScript 3, a class cannot directly inherit multiple classes.

The inheritance isn’t limited to personalised classes. We will see in the chapter entitled Extending Flash how to extend classes native to Flash in order to increase the capabilities of classes such as Array, BitmapData or MovieClip and many others.

Worth remembering

  • Inheritance allows us to easily reuse the functionailities of an existing class.
  • The parent class is called super-class, the child class is called sub-class. We therefore talk about super-types and sub-types.
  • In order to inherit a class we use the keyword extends.

Sub-types and super-types

Thanks to inheritance the administrator class has two types; Player is considered as a super-type and Administrator as a sub-type:

// the administrator class is also the player type
var myModo:Administrator = new Administrator("Michael", "Jackson", 48,
"Los Angeles");
// a moderator is a player
// displays : true
trace( myModo is Player );
// a moderator is also an administrator
// displays : true
trace( myModo is Administrator );

Wherever the super-type is expected we can pass a sub-type instance, a player type variable can store an administrator object type:

// the administrator class is also the player type
var myModo:Player = new Administrator("Michael", "Jackson", 48, "Los
Angeles");
// a moderator is a player
// displays : true
trace( myModo is Player );
// a moderator is also an administrator
// displays : true
trace( myModo is Administrator );

All of the administrators are players, the compiler knows that all the player type functionalities are present in the administrator class and allow us to compile.

The opposite is not true, the players are not exactly administrators, it is therefore impossible to allocate a super-type to a sub-type variable. The following code cannot be compiled:

// the player class is not an administrator type
var myModo:Administrator = new Player("Michael", "Jackson", 48, "Los
Angeles");

The following compilation error is generated:

1118: Implicit coercion of a value with static type player to a possibly
unrelated type administrator.

The compiler cannot guarantee that the functionailities of the administrator class will be present on the player object and therefore forbids compilation.

We find the same concept by using the native graphic classes such as flash.display.Sprite and flash.display.MovieClip , the following code can be compiled without any problems:

// an instance of MovieClip is also a Sprite type
var myClip:Sprite = new MovieClip();

The MovieClip class inherits the Sprite class therefore an instance of a MovieClip is also a Sprite type. On the other hand, a Sprite is not a MovieClip type.

// a Sprite instance is not a MovieClip type
var myClip:MovieClip = new Sprite();

If we test the previous code the following compilation error is generated:

1118: Implicit coercion of a value with static type flash.display:Sprite 
to a possibly unrelated type flash.display:MovieClip.

The question that we can ask is the following: what is the value of storing a corresponding object to a sub-type in a super-type variable? Why not simply use the corresponding type?

In order to understand this concept, imagine that a method returns objects of different types. Let’s take the following case of a getChildAt method and DisplayObjectContainer class.

If we look at its signature, we see that it returns a DisplayObject object type:

public function getChildAt(index:int):DisplayObject

In effect, the get ChildAt method can return all sorts of graphic objects such as Shape, MovieClip, Sprite or SimpleButton. All these types have something that links them, the DisplayObject type is the common type to all the graphic objects, therefore when many types are expected, we use a type common to different classes.

We are going to put this into practice in our playerManger class, if we look at the signature of the addPlayer method we see that this accepts a player type parameter:

public function addPlayer ( pPlayer:Player ):void
{
pPlayer.present();
arrayPlayers.push ( pPlayer );
}

Player is the type common to the two classes player and administrator, we can therefore pass instances of the administrator type with no problem:

// creation of players and the moderator
var firstPlayer:Player = new Player ("Bobby", "Womack", 66, "Detroit");
var secondPlayer:Player = new Player ("Michael", "Jackson", 48,
"Michigan");
var thirdPlayer:Player = new Player ("Lenny", "Williams", 50, "New
York");
var myModo:Administrator = new Administrator ("Stevie", "Wonder", 48, "Los
Angeles");
// management of players
var myManager:PlayerManager = new PlayerManager();
// addition of players
/* displays :
My name is Bobby, I am 66 years old.
My name is Michael, I am 48 years old.
My name is Bobby, I am 30 years old.
My name is Stevie, I am 48 years old.
I am a moderator
*/
myManager.addPlayer ( firstPlayer );
myManager.addPlayer ( secondPlayer );
myManager.addPlayer ( thirdPlayer );
myManager.addPlayer ( myModo );

If we need to create new player types at a later date by extending the player class, no modification is necessary in the addPlayer function.

Worth remembering

  • Thanks to inheritance a class can have many types.
  • Wherever a parent class is expected we can use a child class. This is what we call polymorphism.

Specialising a class

For the moment the administrator class has the same functionalities than the player class. It is useless to simply inherit a parent class without adding new functionalities by defining new methods in the administrator class we specialize the player class.

We will define a new method called kickPlayer which will have the goal of deleting a participating player:

package
{
// the inheritance is translated by the keyword extends
public class Administrator extends Player
{
public function Administrator ( pName:String, pSurname:String,
pAge:int, pTown:String )
{
super ( pName, pSurname, pAge, pTown );
}
// method allowing the deletion of a player of the part
public function kickPlayer ( pPlayer:Player ):void
{
trace ("Kick " + pPlayer );
}
}
}

The administrator class has a kickplayer method as well as the functionailites of the player class. We have specialised the player class through the administrator class.

8.6.2.jpg

When the kickPlayer method is executed, we have to call the deletePlayer method of the playerManager class as it is that which centralises and manages the connected players.

Each administrator could have a reference to the playerManager class but it would be too limiting, in this case we prefer an event approach by using ActionScript 3’s event model in our personalised classes with the help of the flash.events.EventDispatcher class.

The idea of the broadcast of personalised events is treated in detail in the chapter entitled personalised event broadcasts. Once finished, don’t hesitate in coming back to this example to add the necessary code. The idea is that that the administrator class broadcasts an event indicating to the playerManager class to delete the player in question.

We find again here the idea of the listener/ broadcaster discussed in the previous chapters:

8.6.3.jpg

When an administrator broadcasts the appropriate event the playerManager deletes the participating player. We will now look at a process called type-casting which is very useful in the context of inheritance.

Worth remembering

  • You should not confuse inheritance and specialisation.
  • Even if it is not advised a class can inherit another without adding new functionalities.
  • When a sub-class adds new functionality we say that it is a specialised-class.







Adobe Training center


Mediabox Training Centre © 2000 - 2008 All rights reserved.
Adobe Authorized Training Centre. State convention under number 25 14 02167 14.
Mediabox : SARL au capital de 62.000€ - Activity number: 25 14 02167 14 - SIRET : 493 716 468 00027
MEDIABOX, 102 Avenue des Champs Elysées, 75008 PARIS - Tel. +33(0)2.31.91.96.89 - Fax. +33(0)2.72.68.56.42