Java does not support multiple inheritance through classes to avoid issues such as the Diamond Problem. However, multiple inheritance can be achieved in Java through the use of interfaces. Here’s how it can be implemented:

Using Interfaces for Multiple Inheritance

You can create multiple interfaces and then have a class implement those interfaces.

Example

// Define two interfaces
interface InterfaceA {
    void methodA();
}

interface InterfaceB {
    void methodB();
}

// Implement both interfaces in a class
class MultipleInheritanceExample implements InterfaceA, InterfaceB {
    @Override
    public void methodA() {
        System.out.println("Method A from InterfaceA");
    }

    @Override
    public void methodB() {
        System.out.println("Method B from InterfaceB");
    }
}

// Main class to test
public class Main {
    public static void main(String[] args) {
        MultipleInheritanceExample example = new MultipleInheritanceExample();
        example.methodA();
        example.methodB();
    }
}

Why Java Doesn’t Allow Multiple Inheritance with Classes

When a class extends multiple classes, ambiguity may arise if the classes have methods with the same signature. For example, if ClassA and ClassB both have a method(), and ClassC extends both, the compiler won’t know which method to call. Using interfaces avoids this issue because:

  1. Interfaces only declare methods (no method implementation).
  2. The implementing class provides the method definitions, resolving potential conflicts explicitly.

Example with Default Methods

Starting with Java 8, interfaces can include default methods (methods with a body). Even in this case, ambiguity can be resolved explicitly.

interface InterfaceC {
    default void method() {
        System.out.println("Default method in InterfaceC");
    }
}

interface InterfaceD {
    default void method() {
        System.out.println("Default method in InterfaceD");
    }
}

class ConflictResolutionExample implements InterfaceC, InterfaceD {
    @Override
    public void method() {
        // Explicitly resolving conflict
        InterfaceC.super.method();
        InterfaceD.super.method();
        System.out.println("Resolved method in class");
    }
}

// Main class
public class Main {
    public static void main(String[] args) {
        ConflictResolutionExample example = new ConflictResolutionExample();
        example.method();
    }
}

In this example, the method() from both interfaces is explicitly invoked using InterfaceC.super.method() and InterfaceD.super.method(), followed by the class’s own implementation.

This approach ensures flexibility while maintaining clarity and avoiding ambiguity.