Interfaces

Introduction

Interface is a contract that defines what a class must do, but not how. It contains abstract methods that implementing classes must provide.


Basic Syntax

interface InterfaceName {
    // Abstract methods (no body)
    returnType methodName();
}

Simple Example

interface Animal {
    void sound();  // Abstract method
    void eat();    // Abstract method
}

class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("Bark");
    }

    @Override
    public void eat() {
        System.out.println("Dog eats food");
    }
}

class Cat implements Animal {
    @Override
    public void sound() {
        System.out.println("Meow");
    }

    @Override
    public void eat() {
        System.out.println("Cat eats fish");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.sound();  // Bark
        dog.eat();    // Dog eats food

        Animal cat = new Cat();
        cat.sound();  // Meow
        cat.eat();    // Cat eats fish
    }
}

Key Features

  1. All methods are public and abstract (by default)
  2. All variables are public, static, final (constants)
  3. Cannot instantiate interface
  4. Multiple inheritance allowed
  5. Class uses implements keyword

Interface Variables

All variables are constants (public static final).

interface Constants {
    int MAX_VALUE = 100;           // public static final
    String APP_NAME = "MyApp";     // public static final
    double PI = 3.14159;           // public static final
}

class Test {
    public static void main(String[] args) {
        System.out.println(Constants.MAX_VALUE);  // 100
        System.out.println(Constants.APP_NAME);   // MyApp

        // Constants.MAX_VALUE = 200;  // ✗ Error: Cannot change
    }
}

Implementing Interface

interface Drawable {
    void draw();
}

class Circle implements Drawable {
    @Override
    public void draw() {
        System.out.println("Drawing Circle");
    }
}

class Rectangle implements Drawable {
    @Override
    public void draw() {
        System.out.println("Drawing Rectangle");
    }
}

public class Main {
    public static void main(String[] args) {
        Drawable d1 = new Circle();
        Drawable d2 = new Rectangle();

        d1.draw();  // Drawing Circle
        d2.draw();  // Drawing Rectangle
    }
}

Multiple Interfaces

A class can implement multiple interfaces.

interface Printable {
    void print();
}

interface Scannable {
    void scan();
}

class Printer implements Printable, Scannable {
    @Override
    public void print() {
        System.out.println("Printing...");
    }

    @Override
    public void scan() {
        System.out.println("Scanning...");
    }
}

public class Main {
    public static void main(String[] args) {
        Printer p = new Printer();
        p.print();  // Printing...
        p.scan();   // Scanning...
    }
}

Interface Inheritance

Interface can extend another interface.

interface Animal {
    void eat();
}

interface Pet extends Animal {
    void play();
}

class Dog implements Pet {
    @Override
    public void eat() {
        System.out.println("Dog eats");
    }

    @Override
    public void play() {
        System.out.println("Dog plays");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();   // Dog eats
        dog.play();  // Dog plays
    }
}

Complete Example: Payment System

interface Payment {
    boolean processPayment(double amount);
    String getPaymentMethod();
}

class CreditCard implements Payment {
    private String cardNumber;
    private double balance;

    CreditCard(String cardNumber, double balance) {
        this.cardNumber = cardNumber;
        this.balance = balance;
    }

    @Override
    public boolean processPayment(double amount) {
        if (balance >= amount) {
            balance -= amount;
            System.out.println("Paid $" + amount + " via Credit Card");
            System.out.println("Remaining balance: $" + balance);
            return true;
        }
        System.out.println("Insufficient balance");
        return false;
    }

    @Override
    public String getPaymentMethod() {
        return "Credit Card";
    }
}

class PayPal implements Payment {
    private String email;
    private double balance;

    PayPal(String email, double balance) {
        this.email = email;
        this.balance = balance;
    }

    @Override
    public boolean processPayment(double amount) {
        if (balance >= amount) {
            balance -= amount;
            System.out.println("Paid $" + amount + " via PayPal");
            System.out.println("Remaining balance: $" + balance);
            return true;
        }
        System.out.println("Insufficient balance");
        return false;
    }

    @Override
    public String getPaymentMethod() {
        return "PayPal";
    }
}

class PaymentProcessor {
    static void processOrder(Payment payment, double amount) {
        System.out.println("\nProcessing payment via " + payment.getPaymentMethod());
        payment.processPayment(amount);
    }
}

public class Main {
    public static void main(String[] args) {
        Payment card = new CreditCard("1234-5678", 1000);
        Payment paypal = new PayPal("user@email.com", 500);

        PaymentProcessor.processOrder(card, 300);
        PaymentProcessor.processOrder(paypal, 200);
    }
}

Why Use Interfaces?

  1. Abstraction: Hide implementation details
  2. Multiple inheritance: Class can implement many interfaces
  3. Loose coupling: Code depends on interface, not implementation
  4. Polymorphism: Treat different classes uniformly
  5. Contract: Ensure classes implement required methods

Interface as Type

interface Shape {
    double area();
}

class Circle implements Shape {
    double radius;

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

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

class Rectangle implements Shape {
    double length, width;

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

    @Override
    public double area() {
        return length * width;
    }
}

public class Main {
    public static void main(String[] args) {
        // Interface as type
        Shape s1 = new Circle(5);
        Shape s2 = new Rectangle(4, 6);

        System.out.println("Circle area: " + s1.area());
        System.out.println("Rectangle area: " + s2.area());

        // Array of interface type
        Shape[] shapes = {new Circle(3), new Rectangle(5, 2)};
        for (Shape shape : shapes) {
            System.out.println("Area: " + shape.area());
        }
    }
}

Marker Interface

Interface with no methods (just marks a class).

interface Serializable {
    // No methods - marker interface
}

class Student implements Serializable {
    String name;
    int rollNo;

    Student(String name, int rollNo) {
        this.name = name;
        this.rollNo = rollNo;
    }
}

public class Main {
    public static void main(String[] args) {
        Student s = new Student("John", 101);

        // Check if serializable
        if (s instanceof Serializable) {
            System.out.println("Student can be serialized");
        }
    }
}

Real-World Example: Database Operations

interface DatabaseOperations {
    void connect();
    void disconnect();
    void insert(String data);
    void delete(int id);
    void update(int id, String data);
}

class MySQLDatabase implements DatabaseOperations {
    @Override
    public void connect() {
        System.out.println("Connected to MySQL");
    }

    @Override
    public void disconnect() {
        System.out.println("Disconnected from MySQL");
    }

    @Override
    public void insert(String data) {
        System.out.println("MySQL: Inserting " + data);
    }

    @Override
    public void delete(int id) {
        System.out.println("MySQL: Deleting record " + id);
    }

    @Override
    public void update(int id, String data) {
        System.out.println("MySQL: Updating record " + id + " with " + data);
    }
}

class MongoDatabase implements DatabaseOperations {
    @Override
    public void connect() {
        System.out.println("Connected to MongoDB");
    }

    @Override
    public void disconnect() {
        System.out.println("Disconnected from MongoDB");
    }

    @Override
    public void insert(String data) {
        System.out.println("MongoDB: Inserting " + data);
    }

    @Override
    public void delete(int id) {
        System.out.println("MongoDB: Deleting document " + id);
    }

    @Override
    public void update(int id, String data) {
        System.out.println("MongoDB: Updating document " + id + " with " + data);
    }
}

public class Main {
    public static void main(String[] args) {
        DatabaseOperations db = new MySQLDatabase();
        db.connect();
        db.insert("User data");
        db.update(1, "Updated data");
        db.disconnect();

        System.out.println();

        db = new MongoDatabase();
        db.connect();
        db.insert("Document data");
        db.delete(2);
        db.disconnect();
    }
}

Partial Implementation

If class doesn’t implement all methods, it must be abstract.

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

abstract class Pet implements Animal {
    @Override
    public void sleep() {
        System.out.println("Pet is sleeping");
    }

    // eat() and sound() not implemented - abstract class
}

class Dog extends Pet {
    @Override
    public void eat() {
        System.out.println("Dog eats");
    }

    @Override
    public void sound() {
        System.out.println("Bark");
    }
}

Nested Interfaces

class Outer {
    interface Inner {
        void display();
    }
}

class Test implements Outer.Inner {
    @Override
    public void display() {
        System.out.println("Nested interface");
    }
}

public class Main {
    public static void main(String[] args) {
        Outer.Inner obj = new Test();
        obj.display();
    }
}

Common Java Interfaces

  1. Comparable: Compare objects
  2. Comparator: Custom comparison
  3. Serializable: Object serialization
  4. Cloneable: Object cloning
  5. Runnable: Threading
  6. Iterable: Iteration

Quick Reference

// Define interface
interface MyInterface {
    // Abstract method
    void method1();

    // Constant
    int CONSTANT = 100;
}

// Implement interface
class MyClass implements MyInterface {
    @Override
    public void method1() {
        // Implementation
    }
}

// Multiple interfaces
class MyClass implements Interface1, Interface2 {
    // Implement all methods
}

// Interface inheritance
interface Child extends Parent {
    // Additional methods
}

// Use interface as type
MyInterface obj = new MyClass();
obj.method1();

Rules Summary

  1. All methods public abstract (default)
  2. All variables public static final
  3. Cannot create interface object
  4. Must implement all methods (or be abstract)
  5. implements keyword for classes
  6. extends keyword for interfaces
  7. Multiple interfaces allowed
  8. Methods must be public in implementing class

Exam Tips

Remember:

  1. Interface is a contract
  2. All methods are abstract (by default)
  3. All variables are constants
  4. Cannot instantiate interface
  5. Use implements keyword
  6. Multiple inheritance allowed
  7. Must override all methods
  8. Methods must be public
  9. Interface extends interface
  10. Used for abstraction and polymorphism

Common Questions:

  • What is interface?
  • How to define interface?
  • Interface vs abstract class?
  • Can interface have variables?
  • Can we create interface object?
  • How to implement interface?
  • Can class implement multiple interfaces?
  • What is marker interface?
  • Why use interfaces?
  • Rules for interface methods?