Abstraction and loose coupling, abstract classes vs interfaces (with Java 8/9 changes), default and static interface methods, the diamond problem, Comparable vs Comparator, and encapsulation done right.
Published September 25, 2026
"Abstract class vs interface" is probably the most asked OOP question in Java interviews, and many prepared answers are out of date: they still say "interfaces can only have abstract methods". Give the modern answer, and explain when you'd choose each one.
Short answer: Abstraction means exposing what an object does while hiding how it does it. In Java you express it with interfaces and abstract classes: callers depend on the contract, not on the implementation.
public interface PaymentGateway {
PaymentResult charge(Order order); // what — the contract
}
class RazorpayGateway implements PaymentGateway {
public PaymentResult charge(Order order) { /* how — HTTP calls, retries, signatures */ return null; }
}
Learn it in depth → Interfaces and Abstract Classes
Short answer: Everywhere. The Collections Framework is the classic example: you code against List, Map and Set, and you can swap ArrayList for LinkedList without changing the calling code.
Key points to cover:
Connection, PreparedStatement and ResultSet are interfaces. Each database vendor supplies the implementation.InputStream and Reader hide whether bytes come from a file, a socket or memory.java.util.concurrent: you submit tasks to an ExecutorService without knowing how its threads are managed.JpaRepository, and Spring generates the implementation at runtime.Short answer: The class must itself be declared abstract, or it won't compile. An abstract class can't be instantiated with new. A concrete subclass must implement all the abstract methods, or it must be declared abstract as well.
Key points to cover:
static methods.Short answer: When a class depends on an interface rather than a concrete class, you can change, replace or mock the implementation without touching the class. Changes stay contained, and testing becomes easy.
class CheckoutService {
private final PaymentGateway gateway; // depends on the abstraction
CheckoutService(PaymentGateway gateway) { this.gateway = gateway; }
}
// production: new CheckoutService(new RazorpayGateway())
// unit test: new CheckoutService(mock(PaymentGateway.class))
Key points to cover:
Learn it in depth → Dependency Inversion
Short answer: An interface is a reference type that defines a contract: a set of methods that implementing classes must provide. A class can implement many interfaces.
Key points to cover:
public abstract).public static final).default and static methods (Java 8).private methods (Java 9).Serializable, Cloneable) have no methods at all.Short answer: An abstract class is a partially built parent. It can hold state, constructors and shared code, and a class can extend only one. An interface is a capability contract. It has no instance state, and a class can implement many.
| Abstract class | Interface | |
|---|---|---|
| Inheritance | extends one only | implements many |
| Instance fields (state) | Yes | No (constants only) |
| Constructors | Yes | No |
| Method kinds | Abstract + concrete (any access level) | Abstract, default, static, private |
| Default access of members | Package-private | public |
| Typical meaning | "is a kind of" (template) | "can do" (capability) |
Common trap: saying "interfaces give 100% abstraction and can only have abstract methods". That was true before Java 8. Today interfaces can contain default, static and private method bodies. What they still can't have is instance state.
Learn it in depth → Interfaces and Abstract Classes
Short answer:
Comparable, PaymentGateway, Runnable), and whenever you want multiple implementations or easy mocking. It's the default choice.Key points to cover:
List and AbstractList in the JDK.Short answer: A class can implement several interfaces, so it inherits several types. It can be passed wherever any of them is expected.
class SmartCamera implements Recordable, Streamable, AutoCloseable {
public void record() { }
public void stream() { }
public void close() { }
}
Key points to cover:
extend multiple interfaces: interface Device extends Recordable, Streamable {}.Short answer: Yes, since Java 8.
InterfaceName.method(), and it's not inherited by implementing classes, so it can't be overridden.public interface Discount {
BigDecimal apply(BigDecimal price);
default Discount andThen(Discount next) { // inherited, overridable
return price -> next.apply(apply(price));
}
static Discount percent(int p) { // utility/factory: Discount.percent(10)
return price -> price.multiply(BigDecimal.valueOf(100 - p)).divide(BigDecimal.valueOf(100));
}
}
Key points to cover:
Collection.stream() and Iterable.forEach() were introduced.Short answer: The diamond problem arises when a class inherits the same method from two parents that share an ancestor, which makes it ambiguous which version to use. Java avoids it for classes by allowing only single inheritance. For interface default methods, the compiler forces the class to resolve the conflict explicitly.
interface Printer { default String name() { return "printer"; } }
interface Scanner { default String name() { return "scanner"; } }
class AllInOne implements Printer, Scanner {
@Override public String name() { // required, or it's a compile error
return Printer.super.name() + "+" + Scanner.super.name();
}
}
Key points to cover:
Comparable and Comparator?Short answer: Comparable defines a class's natural ordering. The class itself implements compareTo, and there's exactly one such ordering. Comparator defines an external, custom ordering. You can have as many as you like, and you pass them to sorting methods.
record Employee(String name, int salary) implements Comparable<Employee> {
public int compareTo(Employee o) { return name.compareTo(o.name); } // natural order: by name
}
employees.sort(Comparator.comparingInt(Employee::salary).reversed() // custom: salary desc,
.thenComparing(Employee::name)); // then by name
Key points to cover:
Collections.sort(list) and TreeSet use the natural order. Pass a Comparator for anything else.return a.salary - b.salary;), because it overflows for large values. Use Integer.compare(a, b) or Comparator.comparingInt.compareTo consistent with equals. A TreeSet treats a compareTo result of 0 as a duplicate.Learn it in depth → TreeMap & LinkedHashMap
Short answer: Encapsulation means bundling data with the methods that operate on it, and restricting direct access to that data. Fields are private, and the class exposes controlled operations that keep its state valid.
public class Wallet {
private long balancePaise; // hidden state
public void debit(long paise) { // controlled access keeps the invariant
if (paise <= 0) throw new IllegalArgumentException("amount must be positive");
if (paise > balancePaise) throw new IllegalStateException("insufficient balance");
balancePaise -= paise;
}
public long balancePaise() { return balancePaise; } // read-only view
}
Key points to cover:
Learn it in depth → Classes and Objects
Short answer: Only the class's own methods can change its state, so every change goes through validation. Invalid states become impossible, misuse is limited, and the internal representation can change without breaking callers.
Key points to cover:
List.copyOf(items), or an unmodifiable view, instead of the internal list. Otherwise callers can modify your state behind your back.final fields, no setters) makes objects inherently thread safe.Q: Can an abstract class implement an interface without implementing its methods? A: Yes. The abstract class can leave some or all interface methods unimplemented. The first concrete subclass must implement whatever is left.
Q: Can an interface extend a class? A: No. An interface can only extend other interfaces.
Q: Why were private methods added to interfaces in Java 9?
A: So that several default methods can share helper code without exposing that helper as part of the public contract.
Q: Are abstraction and encapsulation the same thing? A: No, although they work together. Abstraction is about designing a simple outward view (what to expose). Encapsulation is about enforcing it: hiding and protecting the internals behind access control.