Skip to content
Historical revision
Object-Oriented Programming2026-05-17 19:09 UTC
rev_3121025e9fd14f5ea17208f4f5aee340

Object-Oriented Programming

Object-Oriented Programming

Preface

People often call design patterns a universal solution. Now that OOP has been established and the Gang of Four's book on design patterns has become something of a gospel, many developers open the pattern book, glance at the structural diagrams, and write code from there. The result is often a rigid implementation with no flexibility.

When learning design methodologies and patterns, we constantly waver in the gap between 'schematic understanding' and 'practical experience'. As Christopher Alexander argued, decomposing design methods from the substance of design ultimately leaves us speaking of nothing but empty abstractions.1

There are actually several branches worth exploring before getting to patterns, including idioms, but that discussion is reserved for the Programming Idioms article; this piece focuses on the true nature of OOP as it surrounds the topic of patterns.


Object-Oriented Programming (OOP) is a programming paradigm that organizes a program by bundling data and the procedures that manipulate that data into units called objects. The core idea is encapsulating data and functions that were separate in procedural programming into a single unit. It originated in the Simula language in the 1960s and has since become one of the most widely used paradigms in the industry today.

Important caveat: the OOP we commonly use today is not the message-based object-oriented model that Alan Kay originally envisioned, but rather a class-based OOP that traces its roots to Simula and was gradually shaped in industry through figures such as Bjarne Stroustrup, Peter Wegner, Bertrand Meyer, and Grady Booch. It is not the product of a single author or a single book, but a collaborative development that unfolded from the late 1980s through the early 1990s; the OOP you encounter in textbooks, interviews, and design pattern books is a later, simplified form of this collective work.

For other meanings, see the following:

  • The original object-oriented model proposed by Alan Kay: Message-based OOP

  • Prototype-based OOP: Prototype-based Programming

Table of Contents

  1. Preface

  2. Overview

  3. History

  4. Booch's Object Model: 4 major + 3 minor

  5. The Origin of OOP's Three Elements (Encapsulation, Inheritance, Polymorphism)

  6. Message-Based OOP vs. Class-Based OOP

  7. Core Concepts

  8. Design Principles

  9. Design Patterns

  10. Advantages and Disadvantages

  11. Criticisms

  12. See Also

  13. Footnotes

Overview

The definition of OOP varies subtly depending on the era and the person defining it. No single authoritative definition exists; multiple definitions coexist.

  • Alan Kay (1967, redefined 2003): Considers messaging, local retention and hiding of state and processing, and extreme late binding to be its core principles.

  • Grady Booch (1991): Proposes the Booch Object Model, composed of 4 major elements (Abstraction, Encapsulation, Modularity, Hierarchy) and 3 minor elements (Typing, Concurrency, Persistence).

  • Bertrand Meyer (1988, OOSC): A formal OOP definition centered on Design by Contract.

  • Peter Wegner (1987, OOPSLA): Distinguishes progressively between object-based, class-based, and object-oriented.

  • Later, the popular industry definition: A simplification of the above lineage into the three pillars of Encapsulation, Inheritance, and Polymorphism (no single clear authorial source exists).

The gap between these definitions is not merely an academic debate; it serves as the starting point for deciding how OOP is applied in practice.

History

The background behind the patterns we are discussing

1962–1967: The Emergence of Simula and the Class

The concept of the class was first introduced in Simula (1962) and Simula 67 (1967), developed by Norwegian researchers Kristen Nygaard and Ole-Johan Dahl for the purpose of discrete-event simulation. It would go on to become the origin of all class-based OOP.2

1967: Alan Kay's Starting Point

The term "object-oriented programming" itself was first coined by Alan Kay, who used the expression "object-oriented" as early as 1967.3 He later realized his vision through Smalltalk at Xerox PARC.

2003: Kay's Self-Correction

In a 2003 email to Stefan Ram, Kay later made clear that what he had meant by object-oriented programming consisted of exactly three things:3

  1. Messaging

  2. Local retention and protection and hiding of state-process

  3. Extreme late-binding of all things

