The Four Pillars of OOP in Java (Explained Simply)
The four pillars of object-oriented programming are encapsulation, inheritance, polymorphism and abstraction. Here's what each means in Java, with examples, the differences interviewers probe, and when to use them.
Object-oriented programming in Java rests on four pillars: encapsulation, inheritance, polymorphism, and abstraction. They’re the ideas that turn a pile of code into well-organised, reusable objects — and they’re the most-asked topic in any Java interview.
Here’s each pillar in plain terms, with a Java example and the distinctions interviewers love to probe (especially abstraction vs encapsulation, and interface vs abstract class).
1. Encapsulation — hide the data
Encapsulation means keeping an object’s data private and exposing controlled access through methods. The object guards its own state.
public class BankAccount {
private double balance; // hidden from outside
public void deposit(double amount) {
if (amount > 0) balance += amount; // controlled access
}
public double getBalance() {
return balance;
}
}
Nobody can set balance to a negative number directly — they must go through deposit, which enforces the rules. Why it matters: you can change the internals later without breaking other code, and invariants stay protected.
2. Inheritance — build on what exists
Inheritance lets a class reuse and extend another class with extends. The child gets the parent’s fields and methods and can add or override its own.
public class Animal {
protected String name;
public Animal(String name) { this.name = name; }
public String speak() { return "..."; }
}
public class Dog extends Animal {
public Dog(String name) { super(name); } // call parent constructor
@Override
public String speak() { return name + " says woof"; }
}
Why it matters: shared behaviour lives in one place. Use it for genuine “is-a” relationships (a Dog is an Animal) — and prefer composition when there’s no true is-a, since deep hierarchies get brittle.
3. Polymorphism — one interface, many forms
Polymorphism means the same call does different things depending on the actual object behind a reference.
Animal a = new Dog("Rex");
System.out.println(a.speak()); // "Rex says woof" — Dog's version runs
a = new Cat("Milo");
System.out.println(a.speak()); // "Milo says meow" — Cat's version runs
The variable is typed Animal, but Java dispatches to the real object’s method at runtime. Why it matters: you can write code against the general type (Animal) and it works with any subtype — the basis of flexible, extensible design.
Animal and works with every current and future subclass without changes. Program to the general type, and new implementations slot in for free.
4. Abstraction — expose what, hide how
Abstraction means exposing a simple, essential interface and hiding the messy details. In Java you express it with interfaces and abstract classes.
public interface Shape {
double area(); // WHAT every shape does — not how
}
public class Circle implements Shape {
private double r;
public Circle(double r) { this.r = r; }
public double area() { return Math.PI * r * r; } // the HOW
}
Code that uses Shape never needs to know how area() is computed. Why it matters: you depend on contracts, not implementations, so parts of the system evolve independently.
The distinctions interviewers probe
Abstraction vs encapsulation — the most common trick question:
- Abstraction hides complexity (design level — “what does it do?”), via interfaces/abstract classes.
- Encapsulation hides data (implementation level — “protect the fields”), via
private+ methods.
Interface vs abstract class:
| Interface | Abstract class | |
|---|---|---|
| State (fields) | no instance state | can have fields |
| Methods | abstract + default (Java 8+) | abstract + concrete |
| Multiple? | a class implements many | extends only one |
| Use for | a capability/contract | shared base behaviour |
A rule of thumb: use an interface to say “can do X” (capability), an abstract class to share a common base with state.
Common mistakes
- Public fields instead of private + accessors — breaks encapsulation.
- Overusing inheritance for code reuse where the types aren’t truly related. Prefer composition.
- Forgetting
@Override— the annotation catches typos that would otherwise silently create a new method instead of overriding. - Confusing abstraction with encapsulation in interviews — keep “hides complexity” vs “hides data” straight.
@Override and misspelling the method name (e.g. speak() vs Speak()) creates a brand-new method — the parent's version still runs, and the bug is silent. Always annotate overrides.
Where this fits
The four pillars are Phase 2 of our Java roadmap — the heart of the language. They lead directly into the Collections framework (built on interfaces and generics) and streams and lambdas (functional interfaces).
They’re drawn out with diagrams in Java in One Month (the full beginner path) and taken to interview depth — design trade-offs, SOLID, composition vs inheritance — in Java in Three Months. For sealed types, design patterns, and architecture-level OOP, Java for Staff Engineers goes deeper.
Master the four pillars and the rest of Java is detail layered on a solid frame.
Frequently asked questions
What are the four pillars of OOP in Java?
Encapsulation (hiding data behind methods), inheritance (building classes on other classes), polymorphism (one interface, many implementations), and abstraction (exposing what something does, not how). Together they organise code into reusable, maintainable objects.
What is the difference between abstraction and encapsulation?
Abstraction hides complexity — it exposes only what an object does, through interfaces or abstract classes, hiding how. Encapsulation hides data — it keeps fields private and controls access through methods. Abstraction is about design (the 'what'); encapsulation is about implementation (protecting the 'how').
What is the difference between an interface and an abstract class in Java?
An abstract class can have both abstract and concrete methods plus state (fields), and a class can extend only one. An interface defines a contract; since Java 8 it can have default methods but holds no instance state, and a class can implement many interfaces. Use an interface for a capability and an abstract class for shared base behaviour.
What is polymorphism in Java with an example?
Polymorphism lets one reference type point to different implementations. If Animal has a speak() method and Dog and Cat override it, then Animal a = new Dog() calls Dog's speak(), while Animal a = new Cat() calls Cat's. The same call behaves differently based on the actual object.