Interfaces in Java

Introduction

Definition: An interface is a reference type in Java, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types. Interfaces cannot contain instance fields or constructors.

Purpose: Interfaces provide a way to achieve abstraction and multiple inheritance in Java.

Key Points:

  • All methods in an interface are abstract by default (except default and static methods).
  • A class that implements an interface must have implementations for all the abstract methods in the interface.
  • A class can implement multiple interfaces.
Java
interface Playable {
    void play();
}

class Cricket implements Playable {
    public void play() {
        System.out.println("Playing cricket.");
    }
}

class Tennis implements Playable {
    public void play() {
        System.out.println("Playing tennis.");
    }
}

public class InterfaceExample {
    public static void main(String[] args) {
        Playable cricket = new Cricket();
        Playable tennis = new Tennis();
        cricket.play(); // Output: Playing cricket.
        tennis.play();  // Output: Playing tennis.
    }
}

Advanced Examples: Using Interfaces to Implement Design Patterns
Interfaces are often used to implement design patterns in Java. Here, we’ll look at a few common patterns: Strategy, Observer, and Factory Method.

Strategy Pattern

The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. It lets the algorithm vary independently from clients that use it.

Java
interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " using Credit Card.");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " using PayPal.");
    }
}

class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
    
    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

public class StrategyPatternExample {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.setPaymentStrategy(new CreditCardPayment());
        cart.checkout(100); // Output: Paid 100 using Credit Card.
        
        cart.setPaymentStrategy(new PayPalPayment());
        cart.checkout(200); // Output: Paid 200 using PayPal.
    }
}

Observer Pattern

The Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Java
import java.util.ArrayList;
import java.util.List;
interface Observer {
    void update(String message);
}
class EmailSubscriber implements Observer {
    private String email;    
    public EmailSubscriber(String email) {
        this.email = email;
    }    
    public void update(String message) {
        System.out.println("Email to " + email + ": " + message);
    }
}
class SMSSubscriber implements Observer {
    private String phoneNumber;    
    public SMSSubscriber(String phoneNumber) {
        this.phoneNumber = phoneNumber;    }
        public void update(String message) {
        System.out.println("SMS to " + phoneNumber + ": " + message);
    }
}
class NotificationService {
    private List<Observer> observers = new ArrayList<>();    
    public void addObserver(Observer observer) {
        observers.add(observer);
    }    
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }    
    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}
public class ObserverPatternExample {
    public static void main(String[] args) {
        NotificationService service = new NotificationService();        
        Observer emailSubscriber = new EmailSubscriber("example@example.com");
        Observer smsSubscriber = new SMSSubscriber("1234567890");        
        service.addObserver(emailSubscriber);
        service.addObserver(smsSubscriber);        
        service.notifyObservers("New event notification!");
        // Output: Email to example@example.com: New event notification!
        //         SMS to 1234567890: New event notification!
    }
}

Factory Method Pattern

The Factory Method pattern defines an interface for creating an object, but lets subclasses alter the type of objects that will be created.

Java
interface Sport {
    void play();
}
class Cricket implements Sport {
    public void play() {
        System.out.println("Playing cricket.");
    }
}
class Tennis implements Sport {
    public void play() {
        System.out.println("Playing tennis.");
    }
}
abstract class SportFactory {
    abstract Sport createSport();
}
class CricketFactory extends SportFactory {
    Sport createSport() {
        return new Cricket();
    }
}
class TennisFactory extends SportFactory {
    Sport createSport() {
        return new Tennis();
    }
}
public class FactoryMethodPatternExample {
    public static void main(String[] args) {
        SportFactory cricketFactory = new CricketFactory();
        Sport cricket = cricketFactory.createSport();
        cricket.play(); // Output: Playing cricket.
        
        SportFactory tennisFactory = new TennisFactory();
        Sport tennis = tennisFactory.createSport();
        tennis.play(); // Output: Playing tennis.
    }
}

Conclusion
Understanding interfaces and abstract classes is fundamental to mastering Java. By grasping these concepts, you can leverage them to create flexible, reusable, and maintainable code.

Using interfaces to implement design patterns such as Strategy, Observer, and Factory Method can help you solve common software design problems and write more efficient and scalable applications. Including practical examples and explaining design patterns in your tutorial will provide a comprehensive learning experience for your audience.

Scroll to Top