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:
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).
The parent class defines getPerimeter() as:
public int getPerimeter() { return 2 * ( height + width ) ; }In the child class, we redefine getPerimter() as:
public int getPerimeter() { return 2 * ( super.getHeight() + super.getWidth() + 4 ) ; }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.
public static void main( String [] args ) { Rectangle r = new Rectangle( 3, 5 ) ; FramedRectangle f = new FramedRectangle( 3, 5 ) ; System.out.println( "r's perimeter is: " + r.getPerimeter() ) ; System.out.println( "f's perimeter is: " + f.getPerimeter() ) ; }This prints out:
r's perimeter is 16 f's perimeter is 24If 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.
foo.doSomething() ;Assume foo has type Foo.
The simple rule for deciding which doSomething() gets run is the following.
The problem of which version of doSomething() gets a little more complicated, and we'll see how it's resolved in the next section.