Java is a powerful and versatile programming language. It supports object-oriented programming through features like classes and interfaces. In this tutorial, you’ll learn Java interfaces, how to use them, and why they’re essential.
What Is a Java Interface?
A Java interface defines a contract. It specifies methods that a class must implement. Think of it as a blueprint. It tells the class what to do but not how to do it.
Interfaces do not contain method bodies. Instead, they list method signatures. This allows different classes to implement the same methods in other ways.
Here’s a simple example:
interface Animal {
void makeSound();
}The Animal interface defines one method: makeSound(). Any class that implements this interface must define that method.
Why Use Interfaces in Java?
Interfaces allow you to achieve abstraction. You can hide the implementation details and focus on what a class should do.
They also help with polymorphism. You can use interfaces to create flexible and reusable code. For example, if multiple classes implement the same interface, you can treat them similarly.
Here’s a benefit in action:
public class Dog implements Animal {
public void makeSound() {
System.out.println("Woof");
}
}
public class Cat implements Animal {
public void makeSound() {
System.out.println("Meow");
}
}Now, you can write:
Animal myPet = new Dog(); myPet.makeSound(); // Output: Woof
Later, you can switch to:
myPet = new Cat(); myPet.makeSound(); // Output: Meow
Declaring an Interface in Java
To declare an interface, use the interface keyword:
public interface Vehicle {
void start();
void stop();
}The Vehicle interface declares two methods. Any class that implements Vehicle both methods must provide concrete implementations.
Implementing an Interface
To use an interface, a class must implement it using the implements Keyword:
public class Car implements Vehicle {
public void start() {
System.out.println("Car starts");
}
public void stop() {
System.out.println("Car stops");
}
}If the class does not implement all the interface methods, it must be declared abstract.
Interface vs Abstract Class
You might wonder: Why use an interface when abstract classes exist?
Here’s the difference:
- A class can implement multiple interfaces.
- A class can extend only one abstract class.
- Interfaces cannot have constructors.
- Interfaces define only method signatures (until Java 8 and later).
Use interfaces when you need to enforce behavior across unrelated classes. Use abstract classes when you have shared code or state that needs to be reused across multiple classes.
Java Interface and Multiple Inheritance
Java does not support multiple inheritance with classes. But it does with interfaces.
A class can implement multiple interfaces:
interface Camera {
void takePhoto();
}
interface GPS {
void navigate();
}
class Smartphone implements Camera, GPS {
public void takePhoto() {
System.out.println("Photo taken");
}
public void navigate() {
System.out.println("Navigating to destination");
}
}Here, Smartphone inherits behavior from both Camera and GPS.
Default Methods in Interfaces (Java 8+)
Before Java 8, interfaces could only have abstract methods. Java 8 introduced default methods. These have a method body and provide default behavior.
Example:
interface Message {
default void greet() {
System.out.println("Hello");
}
void send();
}Now, any class implementing Message gets a default greet() method.
class Email implements Message {
public void send() {
System.out.println("Sending Email");
}
}You can override the default method if needed.
Static Methods in Interfaces
Java 8 also introduced static methods in interfaces.
Example:
interface Calculator {
static int add(int a, int b) {
return a + b;
}
}To use this method, call it with the interface name:
int result = Calculator.add(3, 4); System.out.println(result); // Output: 7
Functional Interfaces and Lambda Expressions
A functional interface is an interface with only one abstract method. These are used in lambda expressions.
Example of a Printer:
@FunctionalInterface
interface Printer {
void print(String message);
}You can use a lambda like this:
Printer p = msg -> System.out.println(msg);
p.print("Hello with Lambda");Output
Hello with Lambda
Example of a Calculator:
@FunctionalInterface
public interface Calculator {
int operation(int a, int b);
}You can use a lambda like this:
public class FunctionalInterfaceExample {
public static void main(String[] args) {
Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;
System.out.println("Addition: " + add.operation(5, 3));
System.out.println("Multiplication: " + multiply.operation(5, 3));
}
}Output
Addition: 8 Multiplication: 15
Java has built-in functional interfaces in the java.util.function package, like Predicate, Function, and Consumer.
Example using Predicate<T>
Predicate<T> is a functional interface that takes a single argument and returns a boolean.
import java.util.function.Predicate;
public class PredicateExample {
public static void main(String[] args) {
Predicate<String> isNotEmpty = str -> str != null && !str.isEmpty();
System.out.println(isNotEmpty.test("Hello")); // true
System.out.println(isNotEmpty.test("")); // false
System.out.println(isNotEmpty.test(null)); // false
}
}Example using Function<T, R>
Function<T, R> takes one argument of type T and returns a result of type R.
import java.util.function.Function;
public class FunctionExample {
public static void main(String[] args) {
Function<String, Integer> stringLength = str -> str.length();
System.out.println(stringLength.apply("OpenAI")); // 6
System.out.println(stringLength.apply("ChatGPT")); // 7
}
}Marker Interfaces
A marker interface has no methods or fields. It marks a class with metadata.
Example:
interface Serializable {
}Classes that implement Serializable can be serialized. The JVM uses this information at runtime.
Interface Inheritance
An interface can extend another interface. This allows you to build hierarchies.
interface Readable {
void read();
}
interface Writable extends Readable {
void write();
}A class that implements Writable both read() and write().
Best Practices When Using Interfaces
- Use interfaces to define behavior, not state.
- Favor interfaces over abstract classes when possible.
- Use meaningful method names to describe the contract.
- Document the purpose of each interface.
- Avoid using interfaces for constants; instead, use enums or a separate class.
Conclusion
Interfaces play a crucial role in Java. They provide abstraction, enable polymorphism, and support multiple inheritance. With default and static methods, they are now more powerful than ever. Use interfaces to write clean, modular, and scalable Java code.
This article was originally published on Medium.



