Recent Tutorials and Articles
    Multiple Inheritance in Java 8
    Published on: 25th May 2018

    This tutorial will discuss how multiple inheritance works using default methods of interfaces introduced in Java8.

    Pre-requisites


    It is strongly recommended to read about interfaces in Java 8 if you are not familiar with interface enhancement introduced in Java 8. It will help you understand the use case and highlighed challenges in more detail.

     

    What is Multiple Inheritance?


    Multiple inheritance is a special form of inhertiance wherein a class/interface extends/implements multiple classes/interfaces. Java has traditionally been keeping away from supporting it in full form to keep things simple and thus it does not support multiple inheritance in case of classes.

    Java supports multiple inheritance for interfaces. E.g. Let's consider following two interfaces - InterfaceOne and InterfaceTwo -

    public interface InterfaceOne {
    	String methodOne();
    	String methodOneTwo();
    }
    public interface InterfaceTwo {
    	String methodTwo();
    	String methodOneTwo();
    }

    We can now have a class MultipleInheritance implementing both of these interfaces as follows -

    public class MultipleInheritance implements InterfaceOne, InterfaceTwo{
    
    	@Override
    	public String methodTwo() {
    		return "Two";
    	}
    
    	@Override
    	public String methodOne() {
    		return "One";
    	}
    
    	@Override
    	public String methodOneTwo() {
    		return "OneTwo";
    	}
    }

    Although InterfaceOne and InterfaceTwo have a common method methodOneTwo(), it does not create problems as interfaces don't have implemenations. Additionally, it doesn't matter which method is implemented by class as method signature is exactly same in both interfaces.

    Similarly, since Java does not support multiple inheritance for classes (one class can't extend from two different classes), we never got into problem of ambiguous implementations of methods until Java 7.

     

    Multiple Inheritances with Default Methods


    It was all fine with multiple inheritance until we were introduced with default methods in interfaces. Default methods pose following challenges for multiple inheritance -

    • Which of the default method implementations from interfaces will be used if sub class does not override default method? E.g. Let's modify our interfaces by converting method methodOneTwo() to default method and provide different implementations as follows -
    public interface InterfaceOne {
    	String methodOne();
    	
    	default String methodOneTwo() {
    		return "OneTwoInInterfaceOne";
    	}
    }
    public interface InterfaceTwo {
    	String methodTwo();
    	
    	default String methodOneTwo() {
    		return "OneTwoInInterfaceTwo";
    	}
    }

    Now we would think that since our MultipleInheritance class does not need to implement default method methodOneTwo(), which of the implementations will be used?

    Answer to this is that if MultipleInheritance class does not implement this default method, Java compiler will give following error. It ensures that you are always overriding default methods implemented in two or more interfaces to avoid ambiguity.

    Duplicate default methods named methodOneTwo with the parameters () and () are inherited from the types InterfaceTwo and InterfaceOne

     

    • How do i re-use default methods implementations from interfaces in sub class? Now we know that we have to override our methodOneTwo() default method in MultipleInheritance class, but how do i re-use implementation from either InterfaceOne or InterfaceTwo.

    In this case, we can use any of the implementations using the following syntax - <interface name>.super.<method name>.E.g. if we want to use methodOneTwo() implementation from InterfaceOne, we will use InterfaceOne.super.methodOneTwo() to call it as shown below -

    public class MultipleInheritance implements InterfaceOne, InterfaceTwo{
    
    	@Override
    	public String methodTwo() {
    		return "Two";
    	}
    
    	@Override
    	public String methodOne() {
    		return "One";
    	}
    
    	@Override
    	public String methodOneTwo() {
    		return InterfaceOne.super.methodOneTwo();
    	}
    }

    Likewise, we will use InterfaceTwo.super.methodOneTwo() to leverage default method implementation from InterfaceTwo as follows -

    public class MultipleInheritance implements InterfaceOne, InterfaceTwo{
    
    	@Override
    	public String methodTwo() {
    		return "Two";
    	}
    
    	@Override
    	public String methodOne() {
    		return "One";
    	}
    
    	@Override
    	public String methodOneTwo() {
    		return InterfaceTwo.super.methodOneTwo();
    	}
    }

     

     

    Thank you for reading through the tutorial. In case of any feedback/questions/concerns, you can communicate same to us through your comments and we shall get back to you as soon as possible.

    Published on: 25th May 2018

    Comment Form is loading comments...