Interfaces are a key feature of object oriented programming. An interface provides a set of methods that an implementing class must provide. One can assign instances of the class to variables of the interface type. As of Java8, an interface can contain default methods that an implementing class can inherit or override. Default methods (also known as Defender Methods) enable us to add new functionalities to interfaces without breaking the classes that implements the interface.
1. Declaring an interface
Interfaces are declared by specifying a keyword “interface”
2. Implementing an interface
The class implementing the interface has to provide the implementation of all the methods in the interface
The @Override annotation tells the compiler that this method is inherited from the interface.
3. Default methods in Interface
Java 8 onwards, you can provide default implementation of methods in interfaces. If the class implementing the interface does not provide an implementation of the method, then the default implementation is used.
Let’s change the main() method to call the newMethod. Observe that the interface implementation has not changed.
4. Using Default Methods or Abstract Classes
After the introduction of default methods, it may seem that there are no differences between abstract classes, and interfaces. However, it is not so. Abstract classes can define constructor. They can have a state associated with them. In contrast, default methods can only be implemented in terms of invoking other interface methods, with no reference to a particular implementation’s state.
5. Default methods and Multiple inheritance ambiguity
A Java class can implement multiple interfaces. Each interface can define default method with same method signature, therefore, the methods can conflict with each other.
Let’s consider an example:
Declare two interfaces with default methods implemented with the same method signature.
The above code will give a compilation error:
java: class InterfaceImpl inherits unrelated defaults for method() from types InterfaceA and InterfaceB
We need to provide an implementation of the default method in order to resolve this conflict.
To summarise, default methods enable addition of new functionality without breaking existing implementations.
When we extend an interface containing the default method, we can do one of the following:
1. Not override the default method and the implementing class will inherit the default method.
2. Override the default method similar to other methods we override in subclass.
3. Redeclare default method as abstract, which forces the subclass to override it.