The Four Pillars of Object-Oriented Programming

Encapsulation, abstraction, inheritance, and polymorphism are the four core principles of OOP. Learn what each one means with simple explanations.

Published September 22, 2026

Object-oriented programming is commonly described through four core principles: encapsulation (bundling data with the methods that operate on it, hiding internal state), abstraction (exposing only relevant details while hiding implementation complexity), inheritance (a class acquiring behavior from a parent class), and polymorphism (treating different types through a common interface).

Common causes

  • These principles emerged as a way to manage complexity in large software systems by modeling code around real-world-like objects with clear boundaries and responsibilities

How to fix it

  • Apply encapsulation by making fields private and exposing controlled access through methods, rather than letting external code freely modify internal state
  • Apply abstraction by designing classes/interfaces around what a consumer needs to know, not how it's implemented internally
  • Use inheritance sparingly and only for genuine 'is-a' relationships — favor composition ('has-a') when you just want to reuse behavior without a strict hierarchy
  • Use polymorphism so calling code can work with a common interface (like Shape) without needing to know the concrete type (Circle vs Square) it's actually dealing with

Example

class Shape {
  area() { throw new Error('not implemented') }
}
class Circle extends Shape {
  constructor(r) { super(); this.r = r }
  area() { return Math.PI * this.r ** 2 }
}

FAQ

Is inheritance always the right way to reuse code?

No — 'favor composition over inheritance' is a widely held principle, because deep inheritance hierarchies can become rigid and hard to change. Inheritance fits genuine is-a relationships; composition fits reusing behavior without one.

More General articles