Inheritance


Real programmers always confuse Christmas and Halloween because Oct31 == Dec25.
       --Andrew Rutherford


Recall
:



Inheritance - what is it?



The "is a kind of" relationship: allows you to define properties and behaviors common to a general class, such as the Animal class - and then inherit these properties in the Animal specializations/subclasses (the Kangaroo, Dog, Cat, Bird classes). So you only have a single copy of these properties, in the superclass. If you had multiple copies of this code, corrections to the code would be made to each copy.



Note: Class Specialization, or inheritance, is a common way of evolving existing object structures. It allows the programmer to re-use previously written code. But specialization should be used with care.



That is: Exercise Caution when creating Inheritance Hierarchies...







Killer Kangas - An "Object" Lesson




Project:  Australian air force - virtual reality simulator for helicopter combat training




Oops! Is a kangaroo "a kind of" soldier??

Lesson?

Possible Solution?






Note about Accessing Instance Variables

When we are writing instance methods for a class (say, class Thing), we can directly access instance variables for any object of type Thing, without using accessor/mutator methods.

Example:
public class Thing {
    private int IDNumber;

    ...
    public boolean compare(Thing two) {
        if(IDNumber == two.IDNumber) {
        ...
        }
    }
}

Note: Since two is of type Thing, we can access two's IDNumber field directly inside the Thing class, without using the accessor method.





Subclasses and Superclasses



Before creating a subclass, ask: Does the inheritance relationship work?
A subclass object "is a kind of" superclass object.


Subclass syntax:
public class <name> extends <parentName> {
    ...
}

Example:
public class Square extends Rectangle {
    ...
}

Syntax for invoking a constructor in the superclass:
super(<argument(s)>);

Example:
public class Square extends Rectangle {
  public Square(double side) {
    //execute the Rectangle constructor with 2 args:
    // width and height inst. vars set to side
    super(side, side); // must be 1st statement
...
}



Polymorphism



polymorphism:
the ability for the same code to be used with different types of objects and behave differently with each.


Example:
System.out.print() prints any type of object. Each object is displayed in its own way.


Recall: The Person class, and its UTStudent subclass

public class Person {
    private String name;
    private int age;
    private String SSN;

    public Person(String name, int age) {
       this.name = name;
       this.age = age;
    }

    public void play() {
       System.out.println("Out having fun...");
    }

    public void talk() {
       System.out.println("Hi!");
    }
}

public class UTStudent extends Person {
    // don't repeat inherited data here - UTStudent objects have name, age, SSN fields
    private String UTEID;
    private String[] classSchedule;
    private double fees;

    public UTStudent(String name, int age) {
       super(name, age); // invoke superclass constructor
    }

    public void study() {
       System.out.println("I'm in the lab writing Java code...");
    }

    public void talk() {
       System.out.println("Hi, Java spoken here...");
    }
}





Now consider some client code:

public class StuffWithPeople {
    public static void main(String[] args) {
       Person p1 = new Person("John Doe", 30);
       Person p2 = new UTStudent("Jane Doe", 19);
       // Any methods in Person class can be called on p1 and p2.
       // You cannot call methods in UTStudent class on p1 or p2.

       p1.talk(); // p1 behaves like a Person
       p2.talk(); // p2 behaves like a UTStudent
    }
}

When a method is called on p2, it acts like a UTStudent.


Output:
Hi!
Hi, Java spoken here...






Abstract Classes



As you move upwards in an inheritance hierarchy:


Example
: Electronic message system
3 classes needed: TextMessage, VoiceMessage, FaxMessage


A mailbox contains messages of all 3 types, so we access them through references to a general parent class called
Message.


Move common operations to the Message class: for example, all messages (TextMessage, VoiceMessage, FaxMessage) have a play() method.
But how do you implement play() in the parent class? You cannot.



public abstract class Message
{
    private String sender;

   public Message(String from)
   {
       sender = from;
   }

   public abstract void play(); // This method cannot be defined in
                                                   //this class.

...

 
}


Example:

Message myMsg = new VoiceMessage("greet.au");





Example:
class TextMessage extends Message
{
   public TextMessage(String from, String text)
   {
       super(from);
       this.text = text;
   }

   public void play()
   {
        System.out.println(text);
   }

   private String text;
}



Interfaces



An interface:


Syntax for interface definition:
public interface <InterfaceName>
{
    // constants - All variables in an interface are explicitly or implicitly
    // public class constants (that is, public static final)


    // method declarations - all methods are explicitly or implicitly public
    //and abstract

}


Syntax for class implementing an interface:
public class <className> implements <InterfaceName> {
  ...
}



Differences - Interfaces and Abstract Classes



Question:
How does an interface differ from an abstract class?

You can: declare variables to be of an interface type, you can declare arguments and return types of methods to be an interface type.


An interface looks like a purely abstract class (that is, a class with only abstract methods).


Example:

interface EngineDriven
{
    boolean startEngine(); // methods do not have to be
                          //declared abstract - they are automatically abstract

    void stopEngine();  //methods do not need to be declared
                         //public - they are automatically public

    float accelerate(float acc);
    boolean turn(Direction dir); // Direction is a class
}


Example:
A class that implements all of EngineDriven's methods declares that it implements the interface.

class Automobile implements EngineDriven
{
  ...
    public boolean startEngine()
    {
       if(notTooCold)
           engineRunning = true;
    }

    public void stopEngine()
    {
        engineRunning = false;
    }

    public float accelerate(float acc)
    {
       ...
    }

    public boolean turn(Direction dir) {....}
}

Other classes that might implement EngineDriven?
LawnMower, MotorizedScooter



The interface defines a new type - EngineDriven. We can declare variables of this type and assign them any instance of an EngineDriven object:


Ex:
EngineDriven auto = new Automobile();
LawnMower mower = new LawnMower();
EngineDriven vehicle;

vehicle = auto;
vehicle.startEngine(); // execute startEngine() from Automobile class
vehicle.stopEngine(); // execute stopEngine() from Automobile class

vehicle = mower;
vehicle.startEngine(); // execute startEngine() from LawnMower class
vehicle.stopEngine();  // execute stopEngine() from LawnMower class


Since Automobile and LawnMower both implement EngineDriven, objects auto and mower are considered to be of type EngineDriven.