Inheritance is a fundamental concept in object-oriented programming (OOP) that allows you to create new classes based on existing ones. This tutorial will cover the basics of inheritance, including subclasses, superclasses, the extends keyword, and the final keyword.
Inheritance enables code reusability and promotes a hierarchical classification of classes. By inheriting properties and behaviors from a superclass, you can create more specific classes (subclasses) that extend or modify the functionality of the superclass. This not only simplifies code but also enhances maintainability by reducing redundancy.
Understanding inheritance is crucial for building scalable and organized Java applications. It forms the basis for polymorphism, which we will explore in the next topic.
In Java, a class that inherits from another class is called a subclass (or derived class), while the class being inherited from is called a superclass (or base class). The extends keyword is used to establish an inheritance relationship between classes.
Let's start with a simple example where we have a superclass named Animal and a subclass named Dog.
1public class Animal {2public void eat() {3System.out.println("This animal eats food.");4};5}
1public class Dog extends Animal {2public void bark() {3System.out.println("The dog barks.");4}5}
In this example, the Dog class inherits the eat() method from the Animal class. We can now create a Dog object and call both its own methods and inherited methods.
$ javac Animal.java$ javac Dog.java$ java Dog
This animal eats food. The dog barks.
Subclasses can override methods of the superclass to provide specific implementations. Let's modify the Dog class to override the eat() method.
1public class Dog extends Animal {2@Override3public void eat() {4System.out.println("The dog eats meat.");5}67public void bark() {8System.out.println("The dog barks.");9}10}
$ javac Dog.java$ java Dog
The dog eats meat. The dog barks.
In this example, the Dog class overrides the eat() method to provide a more specific implementation.
extends KeywordThe extends keyword is used to create a subclass that inherits from a superclass. It establishes an "is-a" relationship between classes.
1public class SubclassName extends SuperclassName {2// Class body3}
final KeywordThe final keyword can be used with classes, methods, and variables to restrict modifications.
A class declared as final cannot be subclassed. This is useful when you want to prevent any further extension of the class.
1public final class FinalClass {2public void display() {3System.out.println("This is a final class.");4}5}
A method declared as final cannot be overridden by subclasses. This is useful when you want to ensure that the behavior of a method remains consistent across different subclasses.
1public class Animal {2public final void eat() {3System.out.println("This animal eats food.");4}5}
A variable declared as final cannot be reassigned after its initial value is set. This is useful for defining constants.
1public class Constants {2public static final int MAX_VALUE = 100;3}
Let's combine the use of final with inheritance.
1public class Animal {2public final void eat() {3System.out.println("This animal eats food.");4}5}
1// This will cause a compile-time error2public class Dog extends Animal {3@Override4public void eat() {5System.out.println("The dog eats meat.");6}7}
$ javac Dog.javaDog.java:4: cannot override final method from Animalpublic void eat() {^1 error
In this example, attempting to override the eat() method in the Dog class results in a compile-time error because the eat() method in the Animal class is declared as final.
Let's create a practical example that demonstrates inheritance and polymorphism. We'll define a superclass Vehicle and two subclasses Car and Motorcycle. Each subclass will have its own specific methods.
1public class Vehicle {2public void start() {3System.out.println("The vehicle starts.");4}5}
1public class Car extends Vehicle {2@Override3public void start() {4System.out.println("The car starts with a key.");5}67public void openTrunk() {8System.out.println("The trunk is opened.");9}10}
1public class Motorcycle extends Vehicle {2@Override3public void start() {4System.out.println("The motorcycle starts with a kick.");5}67public void wheelie() {8System.out.println("Doing a wheelie!");9}10}
1public class Main {2public static void main(String[] args) {3Vehicle myCar = new Car();4Vehicle myMotorcycle = new Motorcycle();56myCar.start(); // Output: The car starts with a key.7myMotorcycle.start(); // Output: The motorcycle starts with a kick.89// Type casting to access specific methods10if (myCar instanceof Car) {11((Car) myCar).openTrunk(); // Output: The trunk is opened.12}1314if (myMotorcycle instanceof Motorcycle) {15((Motorcycle) myMotorcycle).wheelie(); // Output: Doing a wheelie!16}17}18}
$ javac Vehicle.java$ javac Car.java$ javac Motorcycle.java$ javac Main.java$ java Main
The car starts with a key. The motorcycle starts with a kick. The trunk is opened. Doing a wheelie!
In this example, we have a Vehicle superclass and two subclasses Car and Motorcycle. Each subclass overrides the start() method to provide specific behavior. We also demonstrate how to use type casting to access methods that are unique to each subclass.
| Concept | Description |
|---|---|
| Subclass | A class that inherits from another class. |
| Superclass | The class being inherited from. |
extends | Keyword used to create a subclass. |
final | Keyword to prevent inheritance or method overriding. |
extends keyword is essential for establishing an inheritance relationship.final keyword can be used to prevent further subclassing or method overriding.In the next topic, we will explore Java Polymorphism, which allows objects of different classes to be treated as objects of a common superclass. This concept is crucial for building flexible and dynamic applications. Stay tuned!