Put simply, the object Kay had in mind was something like a small computer. Each object exists independently and collaborates by passing messages to one another. Rather than designing class hierarchies, the central question was "what messages pass between objects".

Described this way, however, it does not match the OOP concept most of us think of. So where did the concept we are familiar with actually come from?

Late 1980s to Early 1990s: The Formation of Industrial OOP

The OOP we use today was not defined by any single individual; rather, it took shape gradually through the combined contributions of multiple figures from the late 1980s through the early 1990s.

1985: Stroustrup and C++

Bjarne Stroustrup released C++, porting Simula's class model into the C language.4 C++ was the first decisive language to bring class-based OOP into the industry, and it subsequently became the de facto reference point for all mainstream OOP languages that followed.

1987: Wegner's Classification

Peter Wegner, in his OOPSLA 1987 paper "Dimensions of Object-Based Language Design", proposed the following graduated distinctions.5

  • Object-based: objects + encapsulation (e.g., Ada, Modula-2)

  • Class-based: object-based + classes (e.g., CLU)

  • Object-oriented: class-based + inheritance (e.g., Smalltalk, C++)

This classification would go on to directly influence the formation of the three popularly recognized elements of OOP.

1988: Meyer and OOSC

Bertrand Meyer published Object-Oriented Software Construction (OOSC, 1988). Drawing on the Eiffel language he had designed, he established the formal foundations of OOP, including Design by Contract, invariants, and class invariants. Meyer's OOSC and Booch's OOAD together stood as the two pillars of OOP education throughout the 1990s.

1991: Booch's OOAD

Grady Booch published Object-Oriented Analysis and Design with Applications (1991).6 In this book, Booch defined OOP as follows (p. 37).

"Object-oriented programming is a method of implementation in which programs are organized as cooperative collections of objects, each of which represents an instance of some class, and whose classes are all members of a hierarchy of classes united via inheritance relationships."

In summary, three propositions follow.

  1. OOP uses objects, not algorithms, as its logical building blocks.

  2. Each object is an instance of some class.

  3. Classes are connected to one another through inheritance relationships.

Booch's real contribution, however, lies less in the definition above and more in his object model (4 major + 3 minor elements) and his visual notation (Booch notation). For details, see the Booch's Object Model: 4 major + 3 minor section.

1994: The GoF and the Age of Patterns

Against the backdrop of class-based OOP taking hold in the 1980s and 1990s, one towering programming classic emerged in 1994: the GoF Design Patterns. Its four authors, Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, gave rise to the name Gang of Four.

The GoF drew inspiration from Christopher Alexander's A Pattern Language (1977), yet ironically fell into the very trap Alexander had warned against: the schematization of methodology. The moment patterns were reduced from a question of "why" to a question of "what," a culture emerged in which developers memorized diagrams and crammed them into code. For details, see the document on the schematization trap of patterns.

Post-1995: Java and Enterprise Entrenchment

Java (1995) and later C# (2002) effectively mandated class-based OOP at the language level. Java's design, which required all code to reside inside a class, became the standard paradigm for enterprise software.

Post-2000s: Reassessment

With the rise of functional programming and the emergence of Data-Oriented Design (DOD), the limitations of OOP began to be discussed in earnest. It was also during this period that Alan Kay himself began distancing himself from class-based OOP, stating that it diverged from his original intent.

Booch's Object Model: 4 major + 3 minor

Chapter 2, "The Object Model," of Booch's 1991 book enumerates the elements of the object model as follows.67

Classification

Element

Description

Major (Required)

Abstraction

Extracting essential characteristics

Major (Required)

Encapsulation

Concealing the internals of an abstraction

Major (Required)

Modularity

Decomposing into units of high cohesion and low coupling

Major (Required)

Hierarchy

A hierarchy of "is-a" and "part-of" relationships

Minor (Optional)

Typing

Type safety based on abstract data types

Minor (Optional)

Concurrency

Distinction between active and passive objects

Minor (Optional)

Persistence

Preservation of object state across time and space

