AS1 OOP: Inheritance
by senocular
Super
Since inheritance here is carried through the prototype, it
specifically handles shared properties and methods. Setting
up inheritance like that doesn’t do anything for defining
unique properties in subclass instances. Notice in the
Person-SuperHero example that name and age properties in the
Person constructor are not defined in the SuperHero
constructor. They are available to SuperHero instances, but
only available to through the prototype as that is the only
place they are defined when the inheritance is setup.
Because of this, each SuperHero instance effectively
references the same name and age from the prototype object
instead of having their own unique property for each (which
here would be undefined since the Person constructor was
called without any parameters passed to it). What is needed
is to have the Person constructor run specifically for each
instance of a SuperHero when its created thereby giving each
the unique properties defined by that constructor. The super
command does just that for us.
The super keyword is an operator available in the local
scope of a subclass constructor function call (or method
call) that allows that class to reference the constructor of
and individual methods of the super class in which it
inherits from. This allows you to define unique properties
specified by a super class in each instance of a subclass by
running the super class constructor for each instance
created. In this manner, super acts just like the super
class constructor so pass in variables as needed. Lets
incorporate that into the SuperHero class.
- // Person class definition
- Person = function(name, age){
- this.name = name;
- this.age = age;
- };
- Person.prototype.speak = function(phrase){
- trace(phrase);
- };
- // SuperHero class definition
- // use parameters needed in super class constructor
- SuperHero = function(name, age, power){
- // run the super class constructo, Person, on
- // the instance of SuperHero being created
- super(name, age);
- // assign additional property values as needed
- this.superPower = power;
- this.peopleSaved = new Array();
- };
- SuperHero.prototype = new Person();
- SuperHero.prototype.savePerson = function(person){
- this.peopleSaved.push(person);
- this.speak("A SuperHero's job is never done!");
- };
- SuperHero.prototype.getLastPersonSaved = function(){
- return this.peopleSaved[this.peopleSaved.length-1];
- };
- // check a super heros properties
- worldsLastHero = new SuperHero("Bob", 74,
"Whittling");
- trace(worldsLastHero.name); // traces "Bob"
- trace(worldsLastHero.age); // traces 74
- trace(worldsLastHero.superPower); // traces
"Whittling"
- // which are different from what would be the
otherwise accessed prototype values
- trace(SuperHero.prototype.name); // traces undefined
- trace(SuperHero.prototype.age); // traces undefined
The super function, however, also serves as an object to
reference the super class’s prototype object. Using the
super in this manner allows you to call methods directly off
the super class prototype for your subclass instance.
Normally you wouldn’t need to do this since your subclass
instances automatically inherit those methods directly,
however, when you would need to use this is when you have a
subclass that has a method with the same name as a super
class method. Yes that’s possible and not uncommon.
In defining a subclass, you may find yourself in need of
re-defining a certain method so that it would more
specifically suit instances the new class. That’s well and
fine. Doing so is just a matter of creating the method again
within that subclass with the new definition desired. This
won’t have any effect on the super class’s version and all
instances of the subclass will use the new definition in
favor of the one in the super class since it would be found
first in the inheritance chain. If, however, you wanted to
get a call to the super class method of that same name, you
still could through super. Super would then allow you to
bypass the class prototype’s method and skip right on up to
reach the super class’s method and call it instead, or even
along with the class’s own version.
For example, lets say your company makes computer
monitors. Every monitor has specific behaviors when turned
on. No matter what the make or model, every monitor will
degauss when turned on, but only model 86B will auto-adjust
brightness. Because of this, when turned on, 86B models will
not only perform normal monitor behaviors, but also its own.
As classes in Actionscript, they would be set up in the
following manner.
- // basic monitor class
- Monitor = function(size, res){
- this.screenSize = size;
- this.nativeResolution = res;
- this.powerIsOn = false;
- };
- Monitor.prototype.turnOn = function(){
- this.powerIsOn = true;
- this.degauss();
- };
- Monitor.prototype.degauss = function(){
- trace("Degaussed");
- // degauss here etc.
- };
- // class for a model 86B monitor
- Model86B = function(size, res){
- // model 86B uses same definition as
- // its monitor super class
- super(size, res);
- };
- // setup inheritance with Monitor class
- Model86B.prototype = new Monitor();
- // add a unique turn on method for model86B instances
- Model86B.prototype.turnOn = function(){
- // using this.turnOn would run this function
- // but we need the super class turnOn to run
- // so super allows access to that acting as a
- // reference to the super class prototype
- super.turnOn();
- this.adjustBrightness();
- };
- Model86B.prototype.adjustBrightness = function(){
- trace("Adjusted brightness");
- // adjust brightness here etc.
- };
- // make an 86B instance and turn it on
- demoMonitor = new Model86B(17, [1024,768]);
- demoMonitor.turnOn(); // traces "Degaussed" and
"Adjusted brightness"
As you can see, super here allowed a Model86B instance to
access its super class’s turnOn method in one of its own. So
as you can see, super is available not only in the
constructor call, but class methods as well.