1.5 Abstraction & Modern Interfaces
← Back to Chapter 1: OOPs Concepts
Abstraction is the technique of hiding implementation complexity while exposing only the essential interface to consumers. Java provides two tools for abstraction: Abstract Classes and Interfaces.
1. Abstract Classes vs Interfaces (Java 8 to Java 21)
| Feature | Abstract Class | Interface |
|---|---|---|
| Instance State | Can maintain non-final instance fields | Fields are strictly public static final (constants) |
| Constructors | Supported (called via super()) | Not supported |
| Inheritance | Single class inheritance (extends) | Multiple interface implementation (implements) |
| Speed | Slightly faster method invocation | Minimal indirection via itables |
| Purpose | Shared identity, base logic, and partial state | Contract declaration across disparate hierarchies |
2. Evolution of Java Interfaces
Java interfaces are no longer purely abstract method declarations:
A. Default Methods (Java 8)
Added to evolve interfaces with backward compatibility (e.g., adding stream() to java.util.Collection without breaking millions of legacy implementations):
public interface Cache<K, V> {
void put(K key, V value);
V get(K key);
// Default method: provides default fallback behavior
default boolean contains(K key) {
return get(key) != null;
}
}
B. Static Methods (Java 8)
Utility methods bound directly to the interface namespace:
public interface CryptoService {
String encrypt(String raw);
static CryptoService createDefault() {
return new AesCryptoServiceImpl();
}
}
C. Private Methods (Java 9)
Enables code reuse between default methods without leaking internal helpers into the public API:
public interface Auditor {
default void auditSuccess(String op) {
log(op, "SUCCESS");
}
default void auditFailure(String op) {
log(op, "FAILURE");
}
private void log(String op, String status) {
System.out.println("[AUDIT] " + System.currentTimeMillis() + " " + op + " : " + status);
}
}
3. Resolving Multiple Interface Collisions
If a class implements two interfaces with the identical default method signature:
interface Reader { default void inspect() { System.out.println("Reader"); } }
interface Writer { default void inspect() { System.out.println("Writer"); } }
public class FileManager implements Reader, Writer {
// Compiler Error if not resolved explicitly!
@Override
public void inspect() {
Reader.super.inspect(); // Explicit disambiguation
}
}