The Four Pillars
Java was built around object-oriented programming from day one. Encapsulation, inheritance, polymorphism, and abstraction are the language's whole design, not an add-on.
Encapsulation
Encapsulation hides an object's internal state behind private fields and exposes controlled access through getters and setters — so nothing outside the class can put it in an invalid state.
class BankAccount { private double balance; // hidden — no direct outside access public void deposit(double amount) { if (amount <= 0) throw new IllegalArgumentException("bad amount"); balance += amount; // guarded — can't go invalid } public double getBalance() { return balance; } // read-only access } BankAccount acc = new BankAccount(); acc.deposit(100); acc.getBalance(); // 100 // acc.balance = -50; // compile error — balance is private
Inheritance
extends makes one class inherit the fields and methods of another. A subclass calls the parent's constructor with super(...) and can override its methods.
class Animal { String name; Animal(String name) { this.name = name; } String speak() { return name + " makes a sound"; } } class Dog extends Animal { Dog(String name) { super(name); } // call parent constructor @Override String speak() { return name + " barks"; } // override } Dog d = new Dog("Rex"); d.speak(); // "Rex barks" d instanceof Animal; // true
extends exactly one parent. To share behavior from multiple sources, use interfaces (next section) instead.Polymorphism
Polymorphism lets you treat a subclass through its parent type, and Java dispatches to the actual object's overridden method at runtime.
// One Animal-typed list holding different subclasses List<Animal> zoo = List.of( new Dog("Rex"), new Cat("Milo") ); for (Animal a : zoo) { System.out.println(a.speak()); // each calls ITS OWN overridden speak() } // "Rex barks" // "Milo meows"
Abstraction & Interfaces
An interface is a pure contract — a list of methods a class promises to implement. Unlike classes, a class can implement many interfaces, which is how Java gets multiple-inheritance of behavior. Abstract classes sit in between: partial implementation plus abstract methods subclasses must fill in.
interface Shape { double area(); // abstract — no body, must be implemented default String describe() { // default method — shared implementation return "area = " + area(); } } class Circle implements Shape { double r; Circle(double r) { this.r = r; } public double area() { return Math.PI * r * r; } } Shape s = new Circle(2); s.describe(); // "area = 12.566..." — uses the default method
Comparable, Runnable); an abstract class is a partial base for a family of closely related types. A class implements many interfaces but extends only one class.Records & Enums
A record (Java 16+) is a concise, immutable data carrier — one line replaces a class full of fields, a constructor, getters, equals, hashCode, and toString. An enum is a fixed set of named constants.
// record — immutable data carrier, all boilerplate generated record Point(int x, int y) {} Point p = new Point(3, 4); p.x(); // 3 — accessor generated for you p.equals(new Point(3, 4)); // true — value equality, free System.out.println(p); // Point[x=3, y=4] — toString, free // enum — a fixed set of constants enum Day { MON, TUE, WED, THU, FRI, SAT, SUN } Day today = Day.WED; switch (today) { case SAT, SUN -> System.out.println("weekend"); default -> System.out.println("weekday"); }