GNU Java Training Wheels 1.1: Tutorial 15 Introducing inheritance

Next: Tutorial 16 More inheritance, Previous: Tutorial 14 Linked lists, Up: J.T.W. Tutorials [Contents][Index]

### 4.15 Tutorial 15 Introducing inheritance

#### 4.15.1 Basic Inheritance

When you see the following code: `class` `X` extends `Y`, it means that `class` `X` inherits from the `class` `Y`. Class `X` is called the subclass and the `class` `Y` is called the super-class or sometimes the parent `class`. When the class `X` extends from `Y`, it pulls in all of the non-private methods and properties from the super-class Y. Inherited methods can override the behaviour of that same method in the super-class to give behaviour that is specific to the subclass. The concept of methods overriding other methods is called dynamic method binding or more commonly the more impressive-sounding name: polymorphism. The main thing that this tutorial shows is the idea that inheritance is a non-symmetrical relationship. For example: in the code that follows, the Bird class inherits from the Animal class, which corresponds to the idea that every bird is an animal. The reverse, every animal is a bird is plainly not true! Inheritance forces you to recognize this.

Question 4.15.1: Study, compile and run the following code. The following code shows how inheritance works. In the following code, the `Bird` `class` inherits from the `Animal` `class`. The `Bird` `class` pulls in the Animal class’s `age` property and the `canFly` and `talk` methods. Importantly the `canFly` property overrides the behaviour of the canFly method of the parent Animal class, which reflects that fact that generally speaking, birds can fly. In the code that follows, note that int properties are initialized to zero by default and the super method (also known as the constructor of the super-class) is called by default if there is a zero parameter constructor in the super-class, which there is by default, even if you don’t write one!

    class Animal
    begin

        property int age;    // Animal's age in years
        property int health; // Animal's health in hit points

        constructor Animal()
        begin
            age    = 0; // NOTE: not needed as set by default
            health = 100;
        end

        method boolean canFly()
        begin
            return false;
        end

        method void talk()
        begin
            System.out.println("Hello");
        end
    end

    class Bird extends Animal
    begin

        property double flySpeed;) // Bird's speed in km/h

        constructor Bird()
        begin
            super();      // NOTE: not needed as called by default
            flySpeed = 0; // NOTE: not needed as set by default
        end

        method boolean canFly()
        begin
            return true;
        end

        method void peck()
        begin
            System.out.println("peck");
        end
    end

    class InheriTest
    begin
        beginMain
            var Bird eagle = new Bird();
            eagle.talk();
            eagle.peck();
        endMain
    end

Question 4.15.2: Override the talk method of the Animal class in the Bird class to print out “Tweet Tweet!” rather than “hello” to give more accurate talking of bird objects.

Question 4.15.3: By copying the pattern established in the Bird class, change the eagle from an instance of the Bird class to its own class in its own right and then create an instance of that class in the `main` `function` of InheriTest. Your Eagle class should have one `property`: `int numberOfKills` and one `method`: `void attack()` that internally increments the value of `numberOfKills`. In the `main` `function` you should call every method of the Eagle class and its super-classes.

Question 4.15.4: What is the advantage of using a new separate class to represent a new object rather than using an instance of an existing class?

Question 4.15.5: Create a new `class` `Kiwi` that inherits from the `Bird` `class`. Your `Kiwi` `class` should override the `canFly` method to return `false`, which reflects the fact that generally speaking birds can fly, but the kiwi bird in particular does not fly. Your `Kiwi` `class` have a `property` `numberOfWorms`. Once you have written the `Kiwi` `class` you should create an instance of the `Kiwi` `class` in the `main` `function`.

Question 4.15.6: Why does the following line of code in the `main` `function` print out 100 but there is no setting of that variable to that value in the Kiwi class?

    System.out.println(k.health);

