Objects+(part+2)

You know the basics for creating objects, but there are some advanced techniques such as //inheritance, composition// and //interface//. You won't need to use these for a while, but you should be familiar with them in case you come across them.

**Inheritance** There is a way to define a new class based on another class. If we already have an old class that approximately does what we want and we just need to add a few extras, we can use //inheritance//. The original class is called the //super class// and the new class which //extends// the super class is called the //sub class.// Let's make a //sub class// of Car called //Prius://

code format="actionscript3" package edu.nu.sesp {   public class Prius extends Car {

private var _isUsingElectric:Boolean;

public function Prius {           super; _isUsingElectric = true; }

override public function set speed(value:Number):void{ if(value < 30){ _isUsingElectric = true; }else if(value >= 30){ _isUsingElectric = false; }           super.speed = value; }

public function get isUsingElectric:Boolean{ return _isUsingElectric }

} } code Notice the phrase: "//Prius extends Car"//. That's how we tell Flash that we want Car to be the super class of Prius. Prius extends Car, so it also //inherits// all of Car's functions as well. For example we could do: code format="actionscript3" var myCar:Prius = new Prius; var currentlyElectric:Boolean = myCar.isUsingElectric    // sets currentlyElectric to true; myCar.speed = 55;                                        // _speed is now 55

code You can see that Prius inherits the speed setter from Car. Prius also has it's own isUsingElectric getter that we added in Prius's class definition.

In the current version of Prius, we didn't change how Car's speed setter worked. But we can change the behavior of the speed setter for the Prius if we want to: code format="actionscript3" package edu.nu.sesp {   public class Prius extends Car {

private var _isUsingElectric:Boolean;

public function Prius {           super; _isUsingElectric = true; }

override public function set speed(value:Number):void{ if(value < 30){ _isUsingElectric = true; }else if(value >= 30){ _isUsingElectric = false; }           super.speed = value; }

public function get isUsingElectric:Boolean{ return _isUsingElectric }

} } code Now, look what happens: code format="actionscript3" var myCar:Prius = new Prius; var currentlyElectric:Boolean = myCar.isUsingElectric;   // sets currentlyElectric to true myCar.speed = 55;                                        // _speed is now 55 and _isUsingElectric is now false currentlyElectric:Boolean = myCar.isUsingElectric;       // sets currentlyElectric to false code So not only does Prius get methods from Car, it can also //override// the behavior of those methods.

**Composition** In practice, inheritance can get complicated and lead to weird behavior. An alternate approach is to use //composition.// Here's what Prius would look like if we used composition rather than inheritance:

code format="actionscript3" package edu.nu.sesp {   public class Prius {

private var _isUsingElectric:Boolean; private var _car:Car;

public function Prius {           _car = new Car; _isUsingElectric = true; }

public function set speed(value:Number):void{ if(value < 30){ _isUsingElectric = true; }else if(value >= 30){ _isUsingElectric = false; }           _car.speed = value; }

public function get speed:Number{ return _car.speed; }

public function get isUsingElectric:Boolean{ return _isUsingElectric }   } } code Here, the Pruis //wraps// an instance of Car rather than extending car. Often composition will lead to a cleaner more understandable design. In some cases however, you must use inheritance. You'll learn more about when to use each in the future, but just know that inheritance and composition are two approaches to accomplishing the same thing, each with their own advantages and disadvantages.

**Interfaces** Inheritance is useful because you can substitute one type of object for a subclass of the object. For example (if Prius extends Car): code format="actionscript3" var myCar:Car;

//You can set myCar to be a new Car and use its speed getter myCar = new Car; myCar.speed = 55;

// You can set myCar to be a new Prius and use its speed getter // This is OK because myCar's type is Car, and Prius extends that type myCar = new Prius; myCar.speed = 55; code If Prius does not extend Car, then saying: //myCar = new Prius;// will throw an error.

Being able to substitute one type of object for another may not seem like a big deal, but it is absolutely essential for working with pre written code. For example, suppose you have a class called GasStation with a function: //wash(aCar:Car):void{}//. This function was designed to take a Car as input. But if you try to give GasStation.wash a new class like Prius, it will throw an error. However, if you make Prius extend Car, then GasStation.wash will take a Prius.

But what happens if you use composition? If Prius wraps Car rather than extends Car, you won't be able pass a Prius to GasStation.wash. A better way to write these classes is to use (programming) interfaces (which are different from graphical user interfaces). Here is what an interface looks like in Flash:

code format="actionscript3" package edu.nu.sesp{

public interface ICar{

function set speed(value:Number):void;

function get speed:Number;

} } code This interface says that whatever classes decide to //implement// this interface must have a getter/setter for speed.

Next, you would then have Prius //implement// the interface: code format="actionscript3" package edu.nu.sesp {	public class Prius implements ICar {

private var _isUsingElectric:Boolean; private var _car:Car;

public function Prius {			_car = new Car; _isUsingElectric = true; }

public function set speed(value:Number):void{ if(value < 30){ _isUsingElectric = true; }else if(value >= 30){ _isUsingElectric = false; }			_car.speed = value; }

public function get speed:Number{ return _car.speed; }

public function get isUsingElectric:Boolean{ return _isUsingElectric; }

} } code

And you would have Car implement ICar as well: code format="actionscript3" package edu.nu.sesp {	public class Car implements ICar {		private var _speed:Number;

public function Car:void{ _speed = 0; }

public function set speed(value:Number):void{ if(value >= 0){ _speed = value; }		}

public function get speed:Number{ return _speed; }

public function stop:void {			_speed = 0; }	} } code Finally, you would write the wash function so that it doesn't take a Car or a Prius, but an ICar instead, like: //function wash(aCar:ICar):void{...}.//

In practice, if someone is writing a CarWash class, they will also write the ICar interface. Then, other people who want to use the CarWash class will write their own classes that implement the ICar interface. Classes are allowed to implement multiple interfaces (but can only extend one super class) so interfaces are a very nice way to write generalizable code.