What is an interface in Java?
An interfaces is a type similar to a class and is defined via the interface keyword. Interfaces are used to define common behavior of implementing classes. If two classes implement the same interface, other code which work on the interface level, can use objects of both classes.
Like a class an interface defines methods. Classes can implement one or several interfaces. A class which implements an interface must provide an implementation for all abstract methods defined in the interface.
Abstract, default and static methods in Interfaces
An interface can have abstract methods and _default_methods. A default method is defined via the default keyword at the beginning of the method signature. All other methods defined in an interfaces are public and abstract; explicit declaration of these modifiers is optional.
Interfaces can have constants which are always implicitly public, static and final.
The following code shows an example implementation of an interface.
package testing;
public interface MyInterface {
// constant definition
String URL = "https://www.vogella.com/";
// public abstract methods
void test();
void write(String s);
// default method
default String reserveString(String s){
return new StringBuilder(s).reverse().toString();
}
}
Implementing Interfaces
A class can implement an interface. In this case it must provide concrete implementations of the abstract interface methods. If you implement a method defined by an interface, you can use @Override annotation. This indicates to the Java compiler that you actually want to implement a method defined by this interface. This way the compiler can give you an error in you mis-typed the name of the method or in the number of arguments. The following class implements the MyInterface interface, its must therefore implement the abstract method and can use the default methods.
package com.vogella.javaintro.base;
public class MyClassImpl implements MyInterface {
@Override
public void test() {
}
@Override
public void write(String s) {
}
public static void main(String[] args) {
MyClassImpl impl = new MyClassImpl();
System.out.println(impl.reserveString("Lars Vogel"));
}
}
Evolving interfaces with default methods
Before Java 8 evolving interfaces, e.g., adding new methods to an interface, was not possible without breaking existing clients. Java 8 introduced default methods, now you can extend an interface without breaking clients by simply suppling a default implementation with it. Adding such a default method is a source and binary compatible change.
A class can always override a default method to supply a better behavior.
Multiple inheritance of methods
If a class implements two interfaces and if these interfaces provide the same default method, Java resolves the correct method for the class by the following rules:
Superclass wins always against the superinterface - If a class can inherit a method from a superclass and a superinterface, the class inherits the superclass method. This is true for concrete and abstract superclass methods. This rule implies that default methods are not used if this method is also declared in the superclass chain.
Subtypes win over Supertypes - If a class can inherit a method from two interfaces, and one is a subtype of the other, the class inherts the method from the subtype
In all other cases the class needs to implement the default method
The following listing demonstrates listing number 3.
public interface A { default void m() {} }
public interface B { default void m() {} }
public class C implements A, B { @Override public void m() {} } In your implementation you can also call the super method you prefer.
public class C implements A, B { @Override public void m() {A.super.m();} }
Functional interfaces
All interfaces that have only one method are called functional interfaces. Functional interfaces have the advantage that they can be used together with lambda expressions. See What are lambdas? to learn more about lambdas, e.g., the type of lambdas is a functional interface.
The Java compiler automatically identifies functional interfaces. The only requirement is that they have only one abstract method. However, is possible to capture the design intent with a @FunctionalInterface annotation.
Several default Java interfaces are functional interfaces:
java.lang.Runnable
java.util.concurrent.Callable
java.io.FileFilter
java.util.Comparator
java.beans.PropertyChangeListener
Java also contains the java.util.function package which contains functional interfaces which are frequently used such as:
Predicate
Consumer
Function
Supplier
UnaryOperator
BinaryOperator