Java Inheritance

Resources

Video Script

Let’s review inheritance in the Java programming language. First, we’ll look at interfaces. In Java, an interface is as special type of class, so we’ll use the interface keyword instead of the class keyword when declaring it. Inside of the interface, we typically only include methods that we want to be part of the interface. Any methods included in the interface are automatically public and abstract so we don’t have to include those modifiers on your methods. Likewise, if we do include any attributes, they will automatically be treated as if the public, static, and final modifiers are attached. Finally, it is important to remember that Java interfaces cannot be instantiated, so we don’t include an instructor. In addition, the methods themselves are abstract and don’t contain any code.

Here’s a quick example of a Java interface called IMyQueue, which defines the traditional operations that can be performed on a queue data structure. As we can see, it just lists the methods, along with the return type and parameters. We don’t include the public or abstract keyword, but each of these methods are treated like public and abstract methods by Java.

Then, if we want to create a class that uses that interface, we list it in the class declaration after the implements keyword. Inside of that class, we have to include public methods that are implementations for each method defined in the interface. So, here we see the four methods defined by the interface!

Finally, we must remember that an interface in Java is a data type. So, even though we can’t directly instantiate the interface itself, we can declare a variable using the interface’s name as the data type, and then we’ll have access to any methods defined by that interface through that variable. This is handy if we wish to store several different objects, each instantiated from different classes, in the same list. As long as they all implement the same interface, we can use that as our data type and treat them similarly.

Now, let’s look at the more traditional form of inheritance in Java. Recall that we can declare a class to be a subclass of another class, usually referred to as the superclass. When we do that, the subclass includes, or inherits, all state and behavior defined in the superclass. In Java, any methods or attributes marked with the public or protected modifier are accessible in the subclass. Likewise, the subclass can use the super() method to access elements from within the superclass. This is typically used within the constructor of the subclass to call the constructor of the superclass. Finally, the subclass can choose to override any methods defined in the superclass with new code. We’ll see how that works later in this chapter.

So, here’s a quick example of three classes in Java that demonstrate inheritance. We have a superclass name Canine that defines the protected attribute name as well as the public method bark. Then, we create a subclass called Dog that inherits from Canine. So, it will have a name attribute and a bark method, but it also adds its own owner attribute as well as a new method called pet. Finally, the GuideDog method inherits from Dog, so it will include the name attribute from Canine as well as the owner attribute from Dog, and it adds its own trainer attribute.

Likewise, when we create an instance of a GuideDog, we can access all behaviors that are present in any of the superclasses as well as the class itself. So, an instance of GuideDog will have access to the bark, pet and guide methods. This is a great way to reduce the amount of repeated code between related classes. As we’ll learn in the example project for this module, this can greatly simplify our programs if we are able to take proper advantage of inheritance.

Finally, let’s discuss one other interesting topic - multiple inheritance. In Java a class can only be declared as a subclass of a single superclass, but it can implement multiple interfaces. So, when designing our programs, we’ll have to keep that in mind. Generally there are very few instances where we’d want to directly inherit from multiple classes, but it could happen. For example, if we have a class Teacher and a class Student, we might want to create an object called StudentTeacher that represents a person with both roles. In Java, however, we cannot do this through direct inheritance.

Instead, if we have a class called Person and interfaces for Student and Teacher that defines the behaviors of a teacher, we could create a subclass of Person that implements both the Student and Teacher behaviors. It is a subtle difference, but one we should be aware of.