Skip to content

7.5 Interfaces

An interface is a reference type in Java that contains abstract methods, default methods, static methods, and constants. It defines a contract that implementing classes must follow.

Basic Interface Syntax

java
// Interface declaration
interface Drawable {
    // Constant (implicitly public, static, final)
    String DEFAULT_COLOR = "black";

    // Abstract method (implicitly public abstract)
    void draw();

    // Default method (Java 8+)
    default void setColor(String color) {
        System.out.println("Setting color to: " + color);
    }

    // Static method (Java 8+)
    static void printInfo() {
        System.out.println("This is a Drawable interface");
    }
}

Implementing Interfaces

java
class Circle implements Drawable {
    private double radius;

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

    @Override
    public void draw() {
        System.out.println("Drawing a circle with radius " + radius);
    }
}

class Rectangle implements Drawable {
    private double width, height;

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

    @Override
    public void draw() {
        System.out.println("Drawing a rectangle " + width + "x" + height);
    }
}

Multiple Interface Implementation

java
interface Flyable {
    void fly();
}

interface Swimmable {
    void swim();
}

// Class implementing multiple interfaces
class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("Duck is flying");
    }

    @Override
    public void swim() {
        System.out.println("Duck is swimming");
    }
}

Interface Inheritance

java
interface Animal {
    void eat();
    void sleep();
}

interface Mammal extends Animal {
    void giveBirth();
}

class Human implements Mammal {
    @Override
    public void eat() {
        System.out.println("Human is eating");
    }

    @Override
    public void sleep() {
        System.out.println("Human is sleeping");
    }

    @Override
    public void giveBirth() {
        System.out.println("Human gives birth to live young");
    }
}

Functional Interfaces (Java 8+)

java
// Single abstract method interface
@FunctionalInterface
interface Calculator {
    int calculate(int a, int b);

    // Can have default methods
    default void printResult(int result) {
        System.out.println("Result: " + result);
    }
}

// Using lambda expressions
public class FunctionalInterfaceDemo {
    public static void main(String[] args) {
        Calculator addition = (a, b) -> a + b;
        Calculator multiplication = (a, b) -> a * b;

        System.out.println("5 + 3 = " + addition.calculate(5, 3));
        System.out.println("5 * 3 = " + multiplication.calculate(5, 3));
    }
}

Complete Interface Example

java
// Banking system interfaces
interface Account {
    void deposit(double amount);
    void withdraw(double amount);
    double getBalance();
}

interface InterestBearing {
    double calculateInterest();
    void applyInterest();
}

interface Transferable {
    void transfer(Account toAccount, double amount);
}

// Implementing multiple interfaces
class SavingsAccount implements Account, InterestBearing, Transferable {
    private double balance;
    private double interestRate;

    public SavingsAccount(double initialBalance, double interestRate) {
        this.balance = initialBalance;
        this.interestRate = interestRate;
    }

    @Override
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposited: $" + amount);
        }
    }

    @Override
    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("Withdrawn: $" + amount);
        }
    }

    @Override
    public double getBalance() {
        return balance;
    }

    @Override
    public double calculateInterest() {
        return balance * interestRate;
    }

    @Override
    public void applyInterest() {
        double interest = calculateInterest();
        balance += interest;
        System.out.println("Interest applied: $" + interest);
    }

    @Override
    public void transfer(Account toAccount, double amount) {
        if (amount > 0 && amount <= balance) {
            this.withdraw(amount);
            toAccount.deposit(amount);
            System.out.println("Transferred: $" + amount);
        }
    }
}

Default Methods in Interfaces

java
interface Logger {
    void log(String message);

    // Default method - provides default implementation
    default void logError(String error) {
        log("ERROR: " + error);
    }

    default void logInfo(String info) {
        log("INFO: " + info);
    }
}

class FileLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("File Log: " + message);
        // Actual file logging implementation
    }
}

class ConsoleLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("Console: " + message);
    }

    // Can override default methods
    @Override
    public void logError(String error) {
        System.out.println("🚨 CRITICAL ERROR: " + error);
    }
}

Static Methods in Interfaces

java
interface MathOperations {
    static int add(int a, int b) {
        return a + b;
    }

    static int multiply(int a, int b) {
        return a * b;
    }

    static double power(double base, double exponent) {
        return Math.pow(base, exponent);
    }
}

public class InterfaceStaticMethods {
    public static void main(String[] args) {
        // Call static methods directly on interface
        int sum = MathOperations.add(5, 3);
        int product = MathOperations.multiply(5, 3);

        System.out.println("Sum: " + sum);
        System.out.println("Product: " + product);
    }
}

Interface vs Abstract Class

FeatureInterfaceAbstract Class
MethodsAbstract, default, staticAbstract and concrete
FieldsOnly constantsAny fields
InheritanceMultipleSingle
ConstructorsNoYes
AccessPublic onlyAny access modifier

When to Use Interfaces

  1. Multiple inheritance of type
  2. Defining contracts for unrelated classes
  3. API design and abstraction
  4. Callback mechanisms and event handling
  5. Strategy pattern implementation