For working professionals
For fresh graduates
More
6. JDK in Java
7. C++ Vs Java
16. Java If-else
18. Loops in Java
20. For Loop in Java
45. Packages in Java
52. Java Collection
55. Generics In Java
56. Java Interfaces
59. Streams in Java
62. Thread in Java
66. Deadlock in Java
73. Applet in Java
74. Java Swing
75. Java Frameworks
77. JUnit Testing
80. Jar file in Java
81. Java Clean Code
85. Java 8 features
86. String in Java
92. HashMap in Java
97. Enum in Java
100. Hashcode in Java
104. Linked List in Java
108. Array Length in Java
110. Split in java
111. Map In Java
114. HashSet in Java
117. DateFormat in Java
120. Java List Size
121. Java APIs
127. Identifiers in Java
129. Set in Java
131. Try Catch in Java
132. Bubble Sort in Java
134. Queue in Java
141. Jagged Array in Java
143. Java String Format
144. Replace in Java
145. charAt() in Java
146. CompareTo in Java
150. parseInt in Java
152. Abstraction in Java
153. String Input in Java
155. instanceof in Java
156. Math Floor in Java
157. Selection Sort Java
158. int to char in Java
163. Deque in Java
171. Trim in Java
172. RxJava
173. Recursion in Java
174. HashSet Java
176. Square Root in Java
189. Javafx
An interface in Java Programming is a blueprint of a class that contains abstract methods, default methods, static methods, and constant declarations. Interfaces are a core concept in Java programming that enables abstraction, multiple inheritance, and polymorphism. Unlike classes, interfaces cannot be instantiated directly; instead, they must be implemented by classes or extended by other interfaces. Understanding interfaces is crucial for creating flexible, maintainable, and scalable Java applications.
In this guide, we'll explore what interfaces are, how to implement them, the different types of interfaces in Java including functional and marker interfaces, and provide practical examples to solidify your understanding. We'll also compare interfaces with abstract classes to help you make informed design decisions in your Java projects.
Code like a pro as upGrad’s software engineering course helps you level up your Java skills with real-world projects and expert coaching.
An interface in Java is essentially a contract that specifies what a class must do, without dictating how it should do it. It provides a way to achieve abstraction by separating what a class does from how it does it. This separation is fundamental to good object-oriented programming.
Take the next step in your tech journey with these top AI and data science courses:
• Master’s in Data Science – LJMU
• M.Sc. in AI & Data Science – Jindal Global University
• PG Diploma in ML & AI – IIIT Bangalore
public interface InterfaceName {
// Constant declarations
type CONSTANT_NAME = value;
// Abstract method declarations
returnType methodName(parameterList);
// Default method (Java 8+)
default returnType methodName(parameterList) {
// Method body
}
// Static method (Java 8+)
static returnType methodName(parameterList) {
// Method body
}
// Private method (Java 9+)
private returnType methodName(parameterList) {
// Method body
}
}
Check out: What Is Externalization In Java? Interface, Features & Example
To use an interface, a class must implement it using the implements keyword and provide concrete implementations of all its abstract methods.
Let's start with a simple example of defining and implementing an interface:
// Define the interface
public interface Drawable {
void draw(); // Abstract method
// Default method (Java 8+)
default void setColor(String color) {
System.out.println("Setting color to: " + color);
}
}
// Implement the interface
public class Circle implements Drawable {
@Override
public void draw() {
System.out.println("Drawing a circle");
}
}
// Usage example
public class Main {
public static void main(String[] args) {
Drawable circle = new Circle();
circle.draw(); // Output: Drawing a circle
circle.setColor("Red"); // Output: Setting color to: Red
}
}
In this example:
One powerful feature of interfaces is that a class can implement multiple interfaces:
// Another interface
public interface Resizable {
void resize(double factor);
}
// Class implementing multiple interfaces
public class Rectangle implements Drawable, Resizable {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("Drawing a rectangle with width: " + width + " and height: " + height);
}
@Override
public void resize(double factor) {
width *= factor;
height *= factor;
System.out.println("Rectangle resized. New dimensions - width: " + width + ", height: " + height);
}
}
// Usage example
public class Main {
public static void main(String[] args) {
Rectangle rectangle = new Rectangle(10, 20);
rectangle.draw(); // Output: Drawing a rectangle with width: 10.0 and height: 20.0
rectangle.resize(1.5); // Output: Rectangle resized. New dimensions - width: 15.0, height: 30.0
rectangle.draw(); // Output: Drawing a rectangle with width: 15.0 and height: 30.0
}
}
This example demonstrates how a single class can implement multiple interfaces, allowing for a flexible and modular design.
Java supports several types of interfaces, each with specific purposes and characteristics.
A functional interface is an interface that contains exactly one abstract method. Functional interfaces are the foundation of lambda expressions in Java 8 and later versions. These interfaces can have any number of default, static, or private methods, but must have only one abstract method.
// A functional interface example
@FunctionalInterface
public interface Calculator {
int calculate(int a, int b);
// Multiple default methods are allowed
default void printInfo() {
System.out.println("This is a calculator interface");
}
}
// Implementation using a class
public class Addition implements Calculator {
@Override
public int calculate(int a, int b) {
return a + b;
}
}
// Usage with lambda expressions
public class Main {
public static void main(String[] args) {
// Traditional way
Calculator addition = new Addition();
System.out.println("10 + 5 = " + addition.calculate(10, 5)); // Output: 10 + 5 = 15
// Using lambda expression
Calculator subtraction = (a, b) -> a - b;
System.out.println("10 - 5 = " + subtraction.calculate(10, 5)); // Output: 10 - 5 = 5
// Using lambda with method reference
Calculator multiplication = (a, b) -> a * b;
System.out.println("10 * 5 = " + multiplication.calculate(10, 5)); // Output: 10 * 5 = 50
}
}
The @FunctionalInterface annotation is not mandatory but it's a good practice to use it as it helps the compiler verify that the interface indeed has only one abstract method.
Some commonly used functional interfaces in Java include:
A marker interface is an interface that has no methods or constants. It serves as a tag to inform the compiler about special handling needed for the implementing class. The marker interface simply "marks" a class as having a certain property.
// Example of a marker interface
public interface Serializable {
// No methods or constants
}
// Another example of a marker interface
public interface Cloneable {
// No methods or constants
}
// Class implementing a marker interface
public class Student implements Serializable {
private String name;
private int id;
public Student(String name, int id) {
this.name = name;
this.id = id;
}
// Getters and setters
}
Some well-known marker interfaces in Java are:
Also read: Serializable Interface in Java
A normal interface is one that has one or more abstract methods. This is the traditional form of interface in Java.
// Example of a normal interface
public interface Shape {
double calculateArea();
double calculatePerimeter();
void display();
}
// Implementing a normal interface
public class Square implements Shape {
private double side;
public Square(double side) {
this.side = side;
}
@Override
public double calculateArea() {
return side * side;
}
@Override
public double calculatePerimeter() {
return 4 * side;
}
@Override
public void display() {
System.out.println("Square with side: " + side);
System.out.println("Area: " + calculateArea());
System.out.println("Perimeter: " + calculatePerimeter());
}
}
// Usage example
public class Main {
public static void main(String[] args) {
Shape square = new Square(5);
square.display();
// Output:
// Square with side: 5.0
// Area: 25.0
// Perimeter: 20.0
}
}
The concept of interfaces in Java has evolved significantly over different Java versions.
Java 8 introduced two major additions to interfaces:
public interface Vehicle {
// Abstract method
void accelerate();
// Default method
default void brake() {
System.out.println("Vehicle is braking");
}
// Static method
static void info() {
System.out.println("Vehicles are used for transportation");
}
}
public class Car implements Vehicle {
@Override
public void accelerate() {
System.out.println("Car is accelerating");
}
// No need to implement brake() as it has a default implementation
}
public class Main {
public static void main(String[] args) {
Vehicle car = new Car();
car.accelerate(); // Output: Car is accelerating
car.brake(); // Output: Vehicle is braking
// Calling static method from interface
Vehicle.info(); // Output: Vehicles are used for transportation
}
}
Java 9 introduced private methods in interfaces, both static and non-static. These help in better code organization and reuse within the interface itself.
public interface Logger {
default void logInfo(String message) {
log(message, "INFO");
}
default void logWarning(String message) {
log(message, "WARNING");
}
default void logError(String message) {
log(message, "ERROR");
}
// Private method for code reuse within the interface
private void log(String message, String level) {
System.out.println("[" + level + "] " + message);
}
// Private static method
private static String formatTime() {
return java.time.LocalTime.now().toString();
}
}
public class FileLogger implements Logger {
// No need to implement any method as all methods in the interface have implementations
}
public class Main {
public static void main(String[] args) {
Logger logger = new FileLogger();
logger.logInfo("Application started"); // Output: [INFO] Application started
logger.logWarning("Low memory"); // Output: [WARNING] Low memory
logger.logError("Connection failed"); // Output: [ERROR] Connection failed
}
}
The Runnable interface is one of the most commonly used functional interfaces in Java. It's primarily used for executing code in a separate thread.
// Example of Runnable interface usage
public class TaskRunner implements Runnable {
private String taskName;
public TaskRunner(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
System.out.println("Executing task: " + taskName);
try {
// Simulate work
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task completed: " + taskName);
}
}
public class Main {
public static void main(String[] args) {
// Create and start threads using Runnable
Thread thread1 = new Thread(new TaskRunner("Data processing"));
Thread thread2 = new Thread(new TaskRunner("File backup"));
thread1.start();
thread2.start();
// Using lambda expression with Runnable
Thread thread3 = new Thread(() -> {
System.out.println("Executing task: Email notification");
System.out.println("Task completed: Email notification");
});
thread3.start();
}
}
The output might look like:
Executing task: Data processing
Executing task: File backup
Executing task: Email notification
Task completed: Email notification
Task completed: Data processing
Task completed: File backup
Note that the exact order of output might vary due to thread scheduling.
Understanding when to use an interface versus an abstract class is crucial for good Java design. Here's a comparison of both:
Feature | Interface | Abstract Class |
Multiple Inheritance | A class can implement multiple interfaces | A class can extend only one abstract class |
State | Cannot have instance variables (except constants) | Can have instance variables to hold state |
Constructors | Cannot have constructors | Can have constructors |
Method Implementation | Prior to Java 8, could not have method implementations | Can have method implementations |
Access Modifiers | All methods are implicitly public | Can have methods with different access modifiers |
Fields | All fields are implicitly public, static, and final | Can have fields with different access modifiers |
Purpose | To define a contract of what a class can do | To provide a common base implementation for subclasses |
Use an abstract class when:
Use an interface when:
// Abstract class
public abstract class Animal {
// State
protected String name;
// Constructor
public Animal(String name) {
this.name = name;
}
// Concrete method
public void breathe() {
System.out.println(name + " is breathing");
}
// Abstract method
public abstract void makeSound();
}
// Interface
public interface Pet {
void play();
default void groom() {
System.out.println("Pet is being groomed");
}
}
// Class extending abstract class
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " barks");
}
}
// Class implementing interface
public class Cat implements Pet {
private String name;
public Cat(String name) {
this.name = name;
}
@Override
public void play() {
System.out.println(name + " is playing with a yarn ball");
}
}
// Class extending abstract class and implementing interface
public class Puppy extends Animal implements Pet {
public Puppy(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " whines");
}
@Override
public void play() {
System.out.println(name + " is playing fetch");
}
}
// Usage example
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Buddy");
dog.breathe(); // Output: Buddy is breathing
dog.makeSound(); // Output: Buddy barks
Cat cat = new Cat("Whiskers");
cat.play(); // Output: Whiskers is playing with a yarn ball
cat.groom(); // Output: Pet is being groomed
Puppy puppy = new Puppy("Max");
puppy.breathe(); // Output: Max is breathing
puppy.makeSound(); // Output: Max whines
puppy.play(); // Output: Max is playing fetch
puppy.groom(); // Output: Pet is being groomed
}
}
The java.util package contains many important interfaces. Here are some commonly used interfaces from this package:
Let's see an example using some of these interfaces:
import java.util.*;
public class JavaUtilInterfacesExample {
public static void main(String[] args) {
// List interface example
List<String> namesList = new ArrayList<>();
namesList.add("Alice");
namesList.add("Bob");
namesList.add("Charlie");
System.out.println("List elements: " + namesList);
// Set interface example
Set<Integer> numbersSet = new HashSet<>();
numbersSet.add(10);
numbersSet.add(20);
numbersSet.add(10); // Duplicate - will not be added
System.out.println("Set elements: " + numbersSet);
// Map interface example
Map<String, Integer> ageMap = new HashMap<>();
ageMap.put("Alice", 25);
ageMap.put("Bob", 30);
ageMap.put("Charlie", 35);
System.out.println("Map entries:");
for (Map.Entry<String, Integer> entry : ageMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// Comparator interface example
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 25));
people.add(new Person("Bob", 30));
people.add(new Person("Charlie", 20));
// Sort by age using Comparator
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}
});
System.out.println("\nPeople sorted by age:");
for (Person person : people) {
System.out.println(person.getName() + ": " + person.getAge());
}
// Same sort using lambda expression
Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));
System.out.println("\nPeople sorted by name:");
for (Person person : people) {
System.out.println(person.getName() + ": " + person.getAge());
}
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
Output:
List elements: [Alice, Bob, Charlie]
Set elements: [20, 10]
Map entries:
Bob: 30
Alice: 25
Charlie: 35
People sorted by age:
Charlie: 20
Alice: 25
Bob: 30
People sorted by name:
Alice: 25
Bob: 30
Charlie: 20
Interfaces in Java are vital for building flexible, modular, and maintainable applications. They enable abstraction, polymorphism, and a form of multiple inheritance, supporting better design practices. Java interfaces have evolved from basic abstract methods to advanced features like functional interfaces and default methods to meet modern development needs.
Mastering when to use interfaces over abstract classes promotes clean architecture and adherence to principles like Interface Segregation. More than just syntax, interfaces act as powerful contracts that guide system design and improve code scalability.
An interface in Java is a reference type that contains a collection of abstract methods and constants. It serves as a contract for classes that implement it. For example, a Printable interface might declare a print() method, and any class implementing this interface must provide an implementation for this method. This enables polymorphic behavior where different objects can respond to the same method call in different ways.
public interface Printable {
void print();
}
class Document implements Printable {
@Override
public void print() {
System.out.println("Printing document...");
}
}
A functional interface in Java is an interface that contains exactly one abstract method. Functional interfaces are used as the basis for lambda expressions in Java 8 and above. The @FunctionalInterface annotation is used to ensure that the interface has only one abstract method. Examples include Runnable, Callable, and Comparator. Functional interfaces can have any number of default, static, or private methods as long as there is only one abstract method.
A marker interface in Java is an interface that doesn't declare any methods or constants. It serves as a "marker" that tells the JVM that the implementing class possesses a certain capability. Examples include Serializable, Cloneable, and RandomAccess. The JVM provides special treatment to classes implementing marker interfaces. For instance, only classes implementing Serializable can be serialized to a byte stream.
The main differences between a class and interface in Java are:
Use an abstract class when:
Use an interface when:
The Runnable interface is a functional interface in Java used primarily for defining tasks that can be executed by a separate thread. It contains a single method, run(), which doesn't accept any parameters or return any value. The Runnable interface is commonly used with the Thread class to create and execute tasks concurrently.
public class MyTask implements Runnable {
@Override
public void run() {
System.out.println("Task is running in a thread");
}
}
// Usage
Thread thread = new Thread(new MyTask());
thread.start();
The Java.util package contains several interfaces including:
These interfaces form the foundation of the Java Collections Framework and provide standardized ways to manipulate groups of objects.
Yes, an interface can extend one or more other interfaces using the extends keyword. When an interface extends another interface, it inherits all the abstract methods, default methods, and static methods from the parent interface. A class implementing the child interface must implement all abstract methods from both the child and parent interfaces.
public interface Vehicle {
void move();
}
public interface FlyingVehicle extends Vehicle {
void fly();
}
public class Airplane implements FlyingVehicle {
@Override
public void move() {
System.out.println("Airplane is moving on the runway");
}
@Override
public void fly() {
System.out.println("Airplane is flying in the sky");
}
}
No, an interface cannot have a constructor. Constructors are used to initialize the state of an object, but interfaces don't have state (except constants). Since interfaces cannot be instantiated, there is no need for a constructor. All methods in interfaces are abstract, static, default, or private, and fields are constants.
Yes, since Java 9, interfaces can have private methods. These private methods can be either static or instance methods and are only accessible within the interface itself. They cannot be accessed by implementing classes. Private methods in interfaces are primarily used for code reuse within the interface, especially when default methods share common code.
public interface Logger {
default void logInfo(String message) {
log(message, "INFO");
}
default void logError(String message) {
log(message, "ERROR");
}
// Private method for code reuse
private void log(String message, String level) {
System.out.println("[" + level + "] " + message);
}
}
If a class implements two interfaces that contain default methods with the same signature, the Java compiler will report a conflict. To resolve this conflict, the implementing class must override the default method and provide its own implementation. The class can still access the default implementations from either interface using the InterfaceName.super.methodName() syntax.
public interface A {
default void display() {
System.out.println("Display from A");
}
}
public interface B {
default void display() {
System.out.println("Display from B");
}
}
public class C implements A, B {
// Must override to resolve conflict
@Override
public void display() {
// Can call either default implementation
A.super.display();
// or
B.super.display();
// or provide a completely new implementation
System.out.println("Display from C");
}
}
Take the Free Quiz on Java
Answer quick questions and assess your Java knowledge
Author
Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)
Indian Nationals
1800 210 2020
Foreign Nationals
+918068792934
1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.
2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.