In the previous lesson you learnt about overriding.
Abstract classes and methods
Now that you have created three subclasses of Animal
you might like to consider what is meant by "animal": does it ever make sense to instantiate an Animal
object that isn't a specific type of animal? It seems natural to think that "animal" is in fact an abstract concept. In real-world terms, every animal in existence is a specific type of animal, and it is not possible for any animal to be born without it being a specific type.
Java lets you model this concept by marking classes as abstract. Once you do this, it is no longer possible to instantiate an object of type Animal unless you specify its actual type. Change the class declaration within Animal
as follows:
public abstract class Animal {
If within VirtualZoo
you still have lines which instantiate using new Animal
, you will find they now give rise to an error message:
// The following will no longer work... Animal animal1 = new Animal(“Fred”, “m”, 2); // But these will work fine because a subclass of Animal is created Animal animal2 = new Lion(“Leo”, “m”, 8); Animal animal3 = new Penguin(“Oswald”, “m”, 3); Animal animal4 = new Monkey(“Bonzo”, “f”, 5);
You have now successfully prevented client objects from creating an Animal
object without specifying which specific type of animal it is.
It is often the case with abstract classes that there is some functionality which will differ for each subclass but which has no sensible default. An example for animals would be their favourite food; unlike the isEndangered()
method where it was assumed that the animal was not endangered unless specifically overridden, there is no obvious foodstuff that can serve as a sensible default.
With abstract classes this presents no problem; simply define an abstract method. Insert the following inside the Animal
class:
public abstract String favouriteFood();
Note the following:
- The
abstract
keyword specifies that this method is abstract; that is, it has no default processing. - There is no method body and hence no braces – the method declaration ends with a semi-colon.
- Only classes declared to be abstract are allowed to have abstract methods.
- Subclasses must override the method to supply the missing body (unless the subclass is also abstract).
In the Lion
class, override this method by inserting the following:
@Override public String favouriteFood() { return "meat"; }
In the Penguin
class, override this method by inserting the following:
@Override public String favouriteFood() { return "fish"; }
In the Monkey
class, override this method by inserting the following:
@Override public String favouriteFood() { return "banana"; }
In the next lesson we will tidy up the Animal
constructors.