Java Abstraction
Abstraction is the process of hiding complex internal implementation details and showing only the essential features to the user. In Java, abstraction is achieved using abstract classes and interfaces.
The goal of abstraction is to reduce complexity — users of a class interact with a simplified model without needing to understand what happens internally.
Real-World Analogy
Consider a TV remote control. The remote has simple buttons — power, volume, channel. The user presses a button and the TV responds. The complex circuitry and signal processing inside the remote is hidden. The user only sees and interacts with the essential interface.
Abstract Classes
An abstract class is a class that cannot be instantiated (no objects can be created from it directly). It may contain:
- Abstract methods: Methods with no body — declared but not implemented. Subclasses must provide the implementation.
- Concrete methods: Regular methods with a full implementation that subclasses inherit.
Syntax
abstract class ClassName {
abstract void abstractMethod(); // no body
void concreteMethod() {
// has a body
}
}Example – Payment System
abstract class Payment {
String merchantName;
Payment(String merchantName) {
this.merchantName = merchantName;
}
// Abstract method – each payment type must define this
abstract void processPayment(double amount);
// Concrete method – shared by all subclasses
void printReceipt(double amount) {
System.out.println("Receipt: Paid Rs. " + amount + " to " + merchantName);
}
}
class CreditCardPayment extends Payment {
CreditCardPayment(String merchant) {
super(merchant);
}
@Override
void processPayment(double amount) {
System.out.println("Processing Credit Card payment of Rs. " + amount);
}
}
class UPIPayment extends Payment {
UPIPayment(String merchant) {
super(merchant);
}
@Override
void processPayment(double amount) {
System.out.println("Processing UPI payment of Rs. " + amount);
}
}
public class Main {
public static void main(String[] args) {
Payment p1 = new CreditCardPayment("BookStore");
p1.processPayment(1500);
p1.printReceipt(1500);
System.out.println();
Payment p2 = new UPIPayment("SuperMart");
p2.processPayment(800);
p2.printReceipt(800);
}
}Output:
Processing Credit Card payment of Rs. 1500.0
Receipt: Paid Rs. 1500.0 to BookStore
Processing UPI payment of Rs. 800.0
Receipt: Paid Rs. 800.0 to SuperMartRules for Abstract Classes
- Declared using the
abstractkeyword. - Cannot be instantiated directly (
new Payment()is not allowed). - Can have both abstract and concrete methods.
- Can have constructors, fields, and static methods.
- A subclass must implement all abstract methods, or it must itself be declared abstract.
// Payment p = new Payment("test"); // ERROR – cannot instantiate abstract classAbstract Class with All Concrete Methods
An abstract class is allowed to have no abstract methods — it is simply a class that cannot be instantiated directly. This is useful when the class is meant to be a partial base that should always be extended.
abstract class Template {
void step1() { System.out.println("Step 1: Initialize"); }
void step2() { System.out.println("Step 2: Process"); }
void step3() { System.out.println("Step 3: Finalize"); }
}Abstract Class vs Concrete Class
| Feature | Abstract Class | Concrete Class |
|---|---|---|
| Instantiation | Cannot be instantiated | Can be instantiated |
| Abstract methods | Can have | Cannot have |
| Concrete methods | Can have | Can have |
| Purpose | Provide a partial base for subclasses | Provide a complete, usable blueprint |
Achieving Abstraction with Interfaces
Interfaces provide a higher level of abstraction than abstract classes. In an interface, all methods are implicitly abstract (prior to Java 8). Interfaces are covered in full detail in the next topic. The comparison is:
| Feature | Abstract Class | Interface |
|---|---|---|
| Method types | Abstract + concrete | Abstract (default/static in Java 8+) |
| Fields | Any type | Only public static final (constants) |
| Multiple inheritance | Not supported | Supported |
| Use when | Shared base with some implementation | Pure contract / multiple inheritance needed |
Template Method Pattern – A Real Use of Abstraction
Abstract classes are ideal for defining a fixed algorithm structure where some steps are customized by subclasses.
abstract class DataProcessor {
// Template method – fixed sequence
void process() {
readData();
processData();
writeData();
}
void readData() {
System.out.println("Reading data from source...");
}
abstract void processData(); // customized by subclasses
void writeData() {
System.out.println("Writing results to output...");
}
}
class CSVProcessor extends DataProcessor {
@Override
void processData() {
System.out.println("Processing CSV data...");
}
}
class JSONProcessor extends DataProcessor {
@Override
void processData() {
System.out.println("Processing JSON data...");
}
}
public class Main {
public static void main(String[] args) {
DataProcessor csv = new CSVProcessor();
csv.process();
System.out.println();
DataProcessor json = new JSONProcessor();
json.process();
}
}Output:
Reading data from source...
Processing CSV data...
Writing results to output...
Reading data from source...
Processing JSON data...
Writing results to output...Summary
- Abstraction hides implementation details and exposes only what is necessary.
- Abstract classes are declared with the
abstractkeyword and cannot be instantiated. - Abstract methods have no body and must be implemented by subclasses.
- Abstract classes can contain both abstract and concrete methods.
- If a subclass does not implement all abstract methods, it must also be declared abstract.
- Use abstract classes when subclasses share common code with some customizable behavior.
