Greetings to all!
We are at chapter 9 of the Object Oriented Programming with Flash CS3.
This time, I will get into the Inheritance of Actionscript 3.0.
I would like to precise that this theme is wide and complex and it is not the final goal for FlepStudio to get into every little details.
With this tutorial, you will get the base on what is Inheritance and its primary concepts.
For those of you who want to study Inheritance in more details, I advise this following book:
- Essential Actionscript 3.0 by Colin Moock - O'REILLY
So, what does Inheritance means in Actionscript 3.0"
In Object Oriented Programming, the term Inheritance expresses the concept of relationship in between 2 or more classes, where a class inherits the methods and property"s definitions from another class.
In practical terms, the Inheritance simply allows to use the code from a class to another.
Inheritance in biology is a genetic process with which a child for example inherits the color of eyes from his father and the color of hair from his mother.
This process does not implicate that the child has eyes and hair like his parents but also all its particularities.
In Actionscript 3.0, the Inheritance is very similar to the above example. A class will have available the methods and properties of another class and even more, will implement them as defined.
I create a FLA and I name it "main.fla".
I create a Document Class, an AS file saved as Main.as, implemented the following way:
In the first Object Oriented Programming tutorial I didn"t get into explaining the operator "extends".Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { } } }
It is time to reveal the secret behind it!
The word "extends" tells Flash that our Main class extends another class, in this case, the MovieClip Class.
To extend a class means to inherit its properties and methods.
In programming slang, in this case, we can affirm that the MovieClip Class is the superclass of Main and Main is a subclass of MovieClip.
Let us not be deceived by the terms superclass and subclass because grammatically speaking, it would seem that the MovieClip being the superclass of Main is the most complete class when instead it is the contrary.
The subclass is always the most complete one as it has available the methods and properties of its superclass plus it can implement its own.
In fact, the MovieClip class in this example does not inherit from the Main Class, as Main extends MovieClip, and Main is the child of MovieClip. A father never inherits from its own child!
Let us make an example, as Main is the subclass of MovieClip, it should have available the properties of the MovieClip Class. True! If we try to ask Flash the alpha property of Main:
Flash does not advise us that there is an error or that there is not a property named "alpha" in Main.as. Instead, it gives us this output:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { trace(alpha); } } }
1
This means that Main has inherited the property alpha from the MovieClip Class.
If we try with another example, in this case with the x, y and rotation:
once again, no errors are returned and we get the following output:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { trace(x); trace(y); trace(rotation); } } }
0
0
0
Next, let us make an example with two classes instantiated from the Document Class.
I create a class named "Aclass", an AS file saved as "Aclass.as" implemented the following way:
I implement to it a property (my_name) and a method (eyes):Code:package { public class Aclass { public function Aclass() { } } }
Now I will instantiate the class from the Document Class (Main):Code:package { public class Aclass { public var my_name:String='A'; public function Aclass() { } public function eyes():void { trace('eyes method of Aclass has ben invoked'); } } }
nothing new here. In fact, I instantiated Aclass and I called its property my_name and its method eyes obtaining the following output:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var a_class:Aclass=new Aclass(); trace(a_class.my_name); a_class.eyes(); } } }
A
eyes method of Aclass has been invoked
Next, I create another class named Bclass which extends the Aclass, an AS file saved as "Bclass.as", implemented the following way:
As explained at the beginning of this tutorial, Bclass extends Aclass means that Bclass can use the methods and properties of Aclass.Code:package { public class Bclass extends Aclass { public function Bclass() { } } }
Let us test it. I instantiate Bclass and I call the property my_name and the method eyes from its instance:
I obtain the following output:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var a_class:Aclass=new Aclass(); trace(a_class.my_name); a_class.eyes(); var b_class:Bclass=new Bclass(); trace(b_class.my_name); b_class.eyes(); } } }
A
eyes method of Aclass has been invoked
A
eyes method of Aclass has been invoked
Here we are! Even though Bclass has not the property my_name and even less the method eye implemented, Flash reads that it extends Aclass and following the principle of Inheritance, it goes to retrieve the property and method from Aclass!
I is important to well understand this concept for those of you who want to learn to develop following the good rules of OOP.
Important: an Actionscript 3.0 class can not inherit the static properties and static methods from its superclass.
Let us see another example.
If we have some coding in the constructor function of Aclass (as we know, the code which is carry out as soon as the class is instantiate), would Bclass inherit those code from its own constructor function"
I add the code in the constructor function of Aclass the following way:
if I publish the FLA, I obtain the following output:Code:package { public class Aclass { public var my_name:String='A'; public function Aclass() { trace('Aclass has been instantiate'); } public function eyes():void { trace('eyes method of Aclass has ben invoked'); } } }
Aclass has been instantiate
A
eyes method of Aclass has been invoked
Aclass has been instantiate
A
eyes method of Aclass has been invoked
As we can see, Bclass has also inherited the code implemented in the constructor function of Aclass.
In this case, Flash adds a call to the constructor function of the superclass, adding the keyword super()
To be more "educated", we should add ourselves this keyword super() to call the constructor function of Aclass from the Bclass, the following way:
anyone reading our class will immediately understand what we are doing without any doubt that it has been done by mistake.Code:package { public class Bclass extends Aclass { public function Bclass() { super(); } } }
Until now, we saw how to take advantage of the methods of Aclass even with a Bclass. Obviously, Bclass, at its turn, can implement its own methods.
As an example, I implement a new method (hairs) to Bclass:
From the Document Class, into which are instantiate the Aclass and Bclass, I try to invoke the above method:Code:package { public class Bclass extends Aclass { public function Bclass() { super(); } public function hairs():void { trace('hairs method of Bclass has been invoked'); } } }
and I obtain the following output:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var a_class:Aclass=new Aclass(); trace(a_class.my_name); a_class.eyes(); var b_class:Bclass=new Bclass(); trace(b_class.my_name); b_class.eyes(); b_class.hairs(); } } }
Aclass has been instantiate
A
eyes method of Aclass has been invoked
Aclass has been instantiate
A
eyes method of Aclass has been invoked
hairs method of Bclass has been invoked
We can notice that the method has been carried out as it should. This confirms the fact that the subclass can use the methods of the superclass and also have its own methods.
Be careful though"let us not forget that a father (Aclass) can not inherit from its child (Bclass).
So, if we try to invoke the method hairs of Bclass from the instance of Aclass:
We will get the following error:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var a_class:Aclass=new Aclass(); trace(a_class.my_name); a_class.eyes(); var b_class:Bclass=new Bclass(); trace(b_class.my_name); b_class.eyes(); b_class.hairs(); } } }
1061: Call to a possibly undefined method hairs through a reference with static type Aclass.
This is due to the fact that Flash does not find any method hairs in Aclass and does not go to search it in its child (Bclass).
Let us take a look to another important case.
If we wanted that Bclass inherits the method eyes of Aclass, we know how to do it. But if, instead, we wanted that the same method, other then carry out the code included into the method eyes of Aclass, carries out another action"
Sometimes, a subclass needs to inherit from the superclass not to have to rewrite all the original code. Sometimes, this simple call is not enough and it would need to execute some other code on top of it.
Simple. We can overwrite the method of the superclass from the subclass.
Confused" Let us look at a concrete example.
I overwrite the method eyes from the Bclass:
override public function eyes, means: Flash ! Overwrite the method eyes of BClass inherited from the Aclass. Execute its code and do not go to retrieve this method from Aclass!Code:package { public class Bclass extends Aclass { public function Bclass() { super(); } public function hairs():void { trace('hairs method of Bclass has been invoked'); } override public function eyes():void { trace('override eyes method of Bclass has ben invoked'); } } }
In fact, maintaining the same calls from the instances of Aclass and Bclass from Main, I obtain the following output:
Aclass has been instantiate
A
eyes method of Aclass has been invoked
Aclass has been instantiate
A
override eyes method of Bclass has been invoked
hairs method of Bclass has been invoked
As we can see from this output, the instance b_class of Bclass has invoked the method eyes and as the Bclass implements a method override, that one has been carried out.
Important: an Actionscript 3.0 class can not overwrite properties, static properties and static methods
Finally, let us see what happens if the constructor function of the superclass (Aclass) implements parameters.
Let us say that we have a class named Cclass, an AS file saved as "Cclass.as", implemented the following way:
as we can see, Cclass has 2 parameters implemented in the constructor function, so we can instantiate Cclass from Main, the following way:Code:package { public class Cclass { public function Cclass(a:int,b:String) { trace('parameter a of Cclass is: '+a,'parameter b of Cclass is: '+b); } } }
This is the ouput obtained:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var c_class:Cclass=new Cclass(2,'hello'); } } }
parameter a of Cclass is: 2 parameter b of Cclass is: hello
and nothing new to it.
If we wanted a class that extends Cclass, how would we implement the constructor function"
I create a class named Dclass, an AS file saved as "Dclass.as", implemented the following way:
To reassume"Dclass extends Cclass, with Cclass that implements 2 parameters in the constructor function while Dclass does not.Code:package { public class Dclass extends Cclass { public function Dclass() { } } }
If I try to instantiate Dclass:
I obtain this error:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var c_class:Cclass=new Cclass(2,'hello'); var d_class:Dclass=new Dclass(); } } }
1203: No default constructor found in base class Cclass.
This means that Dclass also needs 2 parameters declared in the constructor function.
Let us try to instantiate it passing the parameters without declaring them first:
nothing to do"we obtain the same error:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var c_class:Cclass=new Cclass(2,'hello'); var d_class:Dclass=new Dclass(4,'bye bye'); } } }
1203: No default constructor found in base class Cclass.
At this point, I declare the 2 parameters in Dclass:
and retry to instantiate Dclass:Code:package { public class Dclass extends Cclass { public function Dclass(a:int,b:String) { trace('parameter a of Dclass is: '+a,'parameter b of Dclass is: '+b); } } }
once again, the same error:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var c_class:Cclass=new Cclass(2,'hello'); var d_class:Dclass=new Dclass(4,'bye bye'); } } }
1203: No default constructor found in base class Cclass.
This is due to Flash that adds the super() but not the parameters. The constructor of Cclass is called but requires 2 parameters and it leads Flash into error.
This is why it is also important to take the habit to use the key super().
Let us try to add it in the constructor function of Dclass, also passing the 2 parameters, the following way:
I instantiate Dclass:Code:package { public class Dclass extends Cclass { public function Dclass(a:int,b:String) { super(a,b); trace('parameter a of Dclass is: '+a,'parameter b of Dclass is: '+b); } } }
and this time I obtain the following output:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var c_class:Cclass=new Cclass(2,'hello'); var d_class:Dclass=new Dclass(4,'bye bye'); } } }
parameter a of Cclass is: 2 parameter b of Cclass is: hello
parameter a of Cclass is: 4 parameter b of Cclass is: bye bye
parameter a of Dclass is: 4 parameter b of Dclass is: bye bye
Let us study this output.
First I instantiate Cclass and obtain:
parameter a of Cclass is: 2 parameter b of Cclass is: hello
next I instantiate Dclass and obtain:
parameter a of Cclass is: 4 parameter b of Cclass is: bye bye,
and this makes me understand that first the constructor function of Cclass has been invoked as there is super() in Dclass. And next, the constructor of Dclass has been invoked with "parameter a of Dclass is: 4 parameter b of Dclass is: bye bye"
One question comes to me"and if I wanted to add a parameter to the subclass but not the superclass"
The right answer is: first, the subclass needs to declare the same parameters as the ones declared in its superclass; second, we then can implement other parameters.
So, the constructor function becomes as follow:
and in fact, If I instantiate Dclass passing to it 3 parameters:Code:package { public class Dclass extends Cclass { public function Dclass(a:int,b:String,c:Number) { super(a,b); trace('parameter a of Dclass is: '+a,'parameter b of Dclass is: '+b,'parameter c of Dclass is: '+c); } } }
I obtain the following output:Code:package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var c_class:Cclass=new Cclass(2,'hello'); var d_class:Dclass=new Dclass(4,'bye bye',3.7); } } }
parameter a of Cclass is: 2 parameter b of Cclass is: hello
parameter a of Cclass is: 4 parameter b of Cclass is: bye bye
parameter a of Dclass is: 4 parameter b of Dclass is: bye bye parameter c of Dclass is: 3.7
This time, we can notice:
First I instantiate Cclass an in fact, it tells me: parameter a of Cclass is: 2 parameter b of Cclass is: hello
then I instantiate Dclass and it tells me: parameter a of Cclass is: 4 parameter b of Cclass is: bye bye, which makes me understand that first the constructor function of cclass has been invoked (as there is super in the constructor of Dclass) but passing only the first 2 parameters (the ones implemented in Cclass)
Then the constructor of Dclass has been invoked using the 3 parameters as it tells me:parameter a of Dclass is: 4 parameter b of Dclass is: bye bye parameter c of Dclass is: 3.7
Source files:
Last edited by Flep; 05-06-08 at 12:52.
Bookmarks