Question 4.15.7: In the classes `Animal`, `Bird`, `Eagle` and `Kiwi`, remove all of the `canFly` methods and replace it with a single `canFly` property of the Animal class. In the constructors you will need to set the value of the `canFly` `property` to a value that is appropriate for that class. For example in the `Bird` class’s constructor you should set the `canFly` `property` to `true`, while in the `Kiwi` `class`’s constructor you should set the `canFly` `property` to `false`.

Question 4.15.8: What is the advantage of having a `canFly` `property` over a bunch of `canFly` methods?

There is an equally valid alternative to having a `public` `property` in the `Animal` `class` and that is to have in the `Animal` `class` a `private` `property` `canFly` and a pair of methods for getting and setting the value of the `canFly` property like so. These methods in J.T.W. and Java are called getter methods and setter methods since, as their names suggest, getters are used for getting the value of something and setters are used for setting the value of something. Nore that the `canFly` `method` of the code above corresponds to `getCanFly` `method` in the code below.

    private property boolean canFly;

    method boolean getCanFly()
    begin
        return canFly;
    end

    method void setCanFly(boolean aCanFly)
    begin
        canFly = aCanFly;
    end

You might think that it is simpler to have one thing (a single non-private property) rather than three things (a private property and a non-private getter method and a non-private setter method) and you would be right. However from the point of view of the client code that uses the Animal `class`, the two approaches are identical. Later on when you learn more you will understand under what circumstances the second getter and setter approach is better.

Question 4.15.9: Change the `main` `function` to what follows:

    beginMain
        var Bird b = new Bird(10);
        var Animal a = b;
        a.talk();
        a.peck();
    endMain

When you compile this code it gives a compilation error. What line gives the error and what is the reason for the error?

Question 4.15.10: Change the `main` `function` to what follows:

    beginMain
        var Animal a = new Animal();
        var Bird b = a;
        b.talk();
        b.peck();
    endMain

When you compile this code it gives a compilation error. What line gives the error and what is the reason for the error?

#### 4.15.2 Run-time type inquiry

In J.T.W. and Java there is a keyword called `instanceof` that does a run-time check on the type of an object. The following `function`:

    function void say(Animal a)
    begin
        System.out.println(a instanceof Bird);
    end

uses the `instanceof` keyword to determine the run-time type of the reference a and prints out whether or not the reference is referring to a `Bird` object. Some examples should clarify the situation:

- `say(new Bird())` prints `true`, Since the parameter a is pointing to a bird object at run-time,
- `say(new Animal())` prints `false` since not every animal is a bird,
- `say(new Eagle())` prints `true`, since every eagle is a bird, and
- `say(new Kiwi())` prints `true`, since every kiwi is a bird.
- ``var` Animal a = new Animal(); say(a);` prints `false` since at run-time a is not pointing to a bird object
- ``var` Animal a = new Bird(); say(a);` prints `true` since at run-time a is pointing to a bird object.

In Tutorial 17 you will learn why in most cases it is better to use polymorphism instead of the instanceof keyword for run-time type enquiry.

#### 4.15.3 The superclass of all objects

Every `class` in Java inherits either directly or indirectly from a `class` called `Object`. That is to say if `x` is a reference variable, then the run-time expression `x instanceof Object` is always `true` except for the pathological case where `x` is `null` (i.e. is currently pointing to no object). The `Object` `class` contains a method called `toString` that returns a string containing the run-time `class` name of the object concatenated with the hash code of the memory address of the object in base 16 (also known as hexadecimal) format. Since every `class` inherits from Object, every object can have `toString` invoked upon it. Even better, every `class` `X` can override `toString` to provide debugging information that is tailored to `X`. Therefore the `toString` `method` is convenient for debugging. Since the `toString` `method` is a `public` `method` of the `Object` `class` it must be overridden as a `public` method, since your overridden `function` cannot have weaker access privileges.

Next: Tutorial 16 More inheritance, Previous: Tutorial 14 Linked lists, Up: J.T.W. Tutorials [Contents][Index]