Java Fundamentals  «Prev  Next»
Lesson 5Putting inheritance to work
ObjectiveBuild a hierarchy of classes using inheritance.

Build Hierarchy of Classes using Inheritance using Java

Building a hierarchy of classes using inheritance in Java SE 22 (or earlier versions of Java) follows these fundamental principles. Inheritance allows a class to acquire properties and behaviors (fields and methods) from another class, enabling code reuse and a natural representation of hierarchical relationships.
Steps to Build a Class Hierarchy Using Inheritance:
  1. Define the Base Class (Parent Class):
    • The base class (or super class) contains common fields and methods that child classes will inherit.
  2. Define Derived Classes (Child Classes):
    • A derived class extends the base class using the extends keyword.
    • The child class can inherit fields and methods from the parent class and add its own unique functionality.
  3. Override Methods:
    • Child classes can override methods of the parent class to provide specific behavior.
    • Use the @Override annotation to indicate the overridden method.
  4. Use super to Access Parent Class Members:
    • Use the super keyword to call parent class constructors or access parent class methods/fields.
  5. Establish Multilevel Inheritance:
    • A child class can also act as a parent class for another class. Java supports multilevel inheritance but not multiple inheritance with classes (to prevent ambiguity).
    • However, multiple inheritance is achievable with interfaces.


Example: A Class Hierarchy for Animals
// Base Class
class Animal {
    String name;

    // Constructor
    Animal(String name) {
        this.name = name;
    }

    // Method
    void eat() {
        System.out.println(name + " is eating.");
    }
}

// Derived Class 1
class Mammal extends Animal {
    // Constructor
    Mammal(String name) {
        super(name); // Call the parent class constructor
    }
    // Specific Method
    void walk() {
        System.out.println(name + " is walking.");
    }
}

// Derived Class 2
class Bird extends Animal {
    // Constructor
    Bird(String name) {
        super(name);
    }

    // Overriding Method
    @Override
    void eat() {
        System.out.println(name + " is pecking food.");
    }

    // Specific Method
    void fly() {
        System.out.println(name + " is flying.");
    }
}

// Test Class
public class Main {
    public static void main(String[] args) {
        Mammal mammal = new Mammal("Dog");
        mammal.eat();  // Inherited from Animal
        mammal.walk(); // Specific to Mammal

        Bird bird = new Bird("Parrot");
        bird.eat();    // Overridden method
        bird.fly();    // Specific to Bird
    }
}


Key Features in Java SE 22:
  1. Records and Sealed Classes:
    • Sealed Classes: Introduced in Java 15, these allow you to tightly control which classes can inherit from a parent class.
    • Example:
      public sealed class Shape permits Circle, Rectangle { }
      public final class Circle extends Shape { }
      public final class Rectangle extends Shape { }
              
  2. Interface Enhancements:
    • Interfaces can have default methods, static methods, and private methods, enabling more flexible behavior reuse.
  3. Pattern Matching for instanceof:
    • Simplifies the type checking and casting process when dealing with objects in hierarchies.

Tips for Building Effective Class Hierarchies:
  1. Encapsulation: Keep fields private and provide getter/setter methods to protect the data.
  2. Abstraction: Use abstract classes or interfaces to define common behaviors across unrelated classes.
  3. Avoid Overcomplication: Keep the hierarchy simple to avoid making the code difficult to maintain.
  4. Leverage Composition: When inheritance doesn't fit well, use composition instead (e.g., "has-a" relationships).

This approach ensures flexibility, clarity, and maintainability in your class hierarchies.


Class inheritance

For the record, the parent/child OOP metaphor is not just something I cooked up to make the course more entertaining. In truth, inheritance works very much like biological inheritance. In biological inheritance, a child inherits many of the physical and personality traits of its two parents. However, the child also develops its own unique traits that are present right alongside the inherited traits. This blend of old and new is what makes us all so unique as individual people. Some of us are more unique than others, but you get the idea. Although Java classes aren't nearly as unique as people, they do reap the same rewards from inheritance. One big difference is that only one class can be the parent of a child class in Java, which I suppose, makes Java an asexual programming language. I could be carrying this analogy a bit too far.
As you learned earlier in the module, inheritance involves creating a new class with the characteristics of an existing class, along with additional characteristics unique to the new class. The Object class[1] forms the root of the Java class hierarchy, which means that all classes in Java derive either directly or indirectly from it.

Class or an Object?

The concept of a class named Object might seem a little strange at first. As you learn a little later in the module, an object is just an instance of a class. The Object class is a very special class, however, because it serves as the base class for all Java classes.
If you were to make a Java family tree, the Object class would be at the top as the great-great-great grandparent of all classes.
This includes the classes in the Java API.
Inheritance in use
A class diagram that represents an inheritance hierarchy in object-oriented programming. Here's the detailed explanation:
Description of the Diagram
  1. Object Class (Yellow):
    • The topmost box in the hierarchy represents the Object Class.
    • It serves as the base class for all other classes in the diagram, indicating that every class is a subclass of the Object class.
  2. First-Level Subclasses:
    • There are two first-level subclasses:
      • Class A
      • Class B
    • These inherit directly from the Object Class.
  3. Second-Level Subclasses:
    • Class A has three direct subclasses:
      • Class AA
      • Class AB
      • Class AC
    • These are specialized versions of Class A, extending its functionality.
  4. Class B:
    • Class B does not have any subclasses shown in this diagram.

Interpretation of the Diagram
  • This diagram illustrates a simple inheritance structure where:
    • The `Object Class` is the root, representing the parent class from which all other classes derive. In many programming languages like Java, this reflects how every class implicitly or explicitly inherits from a universal object class.
    • Class A and Class B are derived classes of the `Object Class`, which means they inherit its properties and methods (if defined in a real-world example).
    • Class A has further subclasses (Class AA, Class AB, Class AC) to extend or modify its functionality.
    • Class B does not have any extensions, representing a leaf node in the inheritance tree.

Use Case for Such a Diagrams
This type of diagram is commonly used in object-oriented design to represent:
  • The generalization-specialization relationship between classes.
  • The structure of a class hierarchy in a system or software project.
  • The possible inheritance relationships and extensions in a design.

Example of Java Inheritance

Java Virtual Machine
This figure shows how inheritance is used in Java to form a hierarchy of classes. Some classes do not explicitly declare a parent class, in which case they are implicitly derived from Object. The Lion class in the previous lesson is a good example of a class that implicitly derives from Object. The extends keyword[2] is used to identify a class as the child of a parent class. The following code shows how the Lion class might explicitly derive from a class other than the Object class:
class Lion extends Predator {
  int energy;
  int aggression;
  boolean hungry;
  Color color;
  
  public Lion() {
   Lion(100, 15, false, Color.yellow);
  }
  
  public Lion(int e, int a, boolean h, Color c) {
   energy = e;
   aggression = a;
   hungry = h;
   color = c;
  }
} 


Predator is parent of Lion

The Predator class is identified as the parent of the Lion class, which means that the Lion class inherits all of the member variables and methods defined in the Predator class.
Keep in mind that at some point the Object class still serves as an indirect parent of the Lion class since all classes ultimately derive from Object. In this case the Predator class might derive directly from Object.
[1] Object class: The >Object< class is the class that forms the root of the Java class hierarchy. The >Object< class serves as the basis for all Java classes, including the classes in the Java API.
[2] Keywords: Keywords are special identifiers set aside as Java programming constructs. Typical keywords in Java can be found on the following page. Java Keywords

SEMrush Software