interface methods, multiple inheritance and Abstract class


Accessing other interface methods within default method

You can as well access other interface methods from within your default method.

public interface Addable {
    int getX();
    int getY();
 
    default int computeSum() {
        return getX() + getY();
    }
}
 
public class Addition implements Addable {
    @Override
    public int getX() {
        return 3;
    }
 
    @Override
    public int getY() {
        return 5;
    }
}
 
// The following statement will print 8:
System.out.println(new Addition().computeSum());

Default methods could be used along with interface static methods as well:

public interface Addable {
    static int getValueX() {
        return 5;
    }
 
    static int getValueY() {
        return 7;
    }
 
    default int calculateSum() {
        return getValueX() + getValueY();
    }
}
 
public class Addition implements Addable {}
 
// The following statement will also print 12:
System.out.println(new Addition().calculateSum());

Default method multiple inheritance collision

Consider next example:

public interface A {
     default void fun() { System.out.println("A.fun"); }
}
 
public interface B {
     default void fun() { System.out.println("B.fun"); }
}

Here are two interfaces declaring default method fun with the same signature.

If you will try to extend these both interfaces in the new interface you have to make choice of two, because Java forces you to resolve this collision explicitly.

First, you can declare method fun with the same signature as abstract, which will override A and B behaviour.

public interface ABExtendsAbstract extends A, B {
	@Override
	void fun();
}

And when you will implement ABExtendsAbstract in the class you will have to provide fun implementation:

public class ABExtendsAbstractImpl implements ABExtendsAbstract {
	@Override
	public void fun() {
		System.out.println("ABImpl.fun");
	}
}

Or second, you can provide a completely new default implementation. You also may reuse code of A and B fun methods by Accessing overridden default methods from implementing class

public interface ABExtends extends A, B {
	@Override
	default void fun() {
		System.out.println("ABExtends.fun");
	}
}

And when you will implement ABExtends in the class you will not have to provide fun implementation:

public class ABExtendsImpl implements ABExtends {}

Class, Abstract class and Interface method precedence

Implementations in classes, including abstract declarations, take precedence over all interface defaults

  • Abstract class method takes precedence over Interface Default Method.
  • public interface WaterSkills {
        default void freestyle() {
            System.out.println("WaterSkills.freestyle");
        }
    }
     
    public abstract class AquaticAthlete implements WaterSkills {
        public void freestyle() {
            System.out.println("AquaticAthlete.freestyle");
        }
    }
     
    public class BarSwimmer extends AquaticAthlete {
    }
    // The following statement will produce:
    AquaticAthlete.freestyle
    new BarSwimmer().freestyle();
  • Class method takes precedence over Interface Default Method
  • public interface WaterSkills {
        default void butterflyStroke() {
            System.out.println("WaterSkills.butterflyStroke");
        }
    }
     
    public abstract class UnderwaterAthlete implements WaterSkills {
    }
     
    public class BarSwimmer extends UnderwaterAthlete {
        public void butterflyStroke() {
            System.out.println("BarSwimmer.butterflyStroke");
        }
    }
    // The following statement will produce:
    BarSwimmer.butterflyStroke
    new BarSwimmer().butterflyStroke();

Basic Programs