Java tutorials > Core Java Fundamentals > Object-Oriented Programming (OOP) > How is inheritance implemented using `extends`?

How is inheritance implemented using `extends`?

Inheritance is a fundamental concept in Object-Oriented Programming (OOP) that allows a class to inherit properties and behaviors from another class. In Java, inheritance is implemented using the extends keyword. This tutorial explains how to use extends to achieve inheritance, along with practical examples and best practices.

Basic Syntax of `extends`

The extends keyword follows the child class name and specifies the parent class from which the child class inherits. The child class inherits all non-private members (attributes and methods) of the parent class. The child class can also define its own unique members or override inherited members.

class ParentClass {
    // Parent class members (attributes and methods)
}

class ChildClass extends ParentClass {
    // Child class members (attributes and methods)
    // Inherits members from ParentClass
}

Example: Inheriting from a Class

In this example, the Dog class extends the Animal class. The Dog class inherits the name attribute from Animal and overrides the makeSound() method to provide its own implementation. It also adds a new method, fetch(), specific to dogs. The super(name) call in the Dog constructor invokes the constructor of the parent class, ensuring that the name attribute is properly initialized.

class Animal {
    String name;

    public Animal(String name) {
        this.name = name;
    }

    public void makeSound() {
        System.out.println("Generic animal sound");
    }
}

class Dog extends Animal {
    public Dog(String name) {
        super(name); // Call the parent class constructor
    }

    @Override
    public void makeSound() {
        System.out.println("Woof!");
    }

    public void fetch() {
        System.out.println(name + " is fetching the ball.");
    }

    public static void main(String[] args) {
        Dog myDog = new Dog("Buddy");
        myDog.makeSound(); // Output: Woof!
        myDog.fetch();   // Output: Buddy is fetching the ball.
        System.out.println(myDog.name); // Output: Buddy
    }
}

Concepts Behind the Snippet

  • Inheritance: Enables code reuse and establishes an IS-A relationship between classes (e.g., a Dog IS-A Animal).
  • Superclass (Parent Class): The class being inherited from.
  • Subclass (Child Class): The class that inherits from another class.
  • Method Overriding: A subclass can provide a specific implementation for a method that is already defined in its superclass. The @Override annotation is used to indicate that a method is being overridden.
  • super Keyword: Used to call methods and constructors of the superclass.

Real-Life Use Case

Consider a graphical user interface (GUI) framework. You might have a base class called Shape with attributes like color and methods like draw(). Specific shapes like Circle, Rectangle, and Triangle could then inherit from Shape, inheriting the color attribute and overriding the draw() method to draw themselves accordingly. This promotes code reuse and a well-organized class hierarchy.

Best Practices

  • Favor Composition over Inheritance: While inheritance can be useful, overuse can lead to a rigid class hierarchy. Consider using composition (where a class holds an instance of another class) for more flexibility.
  • Keep Inheritance Hierarchies Shallow: Deep inheritance hierarchies can be difficult to understand and maintain. Aim for relatively shallow hierarchies.
  • Use Access Modifiers Wisely: Carefully consider the access modifiers (public, protected, private) for members in the parent class. protected members are accessible within the parent class, its subclasses, and other classes in the same package.

Interview Tip

Be prepared to explain the difference between inheritance and composition. Also, understand the advantages and disadvantages of using inheritance. Know the different access modifiers and their impact on inheritance. A common question is to describe scenarios where inheritance is appropriate and where composition might be a better choice.

When to Use `extends`

Use extends when you want to establish an IS-A relationship between classes. This means that the child class is a specialized version of the parent class and should inherit its core behavior. If there's no clear IS-A relationship or if you need more flexibility, consider using composition instead.

Memory Footprint

Inheritance can slightly increase the memory footprint of a class because the child class implicitly includes all the members of its parent class. However, the impact is usually negligible unless you have very large and complex inheritance hierarchies. The primary memory impact comes from the data members defined in the class and its parent classes.

Alternatives

The primary alternative to inheritance is Composition. With composition, instead of inheriting behavior, a class can contain instances of other classes and delegate certain responsibilities to them. Another alternative is Interfaces, which define a contract that classes can implement. Interfaces allow multiple inheritance of behavior, which is not possible with classes in Java. Mixins provide a mechanism to 'mix in' functionalities from different sources into a class.

Pros of Using `extends`

  • Code Reusability: Avoids code duplication by allowing subclasses to inherit attributes and methods from superclasses.
  • Improved Organization: Helps to organize code into a hierarchical structure, making it easier to understand and maintain.
  • Polymorphism: Enables polymorphism, allowing objects of different classes to be treated as objects of a common type (their superclass).

Cons of Using `extends`

  • Tight Coupling: Can lead to tight coupling between classes, making it difficult to modify or reuse them independently.
  • Fragile Base Class Problem: Changes to the superclass can unintentionally affect the behavior of subclasses.
  • Limited Flexibility: Java only supports single inheritance, meaning a class can only inherit from one superclass.

FAQ

  • Can a class extend multiple classes in Java?

    No, Java does not support multiple inheritance of classes. A class can only extend one class. However, a class can implement multiple interfaces.

  • What is the difference between inheritance and composition?

    Inheritance creates an IS-A relationship between classes, allowing a subclass to inherit attributes and methods from a superclass. Composition involves creating a HAS-A relationship, where a class contains instances of other classes and delegates responsibilities to them. Composition provides more flexibility than inheritance.

  • What is method overriding?

    Method overriding is the ability of a subclass to provide a specific implementation for a method that is already defined in its superclass. This allows the subclass to customize the behavior of the inherited method.

  • How do I call the parent class's constructor in a subclass?

    You can call the parent class's constructor using the super() keyword in the subclass constructor. This ensures that the parent class's initialization logic is executed.