Java abstraction exposes a stable contract while hiding implementation detail. Abstract classes can share state and behavior; interfaces define capabilities that unrelated types can implement.
A practical abstraction example should show the caller using a general type while the program chooses a concrete implementation behind it. This is the reason abstraction makes code flexible: the caller depends on behavior, not construction details.
In a service layer, abstraction lets tests replace real database, payment, or email implementations with fake versions. That makes code easier to test without changing the caller.
Depend on Java contracts rather than construction details, choosing an abstract class for shared implementation and an interface for a capability boundary.
An abstract class can contain abstract methods and concrete methods. Use it when closely related classes share state or reusable code.
abstract class Report {
abstract String title();
void printHeader() {
System.out.println("Report: " + title());
}
}
class SalesReport extends Report {
String title() {
return "Sales";
}
}
An interface defines a capability. Classes implement interfaces to promise that they provide those methods.
interface Exporter {
void export(String data);
}
class PdfExporter implements Exporter {
public void export(String data) {
System.out.println("Exporting PDF: " + data);
}
}
Use an interface for a capability that many unrelated classes can implement. Use an abstract class for a shared base among related classes.
| Feature | Abstract Class | Interface |
|---|---|---|
| State | Can have instance fields | Constants only |
| Inheritance | Class extends one abstract class | Class implements multiple interfaces |
| Best for | Shared base behavior | Capability/contract |
Use an abstract class when related classes share state or base behavior. Use an interface when unrelated classes must promise the same capability, such as Comparable, Runnable, or AutoCloseable.
Abstraction means exposing the important behavior and hiding unnecessary implementation details. In Java, abstraction is commonly created with interfaces and abstract classes. A caller can depend on pay(), save(), or send() without knowing whether the actual implementation uses a card gateway, a database table, or an email provider.
The practical value of abstraction is flexibility. If code depends on a PaymentGateway interface, you can replace CardPayment with UpiPayment or MockPayment without rewriting the checkout flow. The page is not only about the abstract keyword; it is about separating the contract from the implementation.
interface Notifier {
void send(String message);
}
class EmailNotifier implements Notifier {
public void send(String message) {
System.out.println("Email: " + message);
}
}
Yes. It can mix shared implementation with abstract methods.
Use an interface for a capability that unrelated classes can implement.
No. Instantiate a concrete subclass that implements the missing methods.
Explore 500+ free tutorials across 20+ languages and frameworks.