Software Engineering for Self-Directed Learners »

Can use interfaces in Java

C++ to Java → Inheritance →

Interfaces

The text given in this section borrows some explanations and code examples from the -- Java Tutorial.

In Java, an interface is a reference type, similar to a class, mainly containing method signatures. Defining an interface is similar to creating a new class except it uses the keyword interface in place of class.

Here is an interface named DrivableVehicle that defines methods needed to drive a vehicle.

public interface DrivableVehicle {
    void turn(Direction direction);
    void changeLanes(Direction direction);
    void signalTurn(Direction direction, boolean signalOn);
    // more method signatures
}

Note that the method signatures have no braces ({ }) and are terminated with a semicolon.

Interfaces cannot be instantiated—they can only be implemented by classes. When an instantiable class implements an interface, indicated by the keyword implements, it provides a method body for each of the methods declared in the interface.

Here is how a class CarModelX can implement the DrivableVehicle interface.

public class CarModelX implements DrivableVehicle {

    @Override
    public void turn(Direction direction) {
       // implementation
    }

    // implementation of other methods
}

An interface can be used as a type e.g., DrivableVehicle dv = new CarModelX();.

Interfaces can inherit from other interfaces using the extends keyword, similar to a class inheriting another.

Here is an interface named SelfDrivableVehicle that inherits the DrivableVehicle interface.

public interface SelfDrivableVehicle extends DrivableVehicle {
   void goToAutoPilotMode();
}

Note that the method signatures have no braces and are terminated with a semicolon.

Furthermore, Java allows multiple inheritance among interfaces. A Java interface can inherit multiple other interfaces. A Java class can implement multiple interfaces (and inherit from one class).

The design below is allowed by Java. In case you are not familiar with UML notation used: solid lines indicate normal inheritance; dashed lines indicate interface inheritance; the triangle points to the parent.

  1. Staff interface inherits (note the solid lines) the interfaces TaxPayer and Citizen.
  2. TA class implements both Student interface and the Staff interface.
  3. Because of point 1 above, TA class has to implement all methods in the interfaces TaxPayer and Citizen.
  4. Because of points 1,2,3, a TA is a Staff, is a TaxPayer and is a Citizen.

Interfaces can also contain constants and static methods.

This example adds a constant MAX_SPEED and a static method isSpeedAllowed to the interface DrivableVehicle.

public interface DrivableVehicle {

    int MAX_SPEED = 150;

    static boolean isSpeedAllowed(int speed){
        return speed <= MAX_SPEED;
    }

    void turn(Direction direction);
    void changeLanes(Direction direction);
    void signalTurn(Direction direction, boolean signalOn);
    // more method signatures
}

Interfaces can contain default method implementations and nested types. They are not covered here.

[Key Exercise] print Printable items

The Main class below passes a list of Printable objects (i.e., objects that implement the Printable interface) for another method to be printed.

public class Main {

    public static void printObjects(Printable[] items) {
        for (Printable p : items) {
            p.print();
        }
    }

    public static void main(String[] args) {
        Printable[] printableItems = new Printable[]{
                new Circle(5),
                new Rectangle(3, 4),
                new Person("James Cook")};

        printObjects(printableItems);
    }
}

Circle of area 78
Rectangle of area 12
Person of name James Cook

Classes Shape, Circle, and Rectangle are given below:

public abstract class Shape {

    public abstract int area();
}
public class Circle extends Shape implements Printable {

    private int radius;

    public Circle(int radius) {
        this.radius = radius;
    }

    @Override
    public int area() {
        return (int)(Math.PI * radius * radius);
    }

    @Override
    public void print() {
        System.out.println("Circle of area " + area());
    }
}
public class Rectangle extends Shape implements Printable {
    private int height;
    private int width;

    public Rectangle(int height, int width){
        this.height = height;
        this.width = width;
    }

    @Override
    public int area() {
        return height * width;
    }

    @Override
    public void print() {
        System.out.println("Rectangle of area " + area());
    }
}

Add the missing Printable interface. Add the missing methods of the Person class given below.

public class Person implements Printable {

    private String name;

    // todo: add missing methods
}

Partial solution