Interface¶
Basics¶
An interface is, like classes, a reference type. It can only contain:
- constants
- method signatures
- methods of type
default
- static methods
- definitions of nested types
No Can create an instance of the interface. Interfaces can be:
- implemented by classes (using the
implements
keyword) - extended by other interfaces (using the
extends
keyword)
Defining the interface¶
When declaring an interface, you define:
- access modifier
- the
interface
keyword - interface name
- optional, a comma-separated list of parent interfaces
- the body of the interface, which may be empty
Below is the definition of a simple interface:
public interface MediaPlayer {
void stop();
void play();
}
The body of the interface¶
The interface body can only contain methods of the type:
- abstract
- default
- static
In addition, when defining the interface, we must remember that certain keywords are by default:
- non-static methods in which we have not defined a body are by default abstract and public, i.e. they must be implemented in implementations
- constants are by default public, [final] (../javaBasics/variables_and_types_of_data.md#final-variables) and static, i.e. they are preceded by the keywords
public static final
- static methods are public by default, ie they are preceded by the
public
keyword
The example below includes all of the above-described elements:
public interface MediaPlayer {
String TAG = "MediaPlayer"; // includes keywords by default- public static final
void stop(); // method with no defined body - abstract by default
default void next() { // the method with the default body, may or may not be overridden in the interface implementation
throw new NoSuchMechanismException("not supported by default");
}
static String getName() { // static method, has the public modifier by default
return "MediaPlayer Interface";
}
}
Implementing the interface¶
In order to create an interface implementation, use the implements
keyword in the class declaration and implement all abstract methods of the interface, e.g .:
// interface declaration
public interface SomeInterface {
void someMethod();
}
// declaration of the class implementing the interface
public class SomeInterfaceImpl implements SomeInterface {
@Override
public void someMethod() {
System.out.println("methodImplementation");
}
}
// creating an instance of the class implementing the interface
SomeInterface someInterface = new SomeInterfaceImpl();
A class can implement more than one interface (separating their names with a comma), e.g .:
// declaration of the first interface
public interface SomeInterface {
void someMethod();
}
// declarations of the second interface, this time without any abstract methods
public interface SomeOtherInterface {
}
// definition of a class that implements both of the above interfaces
public class ClassImplementingInterfaces implements SomeInterface, SomeOtherInterface {
@Override
public void someMethod() {
System.out.println("I am interface method implementation");
}
}
A single class, in addition to implementing multiple interfaces, can also extend at most one class, e.g .:
// declaration of the first interface
public interface SomeInterface {
void someMethod();
}
// declaration of a second interface, this time without any abstract methods
public interface SomeOtherInterface {
}
// a class definition that extends the SomeClass class and implements both of the above interfaces
public class ClassImplementingInterfacesAndExtendingClass extends SomeClass implements SomeInterface, SomeOtherInterface {
@Override
public void someMethod() {
System.out.println("I am interface method implementation");
}
}
Modifying the interface¶
Any modification on the implemented interface will result in errors at the compilation level due to the lack of implementation of the new (modified) interface. Taking into account the already implemented interface:
public interface NewsletterAPI {
void subscribe();
void unsubscribe();
}
and making the following modifications:
public interface NewsletterAPI {
void subscribe(String type);
void unsubscribe();
}
we will get a compilation error related to the following implementation:
// Class must either be declared abstract or implement abstract method error
public class ShopNewsletterAPI implements NewsletterAPI {
@Override
public void subscribe() {
System.out.println("Subscribe to shop newsletter!");
}
@Override
public void unsubscribe() {
System.out.println("Unsubscribe from shop newsletter!");
}
}
NOTE: When changing the interface definition, we must remember about the necessary changes in all of its implementations.
NOTE: Similar compilation errors can be avoided by using the
refactor
option in IntelliJ IDEA using the shortcutShift + F6
.
Default methods¶
Default methods were introduced in Java 1.8. Their main use is to introduce modifications to an existing interface, without causing compilation errors related to changing the interface body. The default methods add new functionalities to library interfaces and ensure binary compatibility with code written for older versions of those interfaces. If you implement interfaces with default methods, there is no need to override those methods as in the example below. For a given interface:
public interface Encoder {
default String encode(String encodeText) {
return encodeText;
}
default String decode(String decodeText) {
return decodeText;
}
}
public class SampleEncoder implements Encoder { }