OOP Abstraction: Fundamentals, Interfaces & Design by Contract
This article provides a definition and explanation of abstraction in object-oriented programming — complete with exam-relevant concepts and study notes.
In a Nutshell
Abstraction reduces complex systems to their essential properties and operations. It defines the what of an interface while keeping the how hidden, allowing implementations to evolve independently.
Core Definition
Abstraction is a fundamental principle that reduces complex reality to relevant properties and hides irrelevant details. In OOP, abstraction manifests through:
- Interfaces: Pure contract definitions with no implementation
- Abstract Classes: Partial implementation combined with abstract methods
- Design by Contract: Preconditions, postconditions, and invariants
Abstraction enables independent development of implementations as long as the contract is honored. It supports the Open Closed Principle: extend systems through new implementations without modifying existing code.
Separating the what (interface) from the how (implementation) is core to sound software architecture. Abstraction reduces cognitive load, promotes reusability, and enables flexible, testable systems.
Key Exam Concepts
- What vs How: Interface defines what; implementation defines how
- Interfaces: Pure contracts, no implementation
- Abstract Classes: Mix of concrete and abstract methods
- Design by Contract: Preconditions, postconditions, invariants
- Open Closed Principle: Extensible without modification
- Abstraction vs Encapsulation: Abstraction hides complexity; encapsulation protects data
- Polymorphism: Multiple implementations of a single interface
- Dependency Inversion: Depend on abstractions, not concrete implementations
Essential Components
- Interface: Defines method signatures without implementation
- Abstract Class: May contain partially implemented methods
- Concrete Class: Implements all abstract methods
- Contract: Guaranteed behavior of an implementation
- Preconditions: Requirements that must hold before a method call
- Postconditions: Guarantees that hold after method execution
- Invariants: Conditions that must always be true
- Dependency Injection: Passing abstractions instead of concrete classes
Practical Example
// Interface: Defines the contract
interface DatabaseConnection {
void connect(String url, String user, String password);
void disconnect();
ResultSet executeQuery(String sql);
void executeUpdate(String sql);
}
// Abstract Class: Shared functionality
abstract class AbstractDatabase implements DatabaseConnection {
protected boolean connected = false;
protected String url;
@Override
public void connect(String url, String user, String password) {
if (connected) {
throw new IllegalStateException("Already connected");
}
this.url = url;
// Check preconditions
validateConnectionParameters(url, user, password);
// Abstract method implemented by subclasses
doConnect(url, user, password);
connected = true;
// Postcondition: connection must be established
assert connected : "Connection failed";
}
@Override
public void disconnect() {
if (!connected) {
throw new IllegalStateException("Not connected");
}
doDisconnect();
connected = false;
}
// Abstract methods for subclasses to implement
protected abstract void doConnect(String url, String user, String password);
protected abstract void doDisconnect();
// Shared validation
private void validateConnectionParameters(String url, String user, String password) {
if (url == null || url.trim().isEmpty()) {
throw new IllegalArgumentException("URL required");
}
if (user == null || user.trim().isEmpty()) {
throw new IllegalArgumentException("User required");
}
}
}
// Concrete Implementation
class MySQLDatabase extends AbstractDatabase {
@Override
protected void doConnect(String url, String user, String password) {
System.out.println("Establishing MySQL connection to: " + url);
// MySQL-specific connection logic
}
@Override
protected void doDisconnect() {
System.out.println("Disconnecting MySQL connection");
// MySQL-specific disconnection logic
}
@Override
public ResultSet executeQuery(String sql) {
if (!connected) {
throw new IllegalStateException("Not connected");
}
System.out.println("Executing MySQL query: " + sql);
return null; // Actual ResultSet implementation
}
@Override
public void executeUpdate(String sql) {
if (!connected) {
throw new IllegalStateException("Not connected");
}
System.out.println("Executing MySQL update: " + sql);
}
}
// Usage with Dependency Injection
class DatabaseService {
private final DatabaseConnection connection;
// Depend on abstraction, not concrete implementation
public DatabaseService(DatabaseConnection connection) {
this.connection = connection;
}
public void displayData() {
connection.connect("jdbc:mysql://localhost:3306/db", "user", "pass");
ResultSet rs = connection.executeQuery("SELECT * FROM customers");
// Process data...
connection.disconnect();
}
}
Advantages and Disadvantages
Advantages
- Complexity Reduction: Irrelevant details remain hidden
- Flexibility: Different implementations can be swapped easily
- Testability: Mocks and stubs are straightforward to create
- Maintainability: Changes to implementation don’t affect the interface
- Teamwork: Parallel development of interface and implementation
Disadvantages
- Indirection: Additional layers increase complexity
- Overhead: More code required for simple tasks
- Learning Curve: Abstract thinking requires practice
- Over-Engineering: Too many abstractions for simple problems
Common Exam Questions
-
What’s the difference between abstraction and encapsulation? Abstraction hides complexity (the what), while encapsulation protects data (the how).
-
When do you use an interface versus an abstract class? Use interfaces for pure contract definitions; use abstract classes when you need shared implementation.
-
What is Design by Contract? Defining preconditions, postconditions, and invariants for software components.
-
How does abstraction support the Open Closed Principle? Systems can be extended with new implementations without modifying existing code.
Key References
- https://en.wikipedia.org/wiki/Abstraction_(computer_science)
- https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
- https://en.wikipedia.org/wiki/Design_by_contract
Continue Your OOP Learning Path
The next article in the OOP learning path covers OOP Class Relationships: Association, Aggregation, Composition & Inheritance — how classes interact with one another.



