Java Interfaces
An interface in Java is a completely abstract type that defines a contract — a set of methods that any class implementing the interface must provide. Interfaces achieve 100% abstraction (prior to Java 8) and enable multiple inheritance in Java.
Think of an interface as a job description. It states what needs to be done but not how to do it. Any class that "takes the job" (implements the interface) must fulfill all requirements.
Why Use Interfaces?
- Achieve full abstraction — define what a class must do without specifying how.
- Enable multiple inheritance — a class can implement multiple interfaces.
- Define a common contract across unrelated classes.
- Support loose coupling — program to an interface, not to an implementation.
Defining an Interface
interface InterfaceName {
// abstract method (no body)
returnType methodName(parameters);
// constants
static final dataType CONSTANT_NAME = value;
}All methods in an interface are implicitly public and abstract. All fields are implicitly public, static, and final.
Implementing an Interface
A class uses the implements keyword to adopt an interface. It must provide a concrete implementation for every method declared in the interface.
interface Drawable {
void draw();
void resize(int factor);
}
class Circle implements Drawable {
@Override
public void draw() {
System.out.println("Drawing a Circle.");
}
@Override
public void resize(int factor) {
System.out.println("Resizing Circle by factor: " + factor);
}
}
class Rectangle implements Drawable {
@Override
public void draw() {
System.out.println("Drawing a Rectangle.");
}
@Override
public void resize(int factor) {
System.out.println("Resizing Rectangle by factor: " + factor);
}
}
public class Main {
public static void main(String[] args) {
Drawable d1 = new Circle();
Drawable d2 = new Rectangle();
d1.draw();
d1.resize(2);
d2.draw();
d2.resize(3);
}
}Output:
Drawing a Circle.
Resizing Circle by factor: 2
Drawing a Rectangle.
Resizing Rectangle by factor: 3Implementing Multiple Interfaces
Unlike class inheritance, a class can implement multiple interfaces. This is how Java supports a form of multiple inheritance.
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
class Duck implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("Duck is flying.");
}
@Override
public void swim() {
System.out.println("Duck is swimming.");
}
}
public class Main {
public static void main(String[] args) {
Duck duck = new Duck();
duck.fly();
duck.swim();
}
}Output:
Duck is flying.
Duck is swimming.Interface Extending Another Interface
An interface can extend one or more other interfaces using the extends keyword.
interface Animal {
void eat();
}
interface Pet extends Animal {
void play();
}
class Dog implements Pet {
@Override
public void eat() {
System.out.println("Dog is eating.");
}
@Override
public void play() {
System.out.println("Dog is playing.");
}
}
public class Main {
public static void main(String[] args) {
Dog d = new Dog();
d.eat();
d.play();
}
}Default Methods in Interfaces (Java 8+)
Since Java 8, interfaces can have default methods — methods with a body. This allows adding new functionality to existing interfaces without breaking classes that already implement them.
interface Greeting {
void sayHello(String name);
// Default method with implementation
default void sayGoodbye(String name) {
System.out.println("Goodbye, " + name + "!");
}
}
class FormalGreeting implements Greeting {
@Override
public void sayHello(String name) {
System.out.println("Good day, " + name + ".");
}
}
public class Main {
public static void main(String[] args) {
FormalGreeting g = new FormalGreeting();
g.sayHello("Mr. Smith");
g.sayGoodbye("Mr. Smith"); // uses default method
}
}Output:
Good day, Mr. Smith.
Goodbye, Mr. Smith!Static Methods in Interfaces (Java 8+)
Interfaces can also have static methods, which belong to the interface itself and cannot be overridden.
interface Validator {
boolean validate(String input);
static boolean isNotEmpty(String input) {
return input != null && !input.isEmpty();
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Validator.isNotEmpty("Hello")); // true
System.out.println(Validator.isNotEmpty("")); // false
}
}Interface vs Abstract Class
| Feature | Interface | Abstract Class |
|---|---|---|
| Keyword | interface / implements | abstract / extends |
| Multiple inheritance | Yes (can implement many) | No (only one parent class) |
| Constructor | Not allowed | Allowed |
| Fields | Only constants (public static final) | Any type |
| Methods | Abstract + default + static | Abstract + concrete |
| Use when | Defining a contract across unrelated classes | Sharing code among closely related classes |
Functional Interfaces (Java 8+)
An interface with exactly one abstract method is called a functional interface. These are used with lambda expressions (covered later). The @FunctionalInterface annotation ensures the interface has only one abstract method.
@FunctionalInterface
interface MathOperation {
int operate(int a, int b);
}
public class Main {
public static void main(String[] args) {
MathOperation add = (a, b) -> a + b;
MathOperation multiply = (a, b) -> a * b;
System.out.println("Add: " + add.operate(5, 3)); // 8
System.out.println("Multiply: " + multiply.operate(4, 6)); // 24
}
}Summary
- An interface is a contract that defines methods a class must implement.
- Interfaces are implemented using the
implementskeyword. - A class can implement multiple interfaces, enabling a form of multiple inheritance.
- All interface methods are public and abstract by default (unless default or static).
- Java 8 introduced default and static methods in interfaces.
- Functional interfaces have exactly one abstract method and work with lambda expressions.
