11. Inheritance Calls II

When a method is overridden, it can be tricky to figure out which method is called. We give an example to show why it is not possible to call the non-overriden method.

Question: is it possible to call a superclass’s method of class M directly in your code (outside of the class M)?

Motivating Question

Is there a way to find out that liam in the example below is really 16 and not 21? See marked point (1). Why or why not?

public class Kid {
    public int age() { return 16; }
}
public class Liar extends Kid {
    public int age() { return 21; }
}
public class Tester {
    public static void demo() {
        Kid liam = new Liar();
        liam.age(); // returns 21
        // (1) ??
    }
}

Discussion

In the example above, it seems reasonable to hope that you could find out Liam’s true age. The overriding of age in Liar isn’t changing anything fundamental about the Kid. This is actually not possible in Java.

Overriding does not always occur just to hide behavior. An example where there are more permanent changes can help you see why overriding is necessary.

Important Examples

One way we talk about inheritance is in terms of biological relations, like mammal and human. In biology, evolutionary descendants usually gain functions, but sometimes functionality is lost or altered beyond recognition.

Java lets us change the behavior of methods by overriding them. When a method refers to lost functionality, it will need to be overridden in order to make sense. Once the functionality is gone, calling the “superclass method” no longer makes any sense.

I hope these examples convince you that whenever a method of an object is invoked, the overridden version should be called. (No matter what the context.) The argument is that the original (non-overridden) method might be completely inappropriate to use in a subclass.

Here are two related examples. The first one is good. The second one seems more of a stretch.

  1. Snakes are tetrapods, so from an evolutionary point of view their ancestors had four legs. Snakes they have lost their limbs. The “flee” method of an ordinary tetrapod involves quickly moving all four legs. The “flee” method of a snake has nothing to do with moving legs, so the Tetrapod “flee” method is overridden in the Snake class to involve slithering.

    This is significant because it makes no sense to call the Tetrapod flee method; it should not even be allowed. That method refers to parts that have disappeared in the course of evolution (subclassing).

  2. Tetrapods are an evolutionary step between fish and fully land-dwelling life. Fish can breathe in water but not air. Most modern tetrapods, like birds, breathe only air. Somewhere along the evolutionary tree, birds lost their ability to breathe in water. For the ancestors of fish, the breathe() method worked in the water. For modern tetrapods like birds, the breathe() method works in air, so this overrides the old breathe method. It is no longer possible to use the Fish breathe() method in the Bird subclass because that ability has changed completely; only the overridden method makes sense. (Of course the idea that birds would be a subclass of fish is ridiculous, but I hope the idea of the example helps.)

Last modified August 18, 2023: 2022-2023 End State (7352e87)