Skip to content

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;
    }
}
the following implementation does not cause compilation errors and is fully functional:

public class SampleEncoder implements Encoder { }