Adapter Class in Java: Practical Guide with Examples
Updated on Dec 17, 2024 | 16 min read | 22.3k views
Share:
For working professionals
For fresh graduates
More
Updated on Dec 17, 2024 | 16 min read | 22.3k views
Share:
Table of Contents
Have you ever needed to charge your phone while you’re traveling in a car? What do you do? You use a car charger adapter that converts the 12V cigarette lighter socket into a USB port, allowing you to charge your phone effortlessly.
In Java, an adapter class works the same way—it bridges the gap between two incompatible systems, allowing them to work together seamlessly. Whether you’re dealing with legacy systems or integrating third-party libraries, the adapter ensures everything functions as intended, just like your car charger adapter!
Understanding this concept of bridging incompatible systems will definitely make you a standout in the tech world. It will open doors to high-demand roles in cybersecurity, data science, and software development.
Ready to level up your programming career? Dive into this practical guide and start augmenting your knowledge and skills.
An adapter class in Java is a design pattern used to allow two incompatible interfaces to work together. It acts as a middleman that converts the interface of a class into another interface that the client expects. Instead of rewriting code or forcing classes to match, the adapter class simplifies integration and makes systems more flexible.
Adapter classes are often used in situations where you're dealing with abstract classes or interfaces that have multiple methods. By creating an adapter, you don't need to implement every method in the interface. Instead, you can extend an existing class and override only the methods you need. This makes the code cleaner and more efficient.
Here are a few key features of adapter class:
Also Read: Abstract Class vs Interface: The Differences and the Similarities | upGrad blog
When working with interfaces that contain multiple methods, you often end up implementing methods that aren't relevant to your task. An adapter class offers a cleaner solution by allowing you to implement only the methods you need, simplifying your code.
Common challenges with interfaces containing multiple methods:
How adapter classes simplify your code:
Real-world scenarios where adapter classes are helpful:
Adapter classes aren't just a convenience—they’re a powerful tool that helps you streamline development and work more efficiently.
Also Read: Java Tutorial: Learn Java Programming From Scratch For Beginners
Now that you know what is adapter class is, let's dive into some common types of adapter classes.
An adapter class in Java is used in various libraries to simplify event handling. These classes act as intermediaries between events and listeners, making it easier to implement only the methods you need.
Let’s explore some common types of adapter classes.
In Java’s AWT (Abstract Window Toolkit), adapter classes help manage common events like mouse clicks, key presses, and window actions. These classes implement the corresponding listener interfaces and offer default empty implementations, so you only need to override the methods you need.
Examples:
Now, let's see the table for these adapter classes and their associated listener interfaces:
Adapter Class |
Listener Interface |
MouseAdapter | MouseListener |
KeyAdapter | KeyListener |
WindowAdapter | WindowListener |
ComponentAdapter | ComponentListener |
Explanation: These adapter classes make it easier to handle events by providing default methods for each listener interface. You only need to override the specific methods that your program requires, which reduces code clutter and complexity.
Drag-and-drop events are managed by the java.awt.dnd package. The adapter classes here simplify the handling of these events, letting you focus on the relevant actions like dragging and dropping items.
Examples:
Here’s a table showing these adapter classes and their corresponding listener interfaces:
Adapter Class |
Listener Interface |
DragSourceAdapter | DragSourceListener |
DropTargetAdapter | DropTargetListener |
Explanation: These adapter classes are specifically designed to handle drag-and-drop events. They provide default implementations of the DragSourceListener and DropTargetListener interfaces, so you only need to focus on the methods that are necessary for your application.
For Swing-based applications, adapter classes help manage events in GUI components. These classes make it easier to work with user interface events without dealing with every single method in the listener interfaces.
Examples:
Let’s take a closer look at how these adapter classes are mapped to their listener interfaces:
Adapter Class |
Listener Interface |
MouseAdapter | MouseListener |
WindowAdapter | WindowListener |
KeyAdapter | KeyListener |
These adapter classes are key in reducing complexity, ensuring that you only implement the necessary event methods while maintaining a clean, readable codebase.
Also Read: Java Swing Project: Properties, Advantages & Frameworks | upGrad blog
Now that you know what is adapter class and its different types, let's go through the process step by step.
Creating your own adapter class in Java is a straightforward process. It allows you to bridge the gap between incompatible interfaces by overriding only the methods you need. Let’s walk through how to write a custom adapter class.
Here’s a step-by-step guide:
Example: Creating a Custom Adapter Class
Let’s say you have a custom interface called ShapeListener that defines methods for handling shape events like onDraw and onResize.
// Step 1: Define the Interface
interface ShapeListener {
void onDraw();
void onResize();
}
// Step 2: Create the Adapter Class
class ShapeAdapter implements ShapeListener {
@Override
public void onDraw() {
// Default empty implementation
}
@Override
public void onResize() {
// Default empty implementation
}
}
// Step 3: Use the Adapter Class
public class MyApp {
public static void main(String[] args) {
ShapeListener listener = new ShapeAdapter() {
@Override
public void onDraw() {
System.out.println("Drawing a shape!");
}
};
listener.onDraw(); // Output: Drawing a shape!
}
}
Explanation: In this example, ShapeAdapter implements the ShapeListener interface. Instead of implementing both methods, it provides default (empty) implementations for onDraw and onResize. In the MyApp class, you create an anonymous subclass of ShapeAdapter to override only the method you need—in this case, onDraw. This keeps the code clean and avoids unnecessary method implementations.
Also Read: 22 Best Java Project Ideas & Topics For Beginners With Source Code 2024 [Latest]
Adapter classes are particularly useful when you want to handle specific events without dealing with unnecessary methods. Let’s look at some examples to understand how these adapter classes simplify event handling.
To see how adapter classes work in action, let's explore a few practical examples. Each of these will demonstrate how adapter classes help simplify event handling in Java.
Overview of the Class: The WindowAdapter class provides default implementations for all the methods in WindowListener. This allows you to focus on the specific event you want to handle, such as window closing.
Example Code:
import java.awt.event.*;
public class WindowExample {
public static void main(String[] args) {
Frame frame = new Frame("Window Example");
// Using windowadapter to handle only windowClosing event
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("Window is closing...");
System.exit(0);
}
});
frame.setSize(300, 200);
frame.setVisible(true);
}
}
Explanation: In this example, the WindowAdapter class is used to handle the windowClosing event. Instead of implementing all the methods in WindowListener, you override just the method you need. This makes the code simpler and cleaner.
The KeyAdapter class simplifies handling keyboard events. It implements the KeyListener interface and provides default empty implementations for all the methods, allowing you to focus only on the key events you care about.
Overview of the class: KeyAdapter provides default implementations for keyPressed(), keyReleased(), and keyTyped(). You can override just the ones that are necessary for your application.
Example Code:
import java.awt.event.*;
public class KeyEventExample {
public static void main(String[] args) {
Frame frame = new Frame("Key Event Example");
// Using keyadapter to handle keyPressed event
frame.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
System.out.println("Key pressed: " + e.getKeyChar());
}
});
frame.setSize(300, 200);
frame.setVisible(true);
}
}
Explanation: Here, the KeyAdapter class is used to listen for key presses. By overriding just keyPressed(), you avoid the need to implement unnecessary methods, keeping the code focused and efficient.
The MouseMotionAdapter class is used to handle mouse movement events, such as when the mouse is moved or dragged across the screen. Like the other adapter classes, it provides default implementations for the MouseMotionListener interface.
Overview of the class: MouseMotionAdapter simplifies the handling of mouse movement events by providing empty implementations of methods like mouseMoved() and mouseDragged(). You only need to override the methods that are relevant.
Example Code:
import java.awt.event.*;
public class MouseMotionExample {
public static void main(String[] args) {
Frame frame = new Frame("Mouse Motion Example");// Using mousemotionadapter to handle mouseMoved event
frame.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
System.out.println("Mouse moved to: (" + e.getX() + ", " + e.getY() + ")");
}
});
frame.setSize(300, 200);
frame.setVisible(true);
}
}
Explanation: In this example, you use MouseMotionAdapter to track mouse movements. By overriding just the mouseMoved() method, you keep the code concise and relevant, without implementing the entire MouseMotionListener interface.
These examples highlight how adapter classes help reduce boilerplate code, making event handling in Java easier and more manageable.
Also Read: Top 8 Reasons Why Java Is So Popular and Widely Used in 2025
Adapter classes and object adapters both serve to bridge incompatible interfaces, but they do so in different ways. Let’s dive into the key differences.
Both the adapter class and object adapter are design patterns used to make incompatible interfaces work together. However, they have key differences in how they function.
Here’s a table differentiating the two:
Aspect |
Adapter Class |
Object Adapter |
Definition | Uses inheritance to adapt an interface. It extends the class and overrides the necessary methods. | Uses composition to adapt an interface by including an instance of another class. |
How it works | The adapter class extends the class to implement the required methods. | The adapter class holds a reference to the target class and delegates method calls. |
Key Feature | Inherits behavior from a class and implements the target interface. | Composes behavior by holding an object and delegating method calls. |
Advantages | Simple when adapting interfaces of a single class. | More flexible as it allows adapting multiple classes and avoiding inheritance issues. |
Disadvantages | Tied to the class it extends, limiting flexibility. | Can be slightly more complex due to composition and delegation. |
Example Code: Using Adapter Class in Java
In this example, we’ll use an adapter class to implement a Shape interface that has multiple methods. We’ll create an adapter class for Rectangle that only overrides the methods you need.
Step 1: Define the Shape interface
interface Shape {
void draw(); // method to draw the shape
void resize(); // method to resize the shape
void color(); // method to color the shape
}
Step 2: Create an adapter class that implements Shape
// Adapter class that implements Shape but provides default behavior for unused methods
class ShapeAdapter implements Shape {
@Override
public void draw() {
System.out.println("Drawing a rectangle.");
}
@Override
public void resize() {
// Default implementation can be left empty
}
@Override
public void color() {
// Default implementation can be left empty
}
}
Step 3: Use the adapter class in your program
public class AdapterExample {
public static void main(String[] args) {
Shape rectangle = new ShapeAdapter();
rectangle.draw(); // Output: Drawing a rectangle.
}
}
Explanation:
This is a basic demonstration of how an adapter class simplifies interface implementation by overriding only the methods that are needed, making your code cleaner and more focused.
Example Code: Using Object Adapter in Java
Let’s assume you need to adapt a MediaPlayer interface to work with an existing AudioPlayer class that has its own method for playing audio.
Step 1: Define the MediaPlayer interface
interface MediaPlayer {
void play();
}
Step 2: Define the AudioPlayer class with its own method
class AudioPlayer {
public void playAudio() {
System.out.println("Playing audio...");
}
}
Step 3: Create the Object Adapter that adapts the AudioPlayer class to the MediaPlayer interface
// Object Adapter
class MediaAdapter implements MediaPlayer {
private AudioPlayer audioPlayer;
public MediaAdapter(AudioPlayer audioPlayer) {
this.audioPlayer = audioPlayer;
}
@Override
public void play() {
audioPlayer.playAudio(); // Adapting the playAudio method to play method
}
}
Step 4: Use the adapter class in your program
public class AdapterExample {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
MediaPlayer mediaPlayer = new MediaAdapter(audioPlayer); // Pass the AudioPlayer to the adapter
mediaPlayer.play(); // Output: Playing audio...
}
}
Explanation:
This approach gives you more flexibility, as the adapter can delegate calls to different classes based on the context.
Both the adapter class and object adapter patterns serve to bridge incompatible interfaces, but they do so in different ways. While class adapters use inheritance to extend a class, object adapters rely on composition, making them more flexible and reusable across different scenarios.
Also Read: Design Patterns: Singleton in Java
Understanding these distinctions is crucial for choosing between an adapter class and a listener interface, depending on your use case complexity and control needs.
upGrad’s Exclusive Software and Tech Webinar for you –
SAAS Business – What is So Different?
Both the adapter class and listener interface are used to handle events in Java, but they differ in their purpose, complexity, and how they are implemented. Understanding the key differences can help you choose the right approach for your specific needs.
Here’s a table differentiating the approaches:
Factors |
Adapter Class |
Listener Interface |
Purpose | Simplifies event handling by providing default method implementations, allowing you to override only the ones you need. | Defines the contract for handling events; all methods must be implemented. |
Ease of Implementation | Easier to implement when you only need to handle some methods, as it provides default implementations. | Requires you to implement every method in the interface, even if some aren't needed. |
Code Complexity | Less complex, as you only override the necessary methods. | More complex, as you must implement all methods, even if they aren't used. |
Use Case | Ideal when you need to handle specific events in a large interface without cluttering your code. | Suitable for cases where you need full control over all events in an interface. |
Inheritance | Involves inheritance, as the adapter class typically extends an existing class. | Does not involve inheritance; it relies on implementing the interface. |
Extensibility | Less flexible since the adapter class is constrained by its inheritance. | More flexible, allowing you to implement the interface in various ways. |
Availability | Available in Java AWT and Swing libraries as predefined adapter classes. | Must be created and implemented manually for custom event handling. |
Example (Brief) | MouseAdapter extends MouseListener, overriding only the methods needed. | MouseListener interface requires the implementation of methods like mousePressed, mouseReleased, etc. |
Explanation: An adapter class is perfect when you want to handle only a few methods of a larger interface without having to implement the entire interface. It reduces code complexity and makes event handling easier.
On the other hand, a listener interface gives you full control over all methods but requires more effort and leads to more code. Both approaches have their uses, depending on whether you need simplicity or full customization.
Also Read: Ultimate Guide to Synchronization in Java
However, to understand when and why to use an adapter class, it's important to weigh its advantages and limitations.
The adapter class pattern simplifies event handling by providing default method implementations, allowing you to override only the ones you need. However, like any design pattern, it comes with both benefits and limitations.
Here is a list of pros:
Here is a list of cons:
The adapter class is useful when you want to streamline event handling or interface integration, but it may not be the best option in situations requiring flexibility across multiple interfaces.
As you explore the power of adapter classes and dive deeper into Java programming, the next step is to ensure you're equipped with the right skills to thrive in the industry.
To succeed in the tech world, continuous learning is key. With upGrad, you gain access to one of the leading online learning platforms, trusted by over 10 million learners globally. Choose from 200+ industry-relevant courses and connect with over 1,400 hiring partners to help you land your ideal job.
Whether you're looking to sharpen your coding skills or dive deeper into specialized fields, upGrad offers the right programming courses to help you achieve your career goals. If you're an aspiring tech professional in India, these courses will set you on the path to success.
Here’s a quick look at some of the relevant programming courses offered by upGrad:
Course Title |
Description |
Java Object-oriented Programming | Master the fundamentals of Object-Oriented Programming (OOP) in Java with this free course, and learn key concepts like classes, inheritance, and polymorphism. |
JavaScript Basics from Scratch | This free course offers a comprehensive introduction to fundamental programming concepts and web development skills using JavaScript. |
Master of Design in User Experience | Earn a Master’s in User Experience Design from Jindal School of Art and Architecture, and gain expertise in creating intuitive, user-centered designs for digital products. |
Best Full Stack Developer Bootcamp 2024 | A program designed to equip learners with essential skills in both front-end and back-end development, preparing them for successful careers in software engineering. |
Python Programming Free courses | Basic Python Free Course | This free course offers 12 hours of learning to develop problem-solving skills through coding exercises on lists, strings, and data structures like tuples, sets, and dictionaries. |
Need help choosing what’s right for your career goals? upGrad offers free one-on-one expert career counseling sessions to help you define your goals, match your skills with the right opportunities, and create a roadmap for long-term success.
Boost your career with our popular Software Engineering courses, offering hands-on training and expert guidance to turn you into a skilled software developer.
Master in-demand Software Development skills like coding, system design, DevOps, and agile methodologies to excel in today’s competitive tech industry.
Stay informed with our widely-read Software Development articles, covering everything from coding techniques to the latest advancements in software engineering.
Build your foundation in software development with our Free Courses – practical, beginner-friendly, and 100% free!
Get Free Consultation
By submitting, I accept the T&C and
Privacy Policy
India’s #1 Tech University
Executive PG Certification in AI-Powered Full Stack Development
77%
seats filled
Top Resources