Home › Learn › Java › Interfaces, generics, and streams

Interfaces

Lesson 31 of 40. A contract that different classes can fulfill.

An interface lists methods without bodies: interface Shape { double area(); }. A class that implements Shape must provide them, and from then on it can be used wherever a Shape is expected. That is how code can work with "anything that has an area" without caring whether it is a circle or a square: for (Shape s : shapes) total += s.area();.

An interface can also carry default methods with bodies, which implementing classes get for free and may override, and constants. A class can implement several interfaces but extend only one class, which is why Java leans on interfaces for shared behavior. An abstract class sits between the two: it can have fields and constructors, but cannot be instantiated and may leave methods abstract for subclasses.

interface Greeter {
    String greet(String name);

    default String greetAll(String a, String b) {
        return greet(a) + " " + greet(b);
    }
}

class Polite implements Greeter {
    public String greet(String name) {
        return "Good day, " + name;
    }
}

Your task

Using Shape from the starter, write class Circle implements Shape with a double radius (constructor Circle(double radius)) and class Square implements Shape with a double side, each with area() and name() ("circle" and "square"). Add a default String describe() to Shape returning <name> with area <area> (the area as a double). Then write static double totalArea(List<Shape> shapes) in Main.

Hint 1

class Circle implements Shape { double radius; Circle(double radius) { this.radius = radius; } public double area() { return Math.PI * radius * radius; } public String name() { return "circle"; } }

Hint 2

default String describe() { return name() + " with area " + area(); } goes inside the interface. totalArea loops and adds s.area().

Show the solution
import java.util.*;

public class Main {
    static double totalArea(List<Shape> shapes) {
        double total = 0;
        for (Shape s : shapes) {
            total += s.area();
        }
        return total;
    }

    public static void main(String[] args) {
        List<Shape> shapes = List.of(new Circle(1), new Square(2));
        System.out.println(totalArea(shapes));
    }
}

interface Shape {
    double area();

    String name();

    default String describe() {
        return name() + " with area " + area();
    }
}

class Circle implements Shape {
    double radius;

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

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

    public String name() {
        return "circle";
    }
}

class Square implements Shape {
    double side;

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

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

    public String name() {
        return "square";
    }
}

    Compiles with OpenJDK javac and TeaVM, both compiled to WebAssembly (7 MB download the first time, then cached), and runs in this tab; nothing is sent anywhere.