Interface Basics in Java
When designing a large application, you often need to describe what a class should be able to do without deciding how that behavior should be implemented. For example, a payment system may support credit cards, UPI, and bank transfers. Every payment type should be payable, but the internal implementation can be completely different.
Java provides interfaces to model this kind of contract. An interface focuses primarily on what a class must provide, rather than forcing all implementing classes to share the same implementation.
An interface is a contract. It defines a set of capabilities that a class agrees to provide when it implements that interface.
Why Do We Need Interfaces?
Imagine an application that sends notifications. Email, SMS, and push notifications all perform the same high-level operation: they send a message. However, the actual communication mechanism is different.
interface Notification
{
void send();
}
The interface does not need to know how an email is sent or how an SMS is delivered. It simply establishes the capability that every notification implementation must provide.
class EmailNotification implements Notification
{
@Override
public void send()
{
System.out.println("Sending email");
}
}
class SMSNotification implements Notification
{
@Override
public void send()
{
System.out.println("Sending SMS");
}
}
This gives the application a common contract while allowing each implementation to remain independent.
Real-World Analogy
Think about a USB port on a computer. The computer does not need to know the internal design of every USB device. It simply follows the USB specification. A keyboard, mouse, storage device, and other compatible devices can work with the same port because they follow the agreed contract.
A Java interface works in a similar way. It defines a contract, and different classes can implement that contract in their own way.
Creating an Interface
An interface is declared using the interface keyword.
interface Vehicle
{
void start();
void stop();
}
Here, Vehicle defines two operations: start() and stop(). The interface establishes what implementing classes must provide.
Implementing an Interface
A class uses the implements keyword to implement an interface.
interface Vehicle
{
void start();
void stop();
}
class Car implements Vehicle
{
@Override
public void start()
{
System.out.println("Car started");
}
@Override
public void stop()
{
System.out.println("Car stopped");
}
}
The Car class agrees to follow the Vehicle contract, so it provides implementations for both methods.
Use implements when a class follows an interface. Use extends when a class inherits from another class.
Basic Interface Syntax
interface InterfaceName
{
// Interface members
}
A class can then implement it using:
class ClassName implements InterfaceName
{
// Implement required behavior
}
Interface Methods
In the traditional form of an interface, methods are implicitly public and abstract unless a different permitted method kind is explicitly used, such as default, static, or private methods.
interface Payment
{
void pay();
}
The method above is effectively treated as a public abstract method.
Therefore, an implementing class must provide a compatible public implementation.
class CreditCardPayment implements Payment
{
@Override
public void pay()
{
System.out.println("Paid using credit card");
}
}
When implementing a public interface method, do not reduce its visibility. The implementation must remain public.
Interface Variables
Variables declared directly inside an interface are implicitly public, static, and final.
interface Payment
{
double TAX_RATE = 0.18;
}
The variable behaves like a constant. It cannot be changed after initialization.
class Invoice implements Payment
{
void calculateTax(double amount)
{
double tax = amount * TAX_RATE;
System.out.println(tax);
}
}
It is generally clearer to access such constants through the interface name when the context calls for it.
System.out.println(Payment.TAX_RATE);
Can We Create an Object of an Interface?
No. An interface cannot be instantiated directly.
interface Vehicle
{
void start();
}
class Main
{
public static void main(String[] args)
{
Vehicle vehicle = new Vehicle(); // Compile-time error
}
}
However, an interface reference can refer to an object of a class that implements the interface.
interface Vehicle
{
void start();
}
class Car implements Vehicle
{
@Override
public void start()
{
System.out.println("Car started");
}
}
class Main
{
public static void main(String[] args)
{
Vehicle vehicle = new Car();
vehicle.start();
}
}
This is a very important pattern in Java. The code depends on the interface rather than the concrete implementation.
Interface Reference and Polymorphism
Interfaces work naturally with runtime polymorphism. Different classes can implement the same interface, and the same interface reference can point to different objects.
interface Payment
{
void pay();
}
class CreditCardPayment implements Payment
{
@Override
public void pay()
{
System.out.println("Credit card payment");
}
}
class UPIPayment implements Payment
{
@Override
public void pay()
{
System.out.println("UPI payment");
}
}
class Main
{
public static void main(String[] args)
{
Payment payment;
payment = new CreditCardPayment();
payment.pay();
payment = new UPIPayment();
payment.pay();
}
}
The variable type remains Payment, while the actual implementation changes at runtime. This allows code to remain flexible and loosely coupled.
Interfaces Represent Capabilities
One useful way to think about interfaces is that they often represent a capability rather than a physical or hierarchical identity.
For example, a printer and a document-management system might both support printing, even though they are unrelated classes. Instead of forcing them into one inheritance hierarchy, an interface can describe the capability.
interface Printable
{
void print();
}
class Invoice implements Printable
{
@Override
public void print()
{
System.out.println("Printing invoice");
}
}
class Report implements Printable
{
@Override
public void print()
{
System.out.println("Printing report");
}
}
The interface communicates a useful idea: anything that implements Printable promises to support the print() capability.
Interfaces Help Reduce Coupling
Suppose an order service directly creates a specific payment implementation.
class OrderService
{
void checkout()
{
CreditCardPayment payment = new CreditCardPayment();
payment.pay();
}
}
This code is tightly coupled to CreditCardPayment. If the application later needs UPI payment, the service itself must be changed.
A better design can depend on the interface.
interface Payment
{
void pay();
}
class OrderService
{
private Payment payment;
OrderService(Payment payment)
{
this.payment = payment;
}
void checkout()
{
payment.pay();
}
}
Now the service does not care whether the supplied payment implementation is a credit card, UPI, or another supported mechanism. This is a practical example of programming to an abstraction.
Interface with Multiple Implementations
A single interface can have many implementations. This is one of the reasons interfaces are valuable in enterprise applications.
interface Logger
{
void log(String message);
}
class ConsoleLogger implements Logger
{
@Override
public void log(String message)
{
System.out.println("Console: " + message);
}
}
class FileLogger implements Logger
{
@Override
public void log(String message)
{
System.out.println("Writing to file: " + message);
}
}
class DatabaseLogger implements Logger
{
@Override
public void log(String message)
{
System.out.println("Saving to database: " + message);
}
}
All three classes follow the same contract, but their implementations are independent. This makes it easier to replace one implementation with another.
Interface Inheritance
An interface can extend another interface using the extends keyword.
interface Animal
{
void eat();
}
interface Dog extends Animal
{
void bark();
}
A class implementing Dog must provide implementations for both eat() and bark().
class Labrador implements Dog
{
@Override
public void eat()
{
System.out.println("Labrador eats");
}
@Override
public void bark()
{
System.out.println("Labrador barks");
}
}
Interface vs Class Inheritance Syntax
The keywords can initially feel confusing, so remember the relationship rather than memorizing isolated rules.
| Relationship | Syntax | Meaning |
|---|---|---|
| Class extends class | extends | Inheritance between classes |
| Interface extends interface | extends | Interface inherits another interface contract |
| Class implements interface | implements | Class agrees to fulfill an interface contract |
Can an Interface Contain a Constructor?
No. An interface cannot have a constructor because an interface is not instantiated directly. Constructors initialize objects, while interfaces define contracts and capabilities.
interface Vehicle
{
Vehicle()
{
// Invalid
}
}
Can an Interface Contain Fields?
Yes. Interface fields are constants by default.
interface Configuration
{
int MAX_CONNECTIONS = 100;
}
You cannot assign a new value to that field.
Configuration.MAX_CONNECTIONS = 200; // Compile-time error
Modern Interfaces Can Have Implemented Methods
A common beginner explanation says that interfaces contain only abstract methods. That was approximately true in early Java, but it is not correct for modern Java.
Java interfaces can contain default methods, static methods, and, since Java 9, private methods. These features allow interfaces to provide reusable behavior while preserving their role as contracts.
interface Vehicle
{
void start();
default void displayType()
{
System.out.println("This is a vehicle");
}
}
The details of default, static, and private interface methods will be covered separately because each has its own rules and use cases.
Interface Naming Convention
Java interface names normally follow the same PascalCase naming convention used for classes.
interface PaymentService
{
}
interface Printable
{
}
interface DataRepository
{
}
Good names should describe the contract or capability represented by the interface. Names such as PaymentService, Runnable, and Comparable communicate meaningful responsibilities.
Common Beginner Mistakes
- Trying to create an object directly from an interface.
- Using extends when a class should implement an interface.
- Implementing an interface method with weaker access than public.
- Assuming modern interfaces can contain only abstract methods.
- Trying to change an interface constant after initialization.
- Adding unrelated responsibilities to one large interface.
- Depending directly on concrete implementations when an interface can provide a cleaner abstraction.
Best Practices
- Design interfaces around clear responsibilities or capabilities.
- Keep interfaces small and focused when possible.
- Program against interfaces when you need interchangeable implementations.
- Use meaningful names that describe the contract rather than implementation details.
- Use @Override when implementing interface methods.
- Avoid placing implementation-specific details into a general-purpose interface.
Interview Insights
Question: What is an interface in Java?
Answer: An interface is a reference type that defines a contract or set of capabilities that implementing classes agree to provide.
Question: Can we create an object of an interface?
Answer: No. An interface cannot be instantiated directly, but an interface reference can point to an object of a class that implements it.
Question: Which keyword is used when a class uses an interface?
Answer: The implements keyword is used.
Question: Can an interface have variables?
Answer: Yes. Fields declared directly in an interface are implicitly public, static, and final, so they behave as constants.
Question: Can an interface extend another interface?
Answer: Yes. An interface can extend another interface using the extends keyword.
Quick Revision
| Concept | Key Point |
|---|---|
| Interface | Defines a contract or capability that implementing classes agree to provide. |
| implements | Used by a class to implement an interface. |
| extends | Used when an interface inherits another interface. |
| Interface method | Traditional interface methods are implicitly public and abstract; modern interfaces can also define default, static, and private methods. |
| Interface field | Implicitly public, static, and final. |
| Constructor | Interfaces cannot have constructors. |
| Object creation | An interface cannot be instantiated directly. |
| Polymorphism | An interface reference can refer to an object of any compatible implementing class. |
Final Takeaway
An interface provides a clean way to define a contract without tying the consumer of that contract to a particular implementation. Classes can implement the same interface in completely different ways, while the rest of the application can work with the common interface type. This makes interfaces a fundamental tool for abstraction, polymorphism, loose coupling, testability, and flexible application architecture.
