[!NOTE] We learned earlier that Java enforces strict Single Inheritance. A child class can only
extendexactly ONE parent class. But what if yourBirdclass needs to inherit fromAnimal, but also needs to inherit a bunch of flying logic from aFlyableclass?
We solve this problem using Interfaces.
What is an Interface?
An Interface is an extreme version of an Abstract Class. Historically (prior to Java 8), an interface could only contain pure abstract methods and constant variables. It represents a strict "Contract of Behavior".
Instead of a class extending an interface, a class implements an interface. And unlike strict single inheritance, a class can implement an infinite number of interfaces simultaneously!
// 1. Defining Interfaces (Contracts)
interface Flyable {
void fly(); // Naturally abstract and public, even if we don't type it!
}
interface Swimable {
void swim();
}
// 2. A normal Parent Class
class Animal {
void sleep() { System.out.println("Zz"); }
}
// 3. The Ultimate Child Class
// It extends ONE parent, but implements TWO interfaces!
class Duck extends Animal implements Flyable, Swimable {
// Contract fulfillment: Must provide flight code!
public void fly() {
System.out.println("The duck flies awkwardly over the lake.");
}
// Contract fulfillment: Must provide swim code!
public void swim() {
System.out.println("The duck paddles in the water.");
}
}
Why Use Interfaces?
Interfaces decouple "what an object is" from "what an object can do".
A Helicopter is absolutely NOT an Animal. It makes zero sense for a Helicopter class to inherit from Animal. However, both a Helicopter and a Duck can fly. They share a behavioral capability.
If you have a video game function that accepts anything that can fly, you can use the Interface as the expected data type!
public class GameEngine {
// This method accepts ANYTHING that implements the Flyable interface!
// It doesn't care if it's a Duck, a Helicopter, or a MagicCarpet!
public void triggerTakeoff(Flyable target) {
target.fly();
}
}
[!TIP] Modern Java Updates: Since Java 8, interfaces are actually allowed to have
defaultmethods with real body implementations. This was added to allow architects to upgrade massive enterprise interfaces without breaking millions of legacy applications that hadn't written overrides for the new methods.