What are the four pillars of object-oriented programming in Java, and how does each one show up in real code?
The four pillars are encapsulation, abstraction, inheritance and polymorphism. Each has a distinct job, and the useful thing is to point at a specific line of code for each rather than reciting definitions.
Encapsulation is about keeping data consistent. The fields are private and the class controls every read and write through its own methods, so an invariant cannot be broken from outside. Abstraction is about hiding how something is done behind a contract: the caller knows what the type promises, not how it delivers. Inheritance is about reusing and specialising: a subclass takes a parent's behaviour and extends or refines it. Polymorphism is what makes the whole thing useful — a single call site can invoke different implementations depending on the runtime type of the object it holds.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Animal> animals = new ArrayList<>();
animals.add(new Dog("Rex"));
animals.add(new Cat("Mia"));
for (Animal animal : animals) {
System.out.println(animal.describe());
}
}
}
abstract class Animal {
private final String name; // encapsulation: the field is private
protected Animal(String name) {
this.name = name;
}
public String getName() { // encapsulation: controlled access
return name;
}
abstract String sound(); // abstraction: contract, no implementation
public String describe() { // polymorphism: the override is chosen at run time
return getName() + " says " + sound();
}
}
class Dog extends Animal { // inheritance
Dog(String name) {
super(name);
}
@Override
String sound() {
return "woof";
}
}
class Cat extends Animal {
Cat(String name) {
super(name);
}
@Override
String sound() {
return "meow";
}
}The output is two lines — Rex says woof and Mia says meow — and every line of that result was decided by one pillar. The call site animal.describe() knows nothing about dogs or cats; that is polymorphism. The sound method is a promise the abstract class makes, which is abstraction. The private name with a getter is encapsulation. And Dog and Cat exist only because Animal could be inherited.