Reading Time: 5 min read
Published: 30 Jan 2025
Abstraction in Java is a basic concept in object-oriented programming (OOP) that focuses on presenting only the essential details of an object or system while hiding the underlying implementation details and complexities. It allows developers to work with simplified representations of objects, which makes it easier to design robust, maintainable, and reusable code without being bogged down by implementation specifics.
Abstraction in Java allows you to design systems that highlight what an object does rather than how it does it. This feature improves the usability and clarity of the code. For example, when you use a smartphone, you interact with its touch screen and buttons without needing to understand the circuitry or software operating it.
Similarly, abstraction in Java helps you interact with classes and methods without dealing with their internal implementation details. Developers achieve data abstraction in Java through abstract classes and interfaces. These tools allow you to define behaviors that classes must implement.
In simple terms, abstract in Java means hiding complexity and uncovering only the essential parts of an object or system. It provides a way to design programs that separate the high-level functionality from intricate implementation details. This design approach makes your programs easier to understand and maintain.
Example: You are using a car. You only need to know how to use the steering wheel, pedals, and gear lever to drive it. You don't need to worry about how the engine or braking system works. Java's abstraction works in the same way: it provides a clear interface or outline to interact with objects without revealing the internal processes.
There are two ways provided by Java programming language for data abstraction:
An abstract class is a class that acts as a blueprint for other classes. You cannot create objects directly from an abstract class, but you can use it to provide shared functionality and implement certain behaviours for its subclasses. Abstract classes are declared using the abstract keyword.
In Java, an abstract class Transportation can represent common vehicle behaviors with abstract methods like move() and fuelEfficiency(). Subclasses such as Car, Bike, and Bus extend this class, each implementing these methods differently while hiding implementation details and maintaining a suitable interface.
// Abstract class
abstract class Vehicle {
abstract void start(); // Abstract method (no body)
void fuel() { // Non-abstract method (has body)
System.out.println("Filling fuel.");
}
}
// Subclass
class Car extends Vehicle {
void start() { // Implementing abstract method
System.out.println("Car is starting.");
}
}
// Main class
public class Main {
public static void main(String[] args) {
Car myCar = new Car();
myCar.start();
myCar.fuel();
}
}
Can Contain Abstract and Concrete Methods: Abstract classes can define methods with or without an implementation.
Supports Constructors: Unlike interfaces, abstract classes can have constructors, which are used during the creation of subclass instances.
Code Example:
abstract class Animal {
String name;
Animal(String name) { // Constructor
this.name = name;
}
abstract void sound(); // Abstract method
void display() { // Non-abstract method
System.out.println("Name: " + name);
}
}
class Dog extends Animal {
Dog(String name) { super(name); }
void sound() { System.out.println("Barks"); }
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Buddy");
dog.display();
dog.sound();
}
}
Output:
Name: Buddy
Barks
Complexity:
Facilitates Inheritance: Abstract classes serve as a base for other classes, and their abstract methods must be executed by subclasses.
abstract class Animal {
// Abstract method (no implementation)
public abstract void makeSound();
// Concrete method (has implementation)
public void sleep() {
System.out.println("The animal is sleeping.");
}
}
Output:
spoj: The program compiled successfully, but main class was not found.
Main class should contain method: public static void main (String[] args).
To access the abstract class, it must be inherited from another class. Let's convert the Animal class to an abstract class and inherit from it using Dog class:
abstract class Animal {
// Abstract method (no implementation)
public abstract void makeSound();
// Concrete method (has implementation)
public void sleep() {
System.out.println("The animal is sleeping.");
}
}
class Dog extends Animal {
@override
public void makeSound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
myDog.makeSound(); // Output: Bark
myDog.sleep(); // Output: The animal is sleeping.
}
}
The Animal abstract class acts as a blueprint with two methods. It has an abstract method makeSound, which has no implementation and must be defined by subclasses, and a Definite method sleep, which prints "The animal is sleeping.". Since Animal is abstract, you cannot create objects directly from it.
The Dog class extends Animal, inheriting its behavior while providing a detailed implementation for makeSound. The makeSound method in Dog prints "Bark", while the sleep method remains the same as in the Animal class.
In the Main class, an object of Dog is created and referenced by the Animal type. When makeSound is called on this object, it executes the overridden version in Dog, printing "Bark." Calling sleep invokes the inherited implementation from the Animal class, printing "The animal is sleeping."
Output:
Bark
The animal is sleeping.
An abstract method is a method declared in an abstract class without providing its implementation. Subclasses must override abstract methods to provide specific functionality.
// Abstract class with an abstract method
abstract class Example {
abstract void display(); // Method without a body
}
// Subclass providing the method's body
class Demo extends Example {
void display() {
System.out.println("Abstract method is now implemented.");
}
}
abstract class Shape {
// Abstract method
public abstract double calculateArea();
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
public class Main {
public static void main(String[] args) {
Shape myCircle = new Circle(5);
System.out.println("Area: " + myCircle.calculateArea()); // Output: Area: 78.53981633974483
}
}
The Shape class is an abstract class that represents the structure for its subclasses by including an abstract method calculateArea. This method has no implementation and must be overridden by any class that expands shape.
The Circle class extends Shape and provides a definite implementation for the calculateArea method. It has a private field radius to store the radius of the circle. The constructor of Circle initializes the radius, and the calculateArea method calculates the area of the circle using the formula π×radius(radius) returning the result.
In the Main class, a Circle object is made with a radius of 5, and it is assigned to a variable of type Shape. When the calculateArea method is called on the myCircle object, the overridden method in the Circle class executes which calculates and returns the area of the circle.
Output:
Area: 78.53981633974483
Abstract classes and methods are essential concepts in object-oriented programming that improve code organization and design. An abstract class acts as a blueprint that allows shared attributes and methods while defining abstract methods for subclasses to implement.
Consider a classic "vehicle" example, perhaps used in a transportation management system or simulation game. The base type is "vehicle," and each vehicle has a type, purpose, and so on. From this, specific types of vehicles are derived (inherited) — car, bicycle, truck, and so on — each of which has additional characteristics and behaviors.
For example, some vehicles may have different fuel efficiencies, and some have unique features such as the number of doors or gears. Certain behaviors, like how the vehicle moves or operates, may differ as well. The type hierarchy explains both the similarities and differences between the vehicles.
// Abstract class Vehicle
abstract class Vehicle {
protected String type;
// Constructor to initialize type
public Vehicle(String type) {
this.type = type;
}
// Abstract methods
public abstract String move();
public abstract double fuelEfficiency();
// Concrete method
public String getType() {
return type;
}
}
// Concrete class Car
class Car extends Vehicle {
private int numDoors;
// Constructor to initialize type and number of doors
public Car(String type, int numDoors) {
super(type);
this.numDoors = numDoors;
}
// Implement abstract methods
@Override
public String move() {
return "The car drives on roads.";
}
@Override
public double fuelEfficiency() {
return 15.5; // Example value (miles per gallon or km/l)
}
// Additional method for Car
public int getNumDoors() {
return numDoors;
}
}
// Concrete class Bicycle
class Bicycle extends Vehicle {
private int gearCount;
// Constructor to initialize type and gear count
public Bicycle(String type, int gearCount) {
super(type);
this.gearCount = gearCount;
}
// Implement abstract methods
@Override
public String move() {
return "The bicycle is pedaled manually.";
}
@Override
public double fuelEfficiency() {
return Double.POSITIVE_INFINITY; // No fuel needed for bicycles
}
// Additional method for Bicycle
public int getGearCount() {
return gearCount;
}
}
// Main class to test abstraction
public class Main {
public static void main(String[] args) {
// Create a Car object
Vehicle car = new Car("Car", 4);
System.out.println("Type: " + car.getType());
System.out.println("Movement: " + car.move());
System.out.println("Fuel Efficiency: " + car.fuelEfficiency() + " km/l");
// Create a Bicycle object
Vehicle bicycle = new Bicycle("Bicycle", 21);
System.out.println("\nType: " + bicycle.getType());
System.out.println("Movement: " + bicycle.move());
System.out.println("Fuel Efficiency: " + bicycle.fuelEfficiency());
}
}
Output:
Type: Car
Movement: The car drives on roads.
Fuel Efficiency: 15.5 km/l
Type: Bicycle
Movement: The bicycle is pedaled manually.
Fuel Efficiency: Infinity
This program explains abstraction in Java using the "Vehicle" hierarchy. The abstract class Vehicle defines shared properties and behaviors for all vehicles, such as the type and the abstract methods move() and fuelEfficiency(). The concrete subclasses, Car and Bicycle, inherit from Vehicle and implement the abstract methods according to their specific behaviors.
For example, a Car moves on roads and has a fuel efficiency of 15.5 km/l, while a Bicycle is manually pedaled and doesn't consume fuel. The main method shows polymorphism by using the Vehicle reference to call methods for both Car and Bicycle objects.
The design effectively separates shared attributes (e.g., type) and unique characteristics (e.g., numDoors for cars and gearCount for bicycles), showing the benefits of abstraction. The move() and fuelEfficiency() methods are implemented differently for each subclass to represent their unique behaviors, encapsulating the idea of real-world objects in a programming context.
An interface in Java is probably the most powerful tool for achieving abstraction. It acts like a contract that defines a set of methods a class must implement. Unlike abstract classes, the key difference is that, by using interfaces, we can achieve 100% abstraction in Java classes. Interfaces allow multiple inheritances, which means a class can implement several interfaces.
// Declaring an interface
interface Shape {
void draw(); // Automatically public and abstract
}
// Class implementing the interface
class Circle implements Shape {
public void draw() { // Implementation of the interface method
System.out.println("Drawing a circle.");
}
}
// Testing the implementation
public class Main {
public static void main(String[] args) {
Shape shape = new Circle(); // Polymorphic reference
shape.draw();
}
}
interface Vehicle {
void start(); // Abstract method
void stop(); // Abstract method
}
class Car implements Vehicle {
@Override
public void start() {
System.out.println("Car is starting...");
}
@Override
public void stop() {
System.out.println("Car is stopping...");
}
}
public class Main {
public static void main(String[] args) {
Vehicle myCar = new Car();
myCar.start(); // Output: Car is starting...
myCar.stop(); // Output: Car is stopping...
}
}
An interface in Java is like a contract. It says, "If you want to create a class that follows this contract, you must have these methods." The Vehicle interface has two methods which are start() and stop() but it doesn't say how they work.
The Car class follows the contract of the Vehicle interface. It tells us, "When I start, I will print 'Car is starting...' and when I stop, I will print 'Car is stopping...'".
In the Main class, we create a Car object, but we treat it like a Vehicle. When we call start() or stop(), the Car version of those methods runs.
Output:
Car is starting...
Car is stopping...
Abstraction in Java is an important concept in object-oriented programming that hides the complex details of how something works, this shows only the essential features to the user.
Here are some properties of abstraction in Java that you should know:
Encapsulation combines data and methods in a single unit (class). It contains external access to certain details, which protects the data from accidental changes. Developers can modify the internal workings of a class without affecting the code that uses it, improving security and making the system easier to maintain.
Abstraction breaks a system into smaller, separate parts, which makes it easier to develop, test, and fix code. It also allows teams to work on different parts at the same time without causing conflicts.
Polymorphism allows objects to be treated as their parent class and enables the same method to behave differently based on the object calling it.
Abstraction allows adding new functionality without altering the system's core structure. Developers can create base classes or interfaces as a foundation for future extensions.
This principle hides extreme details of an object which exposes only the essential parts. This improves security and reduces complexity making the system easier for users and developers to handle.
Abstraction supports creating generalized solutions that can be reused in multiple parts of a program or different projects. Abstract classes and interfaces define shared behaviors which reduces duplication and saves development time.
Here are the types of abstraction in Java that are important to understand. They help simplify complex systems by focusing on essential details.
Focuses on hiding the internal details of how data is stored or represented. Developers interact with data through interfaces or abstract methods, without needing to know the details of its implementation.
It hides the details of how operations are performed. It provides simplified interfaces for complex processes, so developers and users don't need to understand the full workings of those operations.
Although abstraction and encapsulation are related concepts in OOP, they differ significantly:
| Feature | Abstraction | Encapsulation |
|---|---|---|
| Usage | Usage Abstraction is the outer layout that is used in terms of design. | Encapsulation is the inner layout used in terms of implementation. |
| Focus or Purpose | It hides implementation details while showing functionality. | It hides data, code and controls access. |
| Achieved By | This can abstract classes and interfaces. | This can access modifiers (private, protected, public) |
| Purpose | It simplifies usage and improves readability. | It protects data and maintains integrity. |
| Example | Using abstract methods for behaviors. | Using getters and setters to control access. |
Let's consider the example of an ATM machine. Users interact with an ATM by pressing buttons to withdraw cash, check balances, or transfer money. The complex operations behind these actions (e.g., account verification, and database transactions) remain hidden. In Java, abstraction works similarly to provide a clear interface for users while concealing the intricate backend details.
abstract class ATM {
public abstract void withdraw(int amount);
public void showMessage() {
System.out.println("Please follow the instructions on the screen.");
}
}
class BankATM extends ATM {
@Override
public void withdraw(int amount) {
System.out.println("Dispensing " + amount + " dollars.");
}
}
public class Main {
public static void main(String[] args) {
ATM myATM = new BankATM();
myATM.showMessage(); // Output: Please follow the instructions on the screen.
myATM.withdraw(100); // Output: Dispensing 100 dollars.
}
}
The ATM abstract class sets up a basic structure for ATM functionality. It has one method, withdraw(), that subclasses must define, and another, showMessage(), which provides a standard message: "Please follow the instructions on the screen."
The BankATM class extends ATM and defines the withdraw() method. It prints a message like "Dispensing [amount] dollars," while the showMessage() method is inherited from the ATM class without changes.
Output:
Please follow the instructions on the screen.
Dispensing 100 dollars.
Abstraction facilitates complex systems by splitting them into smaller, manageable parts. This makes it easier to work on individual pieces and ensures the entire system is easier to understand, maintain, and scale as needed.
One major advantage is easier maintenance. Since abstraction separates what a system does from how it works, developers can make changes to specific parts without affecting the rest of the system.
Adding new features is also straightforward with abstraction. You can introduce new functionality without changing the existing code which follows the principle of extending systems without modifying their core parts. This keeps the system stable and reduces the risk of errors.
Abstraction also supports teamwork. Different teams can work on separate parts of the system at the same time, as long as they follow shared rules or interfaces. This speeds up development and prevents conflicts during integration.
By reducing the connections between components, abstraction assures that changes in one part don't disrupt others. It also allows developers to optimize specific parts for better performance without needing to modify the whole system.
Here are some advantages of Abstraction in Java that you should know:
Abstraction is an essential concept in Java and object-oriented programming. It simplifies development by focusing on essential features while hiding complex details. Using abstract classes and interfaces, Java allows developers to create flexible, maintainable, and scalable applications.
By applying abstraction, programmers can design modular code that's easy to extend, debug, and reuse which results in efficient and user-friendly systems.
Java abstraction streamlines programming by concentrating only on the important details of an object while hiding the complex implementation. It is achieved using abstract classes and interfaces.
An abstract class is a type of class that cannot be directly used to create objects. It can include abstract methods and regular methods. Subclasses use it as a foundation to build on.
An abstract method is defined without a body which means it has no code. This method must be implemented in any class that extends the abstract class or implements the interface containing it.
Java supports abstraction through abstract classes and interfaces. Abstract classes have a partial implementation, while interfaces define the behavior that classes must follow without implementation.
Abstract classes can include abstract and non-abstract methods, and have constructors. Interfaces, however, especially define abstract methods. Since Java 8, interfaces can also have default and static methods, but they cannot store state.
Abstraction makes code simpler by reducing complexity and helps in building reusable, modular, and secure applications. It also protects sensitive details by exposing only what is necessary to the user.
Yes, abstract classes can have constructors. These constructors are called during the creation of objects of subclasses, even though the abstract class itself cannot be instantiated.
No, you cannot directly create objects of an abstract class. Yet, you can create objects of subclasses that implement the abstract methods which allows them to fully utilize the abstract class's functionality.
Prime Number Program in Java: Explained with Examples - Learn how to write a prime number program in Java with clear logic, optimized algorithms, examples, and interview-ready explanations. (8 min read, 04 Jan 2026)
Why Encapsulation in Java Matters: Learn with Code Snippets - Understand encapsulation in Java, a key object-oriented principle used to restrict direct access and protect internal data from unauthorized changes. (5 min read, 04 Jan 2026)
Master Binary Search in Java: Fast and Efficient Searching Explained - Learn Binary Search in Java with clear logic, easy code examples, and real-world applications. Boost your coding skills with this step-by-step guide! (5 min read, 03 Jan 2026)
Learn Bubble Sort in Java: Easy Sorting Technique Explained - Get a complete guide on bubble sort in Java, including coding examples and tips to understand this basic but important sorting algorithm. (6 min read, 02 Jan 2026)
Best Java Training Institutes in Hyderabad: Your Guide to Career Success - Find the best Java training institutes in Hyderabad for hands-on learning, placement support, and industry-recognized certifications. (5 min read, 02 Jan 2026)
Understanding Inheritance in Java: Key Concepts & Benefits Explained - Learn all about inheritance in Java with clear examples. Understand types, benefits & how it supports code reusability in object-oriented programming. (8 min read, 02 Jan 2026)
Source: NxtWave - CCBP
Original URL: https://www.ccbp.in/blog/articles/what-is-abstraction-in-java