Using an Interface as a Type

An interface is also a reference data type, just like a class.

Interface type → can refer to any object whose class implements that interface.


1. Interface as a Type

interface Flyable {
    void fly();
}

class Bird implements Flyable {
    public void fly() {
        System.out.println("Bird is flying");
    }
}

You can use Flyable as a variable type:

Flyable bird = new Bird();

Here:

Reference type → Flyable
Actual object  → Bird

2. Why Is This Useful?

You don't need to care about the specific class.

Flyable animal = new Bird();

animal.fly();

The variable only cares that the object is Flyable.

Another class can also implement it:

class Airplane implements Flyable {
    public void fly() {
        System.out.println("Airplane is flying");
    }
}

Now:

Flyable a = new Bird();
Flyable b = new Airplane();

a.fly(); // Bird is flying
b.fly(); // Airplane is flying

Same interface type, different objects.


3. Interface as a Method Parameter

You can use an interface as a parameter type.

void makeFly(Flyable object) {
    object.fly();
}

Now you can pass any object that implements Flyable:

makeFly(new Bird());
makeFly(new Airplane());

This makes the method reusable.


4. Interface as a Return Type

An interface can also be the return type.

Flyable createBird() {
    return new Bird();
}

Then:

Flyable bird = createBird();

bird.fly();

The method promises:

"I will return something that is Flyable."

It doesn't matter which implementing class it actually returns.


5. Interface Gives Multiple Types

A class can implement multiple interfaces.

interface Flyable {
    void fly();
}

interface Swimmable {
    void swim();
}

class Duck implements Flyable, Swimmable {

    public void fly() {
        System.out.println("Flying");
    }

    public void swim() {
        System.out.println("Swimming");
    }
}

A Duck can now be treated as:

Duck duck = new Duck();

Flyable f = duck;
Swimmable s = duck;

So the same object has multiple reference types:

Duck
 ├── Flyable
 └── Swimmable

6. Interface Type Makes Code Flexible

Instead of:

void makeFly(Bird bird) {
    bird.fly();
}

use:

void makeFly(Flyable object) {
    object.fly();
}

Now the method works with:

makeFly(new Bird());
makeFly(new Airplane());

without changing the method.

Program against the interface, not the specific implementation.


7. Important Point About Casting

Suppose you have:

Object obj = new Bird();

The reference type is Object, so you cannot directly call:

obj.fly(); // ERROR

You can cast it:

Flyable f = (Flyable) obj;

f.fly();

But only do this if the object actually implements Flyable.

You can check first:

if (obj instanceof Flyable) {
    Flyable f = (Flyable) obj;
    f.fly();
}

Quick Revision

Concept Meaning
Interface as type Interface can be used as a variable/parameter/return type
Interface reference Can point to an object of an implementing class
Multiple types One class can implement multiple interfaces
Parameter Makes methods work with different implementations
Return type Can return any implementing class
Polymorphism Interface reference can represent different objects
Casting Converts another reference type to interface type

Most important example

interface Flyable {
    void fly();
}

class Bird implements Flyable {
    public void fly() {
        System.out.println("Flying");
    }
}

class Airplane implements Flyable {
    public void fly() {
        System.out.println("Flying");
    }
}

Now:

Flyable a = new Bird();
Flyable b = new Airplane();

a.fly();
b.fly();

Interface as a type means you can write code based on what an object can do, rather than what specific class it belongs to.