- 1Java OOP Introduction
- 2Java Class
- 3Java Class Constructor
- 4Java Class Objects
- 5Java Access Modifiers
- 6Java Static Variables in Classes
- 7Java Static Methods Explained
- 8Java Static Blocks
- 9Java final Variables
- 10Java final Methods
- 11Java final class
- 12Inheritance in Java
- 13Java Method Overriding
- 14Java Abstraction in OOP
- 15Interfaces in Java
- 16Polymorphism in Java
- 17Encapsulation in Java
- 18Java Nested Classes
- 19Java Nested Static Class
- 20Java Anonymous Class
- 21Java Singleton Class
- 22Java Enums
- 23Reflection in Java
Interfaces in Java
A Java Interface is a blueprint for a class. It defines what a class must do, but not how it should do it. Think of it as a contract — any class that signs this contract must fulfill its promises (implement the methods declared in the interface).
Interfaces help achieve abstraction and multiple inheritance.
Why Use Interfaces in Java?
Interfaces in Java are not just a technical feature; they represent a powerful design choice that guides how your code is structured and how different parts of your application communicate. Here’s why interfaces matter:
To Achieve Full Abstraction
One of the primary reasons to use interfaces is to achieve complete abstraction. Unlike abstract classes, which can contain both implemented and non-implemented methods, interfaces (at least before Java 8) allow only method declarations. This means you’re defining what an object should do—not how it should do it.
By doing this, you’re creating a clean, minimal contract that any implementing class must fulfill. The details are left to the individual classes, giving your code more clarity, modularity, and consistency.
To Support Multiple Inheritance
Java doesn’t support multiple inheritance with classes to avoid the infamous “Diamond Problem.” But interfaces are the workaround. A class in Java can implement multiple interfaces, effectively inheriting behavior from multiple sources—without the ambiguity of conflicting implementations.
This enables powerful design patterns where one class can simultaneously behave like multiple types. It’s one of the key reasons interfaces are used extensively in large-scale Java systems.
To Decouple Code and Enhance Flexibility
Interfaces help in reducing the tight coupling between different components of your code. When one part of your system interacts with another through an interface, it doesn’t need to know the actual implementation—it just relies on the contract.
This decoupling makes your code more flexible and easier to test, extend, or replace. You can switch out the implementation without changing the interface, which is especially useful in large teams, enterprise-level systems, or when applying design patterns like Strategy, Dependency Injection, or Factory.
Declaring an Interface
Use the interface
keyword:
interface Animal {
void makeSound();
}
Here, makeSound()
is an abstract method — it has no body. Any class that implements Animal
must provide its own version of makeSound()
.
Implementing an Interface
class Dog implements Animal {
public void makeSound() {
System.out.println("Bark");
}
}
Output:
Bark
The Dog
class implements Animal
and provides its own behavior for makeSound()
.
Multiple Interfaces
A class can implement more than one interface. This is how Java achieves multiple inheritance.
interface Walkable {
void walk();
}
interface Swimmable {
void swim();
}
class Duck implements Walkable, Swimmable {
public void walk() {
System.out.println("Duck walks");
}
public void swim() {
System.out.println("Duck swims");
}
}
Output:
Duck walks
Duck swims
Interface Variables and Methods
- All variables in an interface are
public static final
(constants) - All methods are
public abstract
by default (until Java 8)
interface Constants {
int MAX_USERS = 100;
}
You can access MAX_USERS
like this:
System.out.println(Constants.MAX_USERS);
Default and Static Methods in Interfaces (Java 8+)
From Java 8 onward, interfaces can also have default
and static
methods with bodies.
interface Vehicle {
default void start() {
System.out.println("Starting vehicle...");
}
static void info() {
System.out.println("Vehicle Interface");
}
}
class Car implements Vehicle {}
Usage:
Car c = new Car();
c.start(); // default method
Vehicle.info(); // static method
Output:
Starting vehicle...
Vehicle Interface
Marker Interfaces
A Marker Interface is an interface with no methods or fields. It acts as a tag for the class.
interface Serializable {} // Java’s built-in marker interface
Functional Interfaces (Java 8+)
Interfaces with exactly one abstract method are called Functional Interfaces. They enable usage with lambda expressions.
@FunctionalInterface
interface Calculator {
int operate(int a, int b);
}
Used like this:
Calculator add = (a, b) -> a + b;
System.out.println(add.operate(5, 3));
Output:
8
Key Takeaways
- Interfaces define contracts without implementation (until Java 8 added default/static methods)
- They support multiple inheritance in Java
- Interfaces improve modularity, flexibility, and testability of code
- From Java 8, interfaces can have default and static methods
- Functional interfaces simplify functional programming in Java
When to Use Interfaces
Use an interface when:
- You need to define behavior without tying to a concrete class
- You expect multiple, unrelated classes to implement the same behavior
- You want to take advantage of polymorphism and dependency injection
QUIZ
Question 1:What keyword is used to define an interface in Java?
Question 2:A Java class can implement multiple interfaces.
Question 3:Which of the following are characteristics of a Java interface before Java 8?
Question 4:What will be the output of the following code?
interface Animal {
void makeSound();
}
class Dog implements Animal {
public void makeSound() {
System.out.println("Bark");
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Dog();
a.makeSound();
}
}
interface Animal {
void makeSound();
}
class Dog implements Animal {
public void makeSound() {
System.out.println("Bark");
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Dog();
a.makeSound();
}
}