Java 8 Interface | Set 1 - Walking Techie

Blog about Java programming, Design Pattern, and Data Structure.

Sunday, July 3, 2016

Java 8 Interface | Set 1

Prior to Java 8, Interface having the abstract methods(method declarations) only. In Java 8, Default method and Static method included into Interface.

default method in interface

public interface Mammal {
 default public String identifyMyself() {
  return "I am a mammal";
 }
}

static method in interface

public interface Mammal {
 static public String identifyMyself() {
  return "I am a mammal";
 }
}
We will discuss the static method of the interface in next article. static method of interface

Interface default methods and Its implementation

when the supertypes of a class or interface provide multiple default methods with the same signature, the Java compiler follows inheritance rules to resolve the name conflict.
These rules are driven by the following two principles:
  • Instance methods are preferred over interface default methods.
  • Methods that are already overridden by other candidates are ignored.
1. Instance methods are preferred over interface default methods.
Let's understand by examples.
public class Human {
 public String identify() {
  return "I am human.";
 }
}
public interface Bird {
 default public String identify() {
  return "I am a bird.";
 }
}
public class Test extends Human implements Bird{

 public static void main(String[] args) {
  Test test=new Test();
  System.out.println(test.identify()); // print I am human
 }
}
Now, We will add one more interface in above example and implements this interface in Test class.
public interface Mythical {
 public default String identify() {
  return "I am a mythical creature.";
 }
}
public class Test extends Human implements Bird, Mythical{

 public static void main(String[] args) {
  Test test=new Test();
  System.out.println(test.identify()); // print I am human
 }
}
Now, It is clear that when a class inherits instance method and default method of interfaces of the same signature, preference goes to the instance method.
2. Methods that are already overridden by other candidates are ignored.
Let's understand this point by example.
public interface Animal {
 default public String identify() {
  return "I am an animal.";
 }
}
public interface EggLayer extends Animal {
 //default identify() method of EggLayer interface override, default method of Animal
 default public String identify() {
  return "I am able to lay eggs.";
 }
}
public class Dragon implements Animal, EggLayer {

 public static void main(String[] args) {
  Dragon d = new Dragon();
  System.out.println(d.identify());// print I am able to lay eggs.
 }
}
Now see another example.
public interface FireBreather extends Animal{}
public class Dragon implements Animal, EggLayer,FireBreather  {

 public static void main(String[] args) {
  Dragon d = new Dragon();
  System.out.println(d.identify());// print I am able to lay eggs.
 }
}
In above example, we did not get a compile-time error, because FireBreather does not have default identify() method

Another example, when we have default method identify(), compiler give compile time error.
public interface FireBreather extends Animal{
 default public String identify() {
  return "I am an firebreather.";
 }
}
public class Dragon implements Animal, EggLayer,FireBreather {//we get compile time error

 public static void main(String[] args) {
  Dragon d = new Dragon();
  System.out.println(d.identify());
 }
}
In above example, due to ambiguities compile gives an error. The compiler will give an error like Duplicate default methods named identify with parameters () and () are inherited from types EggLayer and FireBreather.

Consider the example, You have two interfaces (OperateCar and FlyCar) that provide default implementations for the same method, (startEngine):
public interface OperateCar {
    default public int startEngine() {
        // Implementation
    }
}
public interface FlyCar {
    default public int startEngine() {
        // Implementation
    }
}
A class that implements both OperateCar and FlyCar must override the method startEngine. You could invoke any of the of the default implementations with the super keyword.
public class FlyingCar implements OperateCar, FlyCar {
    public int startEngine() {
        FlyCar.super.startEngine(key);
        OperateCar.super.startEngine(key);
    }
}
The name preceding super (in this example, FlyCar or OperateCar) must refer to a direct super interface that defines or inherits a default for the invoked method.

Inherited instance methods from classes can override abstract interface methods. Consider the following interfaces and classes:
public interface Mammal {
    String identify();
}
public class Horse {
    public String identify() {
        return "I am a horse.";
    }
}
public class Test extends Horse implements Mammal {
    public static void main(String... args) {
        Test myApp = new Test();
        System.out.println(myApp.identify()); //print I am a horse.
    }
}

No comments :

Post a Comment