Interfaces

CSCI 1913 – Introduction to Algorithms, Data Structures, and Program Development
Adriana Picoral

Interfaces

Used for: describing what a class can do, without saying how it does it

An interface is a “contract” – a list of methods a class promises to provide

Syntax: interface (instead of class)

public interface MyInterface {...}

Like abstract classes, we cannot make instances of an interface (cannot use “new” keyword)

Interface Methods

Methods in an interface have no body (end line with semi-colon)

public interface Shape {
    double area();
    double perimeter();
}
  • Interface methods are automatically public and abstract
  • No instance variables (only static final constants are allowed)
  • No constructors

Implementing an Interface

Use keyword implements to sign the contract

public class Square implements Shape {
    private double side;

    public Square(double side) {
        this.side = side;
    }

    public double area() {
        return side * side;
    }

    public double perimeter() {
        return 4 * side;
    }
}

Class has an obligation to implement every method in the interface (or the code does not compile)

Interface as a type

An interface can be used as a variable type (just like a parent class)

Shape s = new Square(2.0);
System.out.println(s.area());
  • Java knows the methods in Shape exist (you can call them)
  • Dynamic binding: the Square version of area() runs
  • Polymorphism: one interface with multiple implementations

is-a relationship

Square implements Shape means a Square is-a Shape

Square sq = new Square(2.0);
System.out.println(sq instanceof Shape); // true

We can write methods that work with any class that implements the interface

public static double totalArea(Shape[] shapes) {
    double total = 0;
    for (Shape s : shapes) {
        total += s.area();
    }
    return total;
}

Multiple interfaces

A class can only extend one parent class…

…but it can implement many interfaces

public class Duck extends Animal implements Flyer, Swimmer {...}
  • extends comes first, then implements
  • Separate multiple interfaces with commas
  • Class must implement the methods from all interfaces

Interfaces can extend interfaces

public interface Shape {
    double area();
    double perimeter();
}


public interface Shape3D extends Shape {
    double volume();
}

A class that implements Shape3D must implement area(), perimeter(), and volume()

default methods

Interfaces can provide a method with a body using the default keyword

public interface Shape {
    double area();
    double perimeter();

    default String describe() {
        return "Shape with area " + area();
    }
}
  • Implementing classes inherit describe()
  • Implementing classes can still override it

Abstract class vs. Interface

Abstract class Interface
Keyword abstract class, extends interface, implements
How many? extend only one implement many
Instance variables yes no (only constants)
Constructors yes no
Methods with body yes only default (and static)
Privacy public, protected, private methods are public
Relationship “is a kind of” (shared code) “can do” (shared ability)

When to use which?

Abstract class: closely related classes that share data and code

  • Greeter → Formal, Informal (they all share name)

Interface: unrelated classes that share an ability

  • Comparable – things that can be ordered (String, Integer, Student…)
  • Flyer – things that can fly (Bird, Airplane, Superhero…)

Built-in interface: Comparable

Java’s Comparable interface has one method:

public interface Comparable<T> {
    int compareTo(T other);
}

a.compareTo(b) returns:

  • a negative number if a comes before b (the calling object is smaller than the argument object)
  • zero if a and b are equal
  • a positive number if a comes after b (the calling object is larger than the argument object)

Comparable example

public class Student implements Comparable<Student> {
    private String name;
    private double gpa;

    public Student(String name, double gpa) {
        this.name = name;
        this.gpa = gpa;
    }

    public int compareTo(Student other) {
        return this.gpa - other.gpa;
    }
}

Now Arrays.sort() can sort an array of Student objects (by GPA)

Student[] students = {...};
Arrays.sort(students);

Practice – Shape Interface

Write a Shape interface and two classes that implement it

  • Shape: methods area(), perimeter() (both return double)
  • Circle: private radius (set in constructor)
  • Rectangle: private width and height (set in constructor)
  • Override toString() in both classes

Things to note:

  • Interface provides structure (a contract) to implementing classes
  • Code in main only needs to know about Shape

Practice – main function

Submit your Shape.java, Circle.java and Rectangle.java to gradescope

You can use this Shapes.java main to test your code in your computer:

public class Shapes {

    public static void main(String[] args) {
        Shape[] shapes = {new Circle(1.0), new Rectangle(2.0, 3.0)};

        for (Shape s : shapes) {
            System.out.println(s);
            System.out.printf("area: %.2f%n", s.area());
            System.out.printf("perimeter: %.2f%n", s.perimeter());
        }
    }
}
Circle with radius 1.0
area: 3.14
perimeter: 6.28
Rectangle 2.0 x 3.0
area: 6.00
perimeter: 10.00

Solution Shape.java

public interface Shape {
    double area();
    double perimeter();
}

Solution Circle.java

public class Circle implements Shape {
    private double radius;

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

    public double area() {
        return Math.PI * radius * radius;
    }

    public double perimeter() {
        return 2 * Math.PI * radius;
    }

    @Override
    public String toString() {
        return "Circle with radius " + radius;
    }
}

Solution Rectangle.java

public class Rectangle implements Shape {
    private double width;
    private double height;

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

    public double area() {
        return width * height;
    }

    public double perimeter() {
        return 2 * (width + height);
    }

    @Override
    public String toString() {
        return "Rectangle " + width + " x " + height;
    }
}