You are on page 1of 6

School of Computer Science, University of Birmingham

Java Lecture notes. M. D. Ryan. October 2001.

What is inheritance

8: Inheritance

A way of defining a new class in terms of


an old one.
Idea: class B is like the existing class A,
except with the following differences: . . .
We can add new variables and methods and
also override the behaviour of existing
methods.
We say that class B extends A.
Class B inherits the properties of A.

Recall the objectives of OOP

Defining a Subclass

To try to deal with the complexity of programming


To apply principles of abstraction in order to simplify
the tasks of writing, testing, maintaining and
understanding complex programs
To increase code reuse
to reuse classes developed for one application in
other applications instead of writing new programs
from scratch.
Inheritance is a major technique for realising these
objectives

public class Cat


{
public void kick(){
System.out.println(Meeeooowww!);
}
public void stroke(){
System.out.println(Purr. Puurrr.);
}

A.java
public class A
{
...
}

B.java

A is the original superclass


B is the new subclass
B inherits (or extends) A
B is derived from A
B is everything A is and more
a B object is also an A object

public class B extends A


{
... extra new features ...
}

A cylinder is like a circle, but


with an extra length
r
r
l

}
public class Lion extends Cat
{ //Override the kick behaviour
public void kick(){
System.out.println(RoooAAARRWW!);
}
}
//Lion also inherits the stroke method

The circle method findCircumference


is still valid for cylinders.
The circle method findArea will have to
be changed if we want to find the whole
surface area, but still, the old method is
useful.

public class Circle


{
private double radius;

public class Cylinder extends Circle


{
private double length;

public Circle(double r) { radius = r; }


public Circle() {this(1.0); }

public Cylinder(double r, double l) {


super(r);
length = l;
}

public double getRadius() { return radius; }


public Cylinder() {
this(1.0,1.0);
}

public double findCircumference() {


return 2*Math.PI*radius;
}

public double getLength() {


return length;
}

public double findArea() {


return radius*radius*Math.PI;
}
}

continued...

continued from prev. slide

Points to note

public double findArea() {


// overrides findArea in Circle
return 2*super.findArea()
+ findCircumference()*length;
}

The subclass adds variables and methods to


what it inherits from the superclass.
It may also call methods and constructors
from the superclass.
It may redefine methods rather than
inheriting them from the superclass.

public double findVolume() {


return super.findArea()*length;
}
}

findArea overrides the findArea in Circle: it


returns the total surface area of the cylinder.
findVolume uses super.findArea to find the area
of the cross-section.

Derived classes: a class hierarchy


the Object class is very
general, having just the
methods equals and
toString (they are
normally overridden)

Object

Person

Circle

Cylinder

Student

Employee

Lecturer

Secretary

method overriding.

It can also redefine variables


variable shadowing.

this and super


this refers to the executing object.
this.varName is used to disambiguate a reference
to a variable in the class, when there is a method
variable also called varName.
this() is used in a constructor to call a constructor
with a different signature.
super is used similarly, to refer to the superclass.
The first thing a constructor in a derived class does is
call a constructor in the base class:
super().
It does this whether you write it or not.

Example: car behaviour

public class Car


{
public static final double SPEEDLIMIT = 7;
private double speed;
protected Color color;

We want to model cars as follows:

Car() { speed = SPEEDLIMIT; color = Color.black;

Black cars are rational (normal).


Blue cars are also rational, but a bit slow.
Red cars like to drive fast, but they break
sharply when too close to the car in front.
Green cars slow down at random, to admire the
countryside.

public double getSpeed() { return speed;

public void setSpeed(double s) {


if (s>=0 && s<=SPEEDLIMIT+2)
speed=s;
//Speed limit not strictly enforced
}
public void update(int d) {
double s = speed;
s+= 0.05*(SPEEDLIMIT-s); // try to go a little faster
if (s >= d) s=d-1; // but avoid crashing into car in front
setSpeed(s);
}
}

public void updateRoad()


{
int distahead=99999;
//Treated as infinity, no car in front

Overriding Cars Behaviour

//Update positions of cars based upon distance to next car ahead


for (int i=road.length-1; i>=0; i--) {
if (road[i]!=null) {
//Update the cars speed
road[i].update(distahead);

Car

//Move to new position on road


int newpos = i+(int)road[i].getSpeed();
if (newpos<road.length) road[newpos] = road[i];
if (newpos!=i) road[i]=null;

BlueCar

RedCar

GreenCar

distahead=0;
}
else distahead++;
}
//Add a new car to road
if ( road[0]==null && r<arrivalprob )
road[0] = getNewCar();
}

// blue cars have lower max speed


public class BlueCar extends Car
{
BlueCar() {
// super(); // this is implicit
color = Color.blue;
}

// red cars tend to drive fast, but


// break sharply when close to car in front
public class RedCar extends Car
{
RedCar() {
color = Color.red;
}
public void update(int d)
{
double s = getSpeed();
// try to go a lot faster
s+= 0.1 * (SPEEDLIMIT+3-s);

public void update(int d)


{
super.update(d);
// blue cars have lower max speed
if (getSpeed() > SPEEDLIMIT-3)
setSpeed(SPEEDLIMIT-3);
}

// if near car in front, break sharply


if (d < 8) s -= 3;
// avoid crashing into car in front
if (s >= d) s=d-1;
setSpeed(s);

}
}
}

// Green cars slow down to admire scenery.


// With probability .01 they into a phase of slowing down over 12 cycles
public class GreenCar extends Car
{
private int slowdown=0; // counts cycles during slowdown phase
private final double SLOWSPEED = 0.2*SPEEDLIMIT;

private Car getNewCar() {


// pick a random number between 0 and 20
double rand = 20*Math.random();

GreenCar() { color = Color.green; }


public void update(int d) {
super.update(d);
// if not already in slowdown phase, consider entering it
if (slowdown==0 && getSpeed()>6
&& Math.random()<0.05) slowdown = 12;
// if in slowdown phase, slow down towards SLOWSPEED
if (slowdown>0) {
if (getSpeed()>SLOWSPEED)
setSpeed(SLOWSPEED);
slowdown--;
}
}

if (rand<1.0) return new RedCar();


else if (rand<2.0) return new BlueCar();
else if (rand<3.0) return new GreenCar();
else return new Car();
}

Casting objects
It is always possible to convert a subclass to a
superclass. In this case, explicit casting can be omitted.
For example,
Circle myCircle = myCylinder

is equivalent to

Casting from
superclass to subclass
Explicit casting must be used when casting an object
from a superclass to a subclass. This type of casting
may not always succeed.
Cylinder myCylinder = (Cylinder)myCircle;

Circle myCircle = (Circle)myCylinder;

What is the "type" of a derived class?


Derived classes have more than one type
Of course they have the type of the derived class (the
class they define)
They also have the type of every ancestor class
all the way to the top of the class hierarchy

All classes derive from the original, predefined


class Object
In the cars example, all cars are of type Car
(even those of type RedCar, etc).

Polymorphism
Polymorphism (or generic programming) is a technique
that allows a single piece of code to be reusable with
many different types.
Cat clarence = new Cat();
if (Math.random>0.5)

clarence = new Lion();

//The clarence variable is of type Cat


c.kick(); //But this may kick a Cat or Lion object

Which method is called is decided at runtime, not


compile-time.

Polymorphism - Example
Object[] myobjects = new Object[4];
//Fill the array with objects
myobjects[0] = new Fraction(3,4);
myobjects[1] = new Employee();
myobjects[2] = new Cylinder();
myobjects[3] = Java;

Polymorphism - Example
public static void printArray(Object[] objects)
{
for (int i=0; i<objects.length; i++)
{
Object o = objects[i];
System.out.print(Item at + i + :);

//Calls each objects toString method


//to print the contents of the array
printArray(myobjects);

printArray also accepts arrays of type String[],


Fraction[] or arrays of any class derived from
Object.

private / public / protected


private instance variables from the parent class are
not available by name in derived classes.
"Information hiding" says they should not be.
use accessor methods.
private methods are not inherited!
use public to allow methods to be inherited.
only helper methods should be declared private.
protected means available to subclasses.

if (o==null)
System.out.println(null);
else
System.out.println( o.toString() );
}
}

The final modifier


A final class cannot be extended:
final class Math
{...}

A final variable is a constant:


final static double PI = 3.14159;

A final method cannot be overridden by

its subclasses.
public final void update(int d);

The abstract modifier


The abstract method
Method signature without implementation, intended
to be implemented in subclass.
Useful to ensure that objects of subclass can call the
method.

The abstract class


A class must be declared abstract if any of its
methods are abstract.
Cannot be instantiated
Should be extended and implemented in subclasses

The instanceof Operator


Use the instanceof operator to test whether an
object is an instance of a class:
Circle myCircle = new Circle();
if (myCircle instanceof Cylinder)
{
Cylinder myCylinder = (Cylinder)myCircle;
...
}

Numeric wrapper classes

The Integer class


and the Double class

Boolean

Constructors

Character
Short

Class constants MAX_VALUE, MIN_VALUE

Byte
Integer

Conversion methods

Long
Float
Double

Multiple inheritance?

Interfaces

class

"extends"
"implements"

interface
Comparable
class

Geometric
class

Comparable
interface

Geometric
class
Circle

Cylinder

Circle

Comparable
circle

Cylinder

Comparable
cylinder
Comparable
circle

An interface

Using interfaces

Objective: Use the generic sorting method


defined in the Comparable interface to
sort an array of circles in increasing order of
their radii and an array of cylinders in
increasing order of their volumes.

Comparable
cylinder

public interface Comparable


{
public static final int LESS = -1;
public static final int EQUAL = 0;
public static final int GREATER = 1;
public int compare(Comparable otherObject);
}

You might also like