The key points to note here are as follows.

  • Booch did not explicitly list "Polymorphism" as an independent element of the object model. Polymorphism is merely implied within the concept of Hierarchy.

  • Booch does not treat "Inheritance" as a standalone element but subsumes it as one form of "Hierarchy." Hierarchy is a broader concept that encompasses not only the "is-a" relationship corresponding to inheritance, but also the "part-of" relationship associated with aggregation and composition.

  • Modularity, Concurrency, and Persistence are software-engineering-level concepts explicitly included in Booch's object model, which makes his model considerably richer than the conventional three pillars.

There is therefore a significant gap between Booch's actual model and the "three elements" we encounter in coding bootcamps or job interviews.

The origins of OOP's three elements (Encapsulation, Inheritance, and Polymorphism)

The three elements (or three pillars) of OOP commonly cited as Encapsulation, Inheritance, and Polymorphism are not a definition established by a single author, but rather a popular formulation that solidified incrementally within the software industry.

How It Took Shape

  1. Simula 67 (1967): introduced classes, instances, and inheritance at the language level.

  2. Smalltalk (1972~): implemented encapsulation and polymorphism through message passing.

  3. Peter Wegner (1987): proposed a stepwise distinction from "object-based" to "class-based" to "object-oriented," making clear that inheritance is the decisive feature separating OOP from other paradigms.5

  4. The C++ camp (1985~1990s): industry training materials began circulating the formulation that "true OOP means having all three: encapsulation, inheritance, and polymorphism." The following kind of statement became common:

    Using encapsulation alone (that is, defining and using classes without employing inheritance or polymorphism) is often called object-based programming. To practice true OOP, you must use all three pillars: encapsulation, inheritance, and polymorphism.8

  5. The Java era (1995~): this formulation became entrenched in standard textbooks and educational materials.

A note on sources

  • The "three elements" are not Booch's invention. Booch's book presents a model with four major elements and three minor ones, nothing more.

  • The "three elements" are not Kay's definition either. Kay's definition centers on messaging, encapsulation, and dynamic binding.

  • The "three elements" are a popular consensus formulation from the software industry, not traceable to any single book.

Failing to recognize this leads to the error of reducing the history of OOP to the work of one person (Booch).

Personal note: In fact, the history of OOP is more commonly viewed as the work of Alan Kay alone, so the mistaken impression that it was Booch's story may be an entirely personal misconception of my own.

Message-based OOP and Class-based OOP

OOP has effectively split into two distinct streams.

Category

Message-based OOP

Class-based OOP

Origin

Smalltalk (1972)

Simula 67 (1967)

Unit

Small computers exchanging messages

Instance of a class

Core concept

Messaging, dynamic binding

Class, Inheritance, Composition

Coupling

Extreme late binding

Compile-time type resolution (generally)

Key Figures

Alan Kay

Kristen Nygaard, Bjarne Stroustrup, Bertrand Meyer, Grady Booch

Representative Languages

Smalltalk, Erlang, Self, Objective-C

C++, Java, C#, Eiffel

Intellectual Descendants

Actor Model, the messaging aspect of ECS

Enterprise OOP, GoF Design Patterns

Key Point: The two branches represent a divergence of paradigms, not a personal rivalry. Kay and Booch were solving different problems. Kay was envisioning future personal computing through the Dynabook concept and sought to design loosely coupled systems, while Booch was working to establish an analysis and design methodology for complex systems (such as Ada-based military software). Both used the same term ("OOP"), but they were building fundamentally different species of paradigm.

Core Concepts

All concepts in this section are described with reference to class-based OOP.

Classes and Objects

  • Class: a blueprint for creating objects. It defines data fields and methods.

  • Object: an instance of a class. A concrete unit realized in memory.

  • Message: the means of interaction between objects. In class-based OOP, messages are typically implemented as method calls, but Kay's original intent was a looser form of coupling.

Encapsulation

A mechanism that groups related data and methods into a single unit and hides the internal implementation from the outside world.

C#
public class BankAccount
{
    private decimal balance;

    public void Deposit(decimal amount)
    {
        if (amount <= 0) return;
        balance += amount;
    }

    public decimal GetBalance() => balance;
}

For more details, see the Encapsulation article.

Inheritance

A mechanism by which one class inherits the properties and methods of another class. While commonly used as a means of code reuse, Composition is now often recommended instead.

A warning against inheritance abuse: "Composition over Inheritance" is a principle emphasized in the GoF Design Patterns book.9 The diamond problem and violations of the Liskov Substitution Principle (LSP) are among the side effects of overusing inheritance.

Composition

An approach in which an object contains other objects as fields and delegates the required behavior to those objects to compose functionality. Where inheritance expresses an "is-a" relationship, Composition generally expresses a "has-a" or "part-of" relationship.

Composition enables reuse and extension without creating deep class hierarchies, and has the advantage of allowing composed objects to be swapped at runtime. That said, when delegation relationships between objects multiply, the flow of execution can become scattered and harder to follow.

C#
public interface IDiscountPolicy
{
    decimal Discount(decimal price);
}

public class Order
{
    private readonly IDiscountPolicy discountPolicy;

    public Order(IDiscountPolicy discountPolicy)
    {
        this.discountPolicy = discountPolicy;
    }

    public decimal FinalPrice(decimal price)
    {
        return price - discountPolicy.Discount(price);
    }
}

The key distinction: inheritance is reuse by receiving the parent class's implementation, while Composition is reuse by assembling and delegating to other objects. The GoF's "Composition over Inheritance" does not mean inheritance should be banned; it means one should not abuse inheritance solely for the purpose of reusing implementation.

Polymorphism

The ability to invoke different implementations through the same interface. It is classified as follows.

  • Subtype polymorphism: inheritance/interface-based

  • Ad-hoc polymorphism: method overloading

  • Parametric polymorphism: generics/templates

Abstraction

The act of extracting and expressing only the essential characteristics of a complex system. Abstract classes and interfaces are the primary tools for this.

Design Principles

SOLID Principles

The five OOP design principles formalized by Robert Martin.10

Acronym

Principle

Description

S

Single Responsibility Principle (SRP)

A class should have only one reason to change

O

Open-Closed Principle (OCP)

Open to extension, closed to modification

L

Liskov Substitution Principle (LSP)

Subtypes must be substitutable for their parent types

I

Interface Segregation Principle (ISP)

Clients should not depend on interfaces they do not use

D

Dependency Inversion Principle (DIP)

Depend on abstractions, not on concretions

