Skip to main content
eLearner.app
Module 4 · Lesson 1 of 27/14 in the course~15 min
Module lessons (1/2)

Interfaces

While abstract classes can contain both partially implemented code and instance fields, interfaces in Java are contracts of pure behavior. An interface defines what a class must be able to do, but not how it does it.

This allows complete decoupling between the definition of operations and their actual implementation.

Defining an Interface (interface)

We use the interface keyword. All methods declared in an interface are implicitly public and abstract (no need to specify it):

Code
interface Drivable {
    void startEngine();
    void stopEngine();
}

Implementing an Interface (implements)

A class implements an interface using the implements keyword and is required to provide the implementation (with a body) for all defined methods:

Code
class Motorcycle implements Drivable {
    @Override
    public void startEngine() {
        System.out.println("Rombo del motore acceso!");
    }

    @Override
    public void stopEngine() {
        System.out.println("Motore spento.");
    }
}

Advantages of Interfaces

  1. Multiple Inheritance: In Java, a class can extend only one parent class (single inheritance), but it can implement multiple interfaces at the same time.
    Code
    class HybridCar implements Drivable, Chargeable { ... }
    
  2. Decoupling: You can define variables using the interface type. Any object that implements that interface can be assigned to such a variable.
    Code
    Drivable vehicle = new Motorcycle();
    vehicle.startEngine();
    

Constants in Interfaces

In interfaces, it is possible to declare fields. These fields are implicitly public static final (meaning class constants), even if you do not specify these modifiers. Consequently, they must be initialized immediately upon declaration:

Code
interface PhysicsConstants {
    double GRAVITY = 9.81; // Implicitly public static final
}

Default Methods (default)

Starting from Java 8, it is possible to define methods with a default implementation inside an interface using the default keyword. These methods do not force the implementing classes to override them, providing a fallback behavior:

Code
interface Logger {
    void log(String message);

    // Default method with a body
    default void logError(String message) {
        log("ERROR: " + message);
    }
}

Try it yourself

Exercise#java.m4.l1.e1
Attempts: 0Loading…

Create a Flyable interface with a void fly() method. Then implement a Bird class that implements Flyable and prints Flying to the screen.

Loading editor…
Show hint

In Flyable, write `void fly();`. In the Bird class, implement the method marking it with `@Override public void fly() { System.out.println('Flying'); }`.

Solution available after 3 attempts

Exercise#java.m4.l1.e2
Attempts: 0Loading…

Define a Drawable interface with a void draw() method. Then implement a Rectangle class that implements Drawable and prints Drawing Rectangle.

Loading editor…
Show hint

Define `void draw();` in the interface. In Rectangle, use `@Override public void draw() { System.out.println('Drawing Rectangle'); }`.

Solution available after 3 attempts

Exercise#java.m4.l1.e3
Attempts: 0Loading…

Complete the Swimmable interface by defining the void swim() method. Then, complete the Duck class so that it implements both Flyable and Swimmable, printing Flying in the fly() method and Swimming in the swim() method.

Loading editor…
Show hint

Declare `void swim();` inside Swimmable. Declare `class Duck implements Flyable, Swimmable` and implement both methods printing the requested strings.

Solution available after 3 attempts