# Interfaces

Course: [Java](https://www.devtutorials.ai/learn/java) · Section: Object-Oriented Programming
Source: https://www.devtutorials.ai/learn/java/object-oriented-programming/interfaces

> Describe abilities with interfaces: declare and implement them, implement several at once, add default and static methods, and use functional interfaces with lambdas.

Think about a wall socket.

Any device with the right plug can use it: a phone charger, a lamp, a fan. The socket does not care what the device is. It only cares that the plug has the right shape.

The socket is like a promise: "If you have this kind of plug, you can connect here."

In Java, an interface is that kind of promise. It lists the methods a class must have. Any class that keeps the promise can be used wherever the interface is expected.

In simple words: an interface says what a class can do, without saying how it does it.

## What You Will Learn

In this lesson, you will learn:

1. What an interface is, and why it is useful.
2. How to declare an interface and its methods.
3. How interface constants work.
4. How a class implements an interface.
5. How one class can implement several interfaces.
6. How default and static methods add code to an interface.
7. What a functional interface is, and how it works with lambdas.
8. How interfaces compare with abstract classes.

## Start With a Working Example

Press **Run**.

```java runnable title="Three different classes keep the same promise"
public class Main {
    public static void main(String[] args) {
        Notifier[] channels = {
            new EmailNotifier(),
            new SmsNotifier(),
            new AppNotifier()
        };

        for (Notifier n : channels) {
            n.send("Your order has shipped");
        }
    }
}

interface Notifier {
    void send(String message);
}

class EmailNotifier implements Notifier {
    public void send(String message) {
        System.out.println("Email: " + message);
    }
}

class SmsNotifier implements Notifier {
    public void send(String message) {
        System.out.println("SMS: " + message);
    }
}

class AppNotifier implements Notifier {
    public void send(String message) {
        System.out.println("App alert: " + message);
    }
}
```

Expected output:

```text
Email: Your order has shipped
SMS: Your order has shipped
App alert: Your order has shipped
```

The loop does not know or care which kind of notifier it has. It only knows that every `Notifier` has a `send()` method.

### Try This

Write a fourth class, `WhatsAppNotifier`, that implements `Notifier`. Add it to the array. The loop needs no change.

## Introduction to Interfaces

An **interface** is a type that lists methods a class must provide. It describes a **capability**, such as "can send a message" or "can be compared".

When a class **implements** an interface, it promises to write every one of those methods.

This gives you two big benefits:

- **Swappable parts.** Code that uses `Notifier` works with email, SMS or any future channel. You can switch one for another without touching that code.
- **Shared ability across unrelated classes.** A `Car` and a `Phone` have nothing in common, but both can implement `Chargeable`.

Think of a job advert that says "must be able to drive". It does not care who you are. It only cares that you have that ability.

## Interface Declaration

You declare an interface with the `interface` keyword.

```text
interface Shape {
    double area();
    double perimeter();
}
```

Interface names often describe an ability: `Comparable`, `Runnable`, `Printable`. Like classes, they use PascalCase.

You cannot create an object of an interface directly. `new Shape()` does not compile, because an interface has no full method bodies to run.

## Interface Methods

A plain method in an interface has **no body**. It ends with a semicolon.

```text
double area();
```

This is called an **abstract method**. It says "every class that implements me must write this".

Interface methods are automatically `public` and `abstract`. You do not need to write those words.

## Interface Constants

An interface can hold fields. Every field in an interface is automatically `public`, `static` and `final`. In other words, every field is a **constant**.

```java runnable title="Fields in an interface are shared constants"
public class Main {
    public static void main(String[] args) {
        System.out.println("Max file size: " + Uploadable.MAX_SIZE_MB + " MB");

        Photo p = new Photo(8);
        Photo big = new Photo(40);

        System.out.println("8 MB photo allowed? " + p.canUpload());
        System.out.println("40 MB photo allowed? " + big.canUpload());
    }
}

interface Uploadable {
    int MAX_SIZE_MB = 25;

    boolean canUpload();
}

class Photo implements Uploadable {
    int sizeMb;

    Photo(int sizeMb) {
        this.sizeMb = sizeMb;
    }

    public boolean canUpload() {
        return sizeMb <= MAX_SIZE_MB;
    }
}
```

Expected output:

```text
Max file size: 25 MB
8 MB photo allowed? true
40 MB photo allowed? false
```

`MAX_SIZE_MB` is a constant. You can read it as `Uploadable.MAX_SIZE_MB`, and `Photo` can use it directly because it implements the interface.

You cannot change it. `Uploadable.MAX_SIZE_MB = 50;` does not compile.

## Interface Implementation

A class uses the `implements` keyword to keep an interface's promise.

The class must then write a body for **every** abstract method in the interface. If it misses one, it does not compile.

The methods must be `public`, because interface methods are public.

```java runnable title="Each shape works out its own area"
public class Main {
    public static void main(String[] args) {
        Shape[] shapes = { new Circle(7), new Square(5) };

        for (Shape s : shapes) {
            System.out.println(s.name() + " area: " + s.area());
        }
    }
}

interface Shape {
    double area();
    String name();
}

class Circle implements Shape {
    double radius;

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

    public double area() {
        return 3.14 * 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";
    }
}
```

Expected output:

```text
Circle area: 153.86
Square area: 25.0
```

A `Shape` variable can hold a `Circle` or a `Square`. When you call `s.area()`, Java runs the version for that actual object.

Forgetting `public` on an implemented method is a very common error. Writing `double area()` without `public` gives `attempting to assign weaker access privileges; was public`.

## Multiple Interface Implementation

A class can only have **one** parent class. But it can implement **many** interfaces. You separate them with commas.

```text
class SmartPhone implements Camera, MusicPlayer, Phone { ... }
```

This is how Java lets one class have many abilities.

Think of a person who can drive, cook and swim. Each skill is separate, and one person can have all of them.

```java runnable title="One class, three abilities"
public class Main {
    public static void main(String[] args) {
        SmartPhone phone = new SmartPhone();

        phone.call("98765 43210");
        phone.takePhoto();
        phone.play("Jai Ho");

        Camera cam = phone;
        cam.takePhoto();
    }
}

interface Callable {
    void call(String number);
}

interface Camera {
    void takePhoto();
}

interface MusicPlayer {
    void play(String song);
}

class SmartPhone implements Callable, Camera, MusicPlayer {
    public void call(String number) {
        System.out.println("Calling " + number);
    }

    public void takePhoto() {
        System.out.println("Click! Photo saved.");
    }

    public void play(String song) {
        System.out.println("Playing " + song);
    }
}
```

Expected output:

```text
Calling 98765 43210
Click! Photo saved.
Playing Jai Ho
Click! Photo saved.
```

`SmartPhone` keeps all three promises. So a `SmartPhone` can be stored in a `Camera` variable, a `Callable` variable or a `MusicPlayer` variable.

Through the `Camera` variable `cam`, only `takePhoto()` is visible. The variable's type decides which methods you can call.

A variable of an interface type can only call the methods that interface declares. In the example above, `cam.call(...)` would not compile, even though the object is a `SmartPhone`.

## Default Methods

Since Java 8, an interface can contain a **default method**. A default method **has a body**. Classes that implement the interface get it for free.

You mark it with the `default` keyword.

A class can still write its own version of a default method if it needs different behaviour. This is called **overriding** it.

Why default methods exist: if you add a new abstract method to an interface that 100 classes already use, all 100 classes break. A default method adds new behaviour without breaking anyone.

```java runnable title="A default method gives every class the same extra behaviour"
public class Main {
    public static void main(String[] args) {
        Greeter english = new EnglishGreeter();
        Greeter hindi = new HindiGreeter();

        english.greetTwice("Asha");
        hindi.greetTwice("Ravi");
    }
}

interface Greeter {
    String greet(String name);

    default void greetTwice(String name) {
        System.out.println(greet(name));
        System.out.println(greet(name));
    }
}

class EnglishGreeter implements Greeter {
    public String greet(String name) {
        return "Hello, " + name;
    }
}

class HindiGreeter implements Greeter {
    public String greet(String name) {
        return "Namaste, " + name;
    }

    public void greetTwice(String name) {
        System.out.println(greet(name) + " (twice!)");
    }
}
```

Expected output:

```text
Hello, Asha
Hello, Asha
Namaste, Ravi (twice!)
```

`EnglishGreeter` did not write `greetTwice()`. It used the default version from the interface.

`HindiGreeter` wrote its own `greetTwice()`, which replaced the default.

## Static Methods in Interfaces

An interface can also have **static methods**. They belong to the interface itself, like static methods in a class.

You call them with the interface name: `InterfaceName.method()`.

Use them for helpers that belong with the interface, such as a method that checks or creates values.

```java runnable title="A static helper that lives on the interface"
public class Main {
    public static void main(String[] args) {
        System.out.println(Validator.isValidEmail("asha@mail.com"));
        System.out.println(Validator.isValidEmail("asha.mail.com"));
        System.out.println(Validator.isValidPin("560001"));
    }
}

interface Validator {
    static boolean isValidEmail(String email) {
        return email.contains("@") && email.contains(".");
    }

    static boolean isValidPin(String pin) {
        return pin.length() == 6;
    }
}
```

Expected output:

```text
true
false
true
```

No class implements `Validator` here. The static methods are called directly through the interface name.

Unlike default methods, static interface methods are **not** inherited by classes. You must always call them through the interface name.

## Functional Interfaces

A **functional interface** is an interface with **exactly one** abstract method. It can still have default and static methods.

You can mark one with `@FunctionalInterface`. The compiler then checks that it really has only one abstract method.

Functional interfaces are special because you can implement them with a **lambda expression**. A lambda is a short way to write a method with no name:

```text
(parameters) -> expression
```

Instead of writing a whole class, you write just the method's body.

```java runnable title="Lambdas implement a one-method interface in one line"
public class Main {
    public static void main(String[] args) {
        Calculator add = (a, b) -> a + b;
        Calculator multiply = (a, b) -> a * b;
        Calculator biggest = (a, b) -> a > b ? a : b;

        System.out.println("Add: " + add.compute(6, 4));
        System.out.println("Multiply: " + multiply.compute(6, 4));
        System.out.println("Biggest: " + biggest.compute(6, 4));
    }
}

@FunctionalInterface
interface Calculator {
    int compute(int a, int b);
}
```

Expected output:

```text
Add: 10
Multiply: 24
Biggest: 6
```

Each lambda becomes an object that implements `Calculator`. `(a, b) -> a + b` is the body of `compute()`.

Java comes with many ready-made functional interfaces in `java.util.function`:

| Interface | Method | Takes | Returns | Example use |
|---|---|---|---|---|
| `Predicate<T>` | `test` | One value | `boolean` | Is this number even? |
| `Function<T, R>` | `apply` | One value | Another value | Turn a name into its length |
| `Consumer<T>` | `accept` | One value | Nothing | Print a value |
| `Supplier<T>` | `get` | Nothing | One value | Make a new default object |

```java runnable title="Java's built-in functional interfaces"
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        Predicate<Integer> isAdult = age -> age >= 18;
        Function<String, Integer> length = text -> text.length();
        Consumer<String> shout = text -> System.out.println(text.toUpperCase() + "!");

        System.out.println(isAdult.test(21));
        System.out.println(length.apply("Chennai"));
        shout.accept("welcome");
    }
}
```

Expected output:

```text
true
7
WELCOME!
```

The `<Integer>` and `<String>` parts say which types the interface works with. You will learn about these, called **generics**, in a later chapter.

## Interfaces vs Abstract Classes

An **abstract class** is a class that cannot be created directly and may contain abstract methods. You will study it fully in the Abstraction lesson. Here is how it compares:

| | Interface | Abstract class |
|---|---|---|
| Keyword to use it | `implements` | `extends` |
| How many can a class use? | Many | Only one |
| Fields | Constants only (`public static final`) | Any fields, including ones that change |
| Constructors | No | Yes |
| Methods with bodies | `default` and `static` only | Any |
| Method access | `public` (or `private` helpers) | Any access level |
| Describes | What a class **can do** | What a class **is** |
| Example | `Comparable`, `Runnable` | `Animal`, `Vehicle` |

**Easy Way to Remember:** an interface is a **can-do** list. An abstract class is a **half-built** parent. Use an interface to share an ability. Use an abstract class to share code and fields between closely related classes.

## Common mistakes

The following mistakes are common when writing and implementing interfaces. Each row shows what you see, why it happens and how to fix it.

| Symptom | Cause | Fix |
|---|---|---|
| `weaker access privileges; was public` | An implemented method is not `public` | Add `public` |
| `does not override abstract method` | A required method was not written | Write every abstract method |
| `is abstract; cannot be instantiated` | `new` was used on an interface | Create an object of an implementing class |
| `no interface expected here` | `extends` was used with an interface | Use `implements` |
| `cannot assign a value to final variable` | An interface constant was changed | Treat interface fields as read-only |
| `cannot find symbol` when calling a static interface method on an object | Static interface methods are not inherited | Call it as `InterfaceName.method()` |

## What to Remember

- An interface lists methods a class promises to provide. It describes what a class can do.
- Interface methods with no body are abstract and `public`. Interface fields are constants.
- A class uses `implements` and must write every abstract method, marked `public`.
- A class can implement many interfaces, but can extend only one class.
- Default methods give interfaces ready-made behaviour. Static methods are called through the interface name.
- A functional interface has exactly one abstract method and can be implemented with a lambda.
- Use an interface for a shared ability. Use an abstract class for shared code and fields.

Next: Inheritance