Other Principles

  • GRASP (General Responsibility Assignment Software Patterns)

  • DRY Principle (Don't Repeat Yourself)

  • KISS Principle (Keep It Simple, Stupid)

  • YAGNI (You Aren't Gonna Need It)

  • Law of Demeter

  • Design by Contract — Bertrand Meyer

Design Patterns

Formalized solutions to recurring design problems in OOP. The GoF's Design Patterns (1994) is the starting point. It is worth noting that these patterns are a direct product of class-based OOP; in Kay's message-oriented OOP, many GoF patterns are either meaningless or take an entirely different form.

Category

Representative Patterns

Creational

Singleton, Factory Method, Abstract Factory, Builder, Prototype

Structural

Adapter, Decorator, Proxy, Facade, Bridge, Composite

Behavioral

Strategy, Observer, Command, State, Visitor, Chain of Responsibility

For a detailed classification scheme, see the Design Pattern Index.

Advantages and Disadvantages

Advantages

  • It is intuitive for modeling the real world.

  • It promotes code reuse.

  • When designed appropriately, it improves maintainability.

  • It is well-suited for large-team development.

  • A rich library of Design Patterns is available to leverage.

Disadvantages

  • Increased complexity due to over-abstraction

  • Object creation overhead (memory fragmentation, GC pressure)

  • Reduced data locality (cf. Data-Oriented Design)

  • Method call overhead (virtual function tables)

  • Shared mutable state problems in concurrent processing

Criticisms

The Trap of Pattern Schematization

As noted at the outset, the most fundamental criticism is that the moment a pattern is reduced to a diagram, it becomes the "empty illusion" Alexander warned against. The practice of looking only at GoF diagrams and forcing them onto code is known as the pattern-matching anti-pattern.

Criticism from the Functional Camp

Joe Armstrong (creator of Erlang) criticized OOP by saying, "The problem with object-oriented languages is they've got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle."

Personal note: In the end, you usually realize you needed the entire jungle after all. That's what makes programming so hard.

The functional programming camp views mutable state and side effects as fundamental flaws in OOP. Because referential transparency is not guaranteed, they argue, reasoning about code becomes difficult.

Criticism from the Data-Oriented Design Camp

In his CppCon 2014 talk, Mike Acton pointed out that OOP forces data layouts that cause cache misses.11 The AoS vs. SoA debate is a prime example. In game development and high-performance computing, alternatives such as Entity Component System (ECS) have risen to prominence.

Personal note: The problem is that Data-Oriented Programming creates layouts that cause cognitive misses. Having to dig through all the code every time you want to see the full state of an entity is not a particularly pleasant experience.

Alan Kay's Self-Criticism

Alan Kay, who originally coined the term OOP, has distanced himself from modern class-based OOP, stating that it differs from the message-passing-centric model he originally intended.3 The OOP Kay originally envisioned places so much emphasis on message passing and loose coupling that it is frequently compared to the Actor Model.

See Also

  • Design Pattern

  • GoF Design Patterns

  • Christopher Alexander

  • Pattern Language

  • Programming Idiom

  • Booch Object Model

  • Design by Contract

  • Wegner Classification

  • Functional Programming

  • Procedural Programming

  • Data-Oriented Design

  • Entity Component System

  • Actor Model

  • Prototype-Based Programming

  • Multi-Paradigm Languages

  • Domain-Driven Design


Categories: Programming Paradigms | Software Engineering | Computer Science | Pattern Index | Educational Resources

Footnotes

  1. Alexander, Christopher. "The Timeless Way of Building", 1979. The core argument of this work is that when design methodology is separated from substance, it becomes mere illusion.
  2. ACM A.M. Turing Award citation for Ole-Johan Dahl and Kristen Nygaard: Dahl, Nygaard. The ACM identifies the design of Simula I and Simula 67 as the occasion on which the core ideas of Object-Oriented Programming first emerged.
  3. Kay, Alan. "Dr. Alan Kay on the Meaning of Object-Oriented Programming", email to Stefan Ram, July 23, 2003. In this email, Kay explains that he coined the term object-oriented programming in 1967, and describes the essence of OOP as messaging, local retention and concealment of state and process, and extreme late binding.
  4. Stroustrup, Bjarne. "The C++ Programming Language", 1st edition, Addison-Wesley, 1985.
  5. Wegner, Peter. "Dimensions of Object-Based Language Design", OOPSLA '87 Conference Proceedings, ACM SIGPLAN Notices, Vol. 22, No. 12, 1987. DOI: 10.1145/38765.38823.
  6. Booch, Grady. "Object-Oriented Analysis and Design with Applications", Benjamin/Cummings, 1991. OOP definition is on p. 37; the object model's four major and three minor elements are presented in Chapter 2, "The Object Model".
  7. Booch's Chapter 2 summary of the object model: the four major elements are Abstraction, Encapsulation, Modularity, and Hierarchy. The three minor elements are Typing, Concurrency, and Persistence. For book information, see the Open Library entry on Booch.
  8. A common formulation of the popular three pillars model. It appears frequently in C++ educational materials but is not attributed to a single author. The taxonomic background is safely understood as deriving from Wegner's distinction among object-based, class-based, and object-oriented approaches, followed by later simplifications in educational materials.
  9. Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John. "Design Patterns: Elements of Reusable Object-Oriented Software", Addison-Wesley, 1994.
  10. Martin, Robert C. "Design Principles and Design Patterns", 2000. The acronym SOLID is widely attributed to Michael Feathers, who subsequently organized and popularized it.
  11. Acton, Mike. "Data-Oriented Design and C++", CppCon 2014.
Revision history — Object-Oriented Programming