Incremental Java
Overriding Methods

Extending a Class

Suppose you have a class. This could have been written by you,
or it could have been written by someone else. You like the class.
It does what you want, mostly.

But you want to add some new methods to it, or new instance variables,
or both. You may even want to change the way the methods in the
class behave.

If these are the kinds of changes you want to make, then you
don't have to rewrite a new class. Instead, you can extend
the class by writing a child class. This is what inheritance is
about. It's about reusing code, instead of writing it again from
scratch.

When you write a child class, you can make the following changes:

add new methods

add new instance variables

change methods from parent class (only in method body, not
in signature)

You inherit the following from the parent class.

parent class instance variables

parent class methods

This means, the child class has all of the public methods
that the parent class has. It has all of the instance variables.
The only unusual aspect is that, within child class method definitions,
you can't directly access parent class instance variables. For
example, if the parent had a height instance variable,
child class method definitions wouldn't be able to access this
directly.

The instance variable is there, but the only way to access
it is through the public methods of the parent class. (The other
way is to make the instance variables of the parent class public,
but in general, this is not an option. If someone else did write
the parent class, you won't be able to modify it, in most
cases).

Overriding Parent Class Method

Suppose we wanted to write a child class of Rectangle.
This class is called FramedRectangle. You can set the height
and width as usual, but there is a frame of length 1 all the way
around the Rectangle object. For example, if the width was
7 and the height was 4, then with the frame, the total width is 9
and the total height is 6 (the frame adds 2 units to the width and height).

We have overriden the getPerimeter() method from the
parent class. To override it, we must have the identical
method signature, but put in a new method body.

super is a way for us to call the method from the
parent class (which is also called the superclass).
We can leave super off, and just use getHeight()
and getWidth(). However, this may cause problems
if we also override the getHeight() and getWidth()
method in FramedRectangle.

We assume the getHeight() method in FramedRectangle
adds 2 to the height from getHeight() method in
Rectangle. For example:

public int getHeight()
{
return super.getHeight() + 2 ;
}

By calling super.getHeight(), we use the version provided in
Rectangle, rather than the one that's defined in
FramedRectangle.

If we hadn't overridden getPerimeter() in FramedRectangle,
it would have printed out 16 in both cases, because FramedRectangle
would use the getPerimeter() defined in Rectangle.

Picking Methods

Suppose you have the following method call:

foo.doSomething() ;

Assume foo has type Foo.

The simple rule for deciding which doSomething() gets
run is the following.

Check if doSomething() is defined in class.

If not, check if it's defined in the parent class.

If not, check if it's defined in the parent of the parent class.

And so forth

Basically, you check to see if your class defined this method,
if not, you go up to your parent, parent's parent and so forth.
All of these classes are your ancestor classes. If none of your
ancestor classes define doSomething(), then the Java compiler
prints an error message. It must be defined in some ancestor class.

The problem of which version of doSomething() gets a little
more complicated, and we'll see how it's resolved in the next section.