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:
Define the Base Class (Parent Class):
The base class (or super class) contains common fields and methods that child classes will inherit.
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.
Override Methods:
Child classes can override methods of the parent class to provide specific behavior.
Use the @Override annotation to indicate the overridden method.
Use super to Access Parent Class Members:
Use the super keyword to call parent class constructors or access parent class methods/fields.
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:
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 { }
Interface Enhancements:
Interfaces can have default methods, static methods, and private methods, enabling more flexible behavior reuse.
Pattern Matching for instanceof:
Simplifies the type checking and casting process when dealing with objects in hierarchies.
Tips for Building Effective Class Hierarchies:
Encapsulation: Keep fields private and provide getter/setter methods to protect the data.
Abstraction: Use abstract classes or interfaces to define common behaviors across unrelated classes.
Avoid Overcomplication: Keep the hierarchy simple to avoid making the code difficult to maintain.
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.
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 extendskeyword[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