Skip to content
Historical revision
Object-Oriented Programming โ€” 2026-06-30 14:19 UTC
rev_87fa1d71ffa54dccb5c48081dc717479

Object-Oriented Programming

Object-Oriented Programming

Before We Begin

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 taken on the status of a kind of gospel, many developers open the pattern book, look only at the structural diagrams, and write their code from there. The result is often a rigid implementation with no flexibility.

In learning design methodologies and patterns, we constantly waver in the gap between 'schematic understanding' and 'practical experience'. As Christopher Alexander noted, to decompose a design method away from the substance of design is ultimately to speak of nothing but an empty abstraction.1

There are actually many threads to explore before getting to patterns, including idioms, but that discussion is reserved for the Programming Idioms article. This piece focuses on the identity 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. Its core idea is encapsulating, into a single unit, the data and functions that procedural programming kept separate. The paradigm originated in the Simula language in the 1960s and has since become one of the most widely used paradigms in the software industry.

An important caveat: the OOP we commonly use today cannot be reduced to the message-based object orientation that Alan Kay originally envisioned. It is the result of a mixture: the class and inheritance model of Simula 67, the 1970s research into CLU, Alphard, abstract data types, and access control, Smalltalk's message passing, and the industry-standard class-based OOP that emerged through Bjarne Stroustrup, Peter Wegner, Bertrand Meyer, Grady Booch, and others. The conceptual origins span the 1960s through the 1970s, while standardization within the industry proceeded strongly in the late 1980s through the early 1990s. The OOP encountered in textbooks, interviews, and design pattern books is a later, simplified form of this long evolution.

For other meanings, see the following:

  • Alan Kay's original conception of object orientation: message-based object orientation

  • Prototype-based object orientation: prototype-based programming

Table of Contents

  1. Before We Begin

  2. Overview

  3. History

  4. Booch's Object Model: 4 Major + 3 Minor

  5. The Origins 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. Criticism

  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; retrospectively clarified in 2003) : Views messaging, local retention and hiding of state and process, and extreme late binding as the core principles.

  • Grady Booch (1991): Proposes the Booch Object Model, composed of 4 major elements (Abstraction, Encapsulation, Modularity, Hierarchy) plus 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 among object-based, class-based, and object-oriented.

  • Later mainstream industry definition: A simplification of the above traditions into three pillars of Encapsulation, Inheritance, and Polymorphism (with no single clearly identifiable author as its source).

The gap among 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 from which the patterns we discuss today emerged

1962โ€“1967: The Emergence of Simula and Classes

Simula I was a precursor language designed for discrete-event simulation, while the language recognized today as the direct ancestor of object-oriented languages is Simula 67. Developed by Norwegian researchers Kristen Nygaard and Ole-Johan Dahl, Simula 67 combined classes, objects, inheritance, late binding, and dynamic object creation, and it became the origin of all subsequent class-based OOP.2

1966/1967: Alan Kay's Vision and Verbal Coinage

Alan Kay is widely credited as the person who verbally coined the term "object-oriented programming." 3However, this does not mean he was the first to use it in print. Kay's retrospective accounts of using this phrase in the late 1960s are significant, but the documented history of "object-oriented" appearing in publications is more complex. Kay later realized his vision through Smalltalk at Xerox PARC.

2003: Kay's Retrospective Redefinition

In a 2003 email to Stefan Ram, Kay explicitly stated that what he had meant by object-oriented programming consisted of the following three things.3

  1. Messaging

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

  3. Extreme late-binding of all things

To put it plainly, the object Kay had in mind was something like a small computer. Each object exists independently, and the structure is one where objects collaborate by passing messages to one another. Rather than designing class hierarchies, the central question was "what messages flow between objects."

But framed this way, this is not quite the OOP concept most of us picture. So where did the concept we commonly talk about actually come from?

1976: Jones, Liskov, and "object-oriented languages"

In 1976, MIT Computation Structures Group Memo 137 by Anita K. Jones and Barbara Liskov, titled "An Access Control Facility for Programming Languages," grouped Simula 67, CLU, and Alphard together under the label "object-oriented languages."4 In this context, object-oriented referred less to Smalltalk-style messaging philosophy and more to abstract data types, hiding of object representations, typed operations, and access control.

Why does this matter? Because the history of OOP cannot be told through the Alan Kay/Smalltalk lineage alone. The class-and-object tradition that began with Simula developed along a separate theoretical trajectory, passing through CLU, Alphard, abstract data type research, and access control studies. The class-based OOP we see today in Java, C#, and C++ is best understood as the industrial synthesis of that tradition with the Smalltalk tradition.

Personal note: Rochus Keller helped me trace this historical thread. His site is linked below.

rochus-keller.ch
Rochus Keller's Website | About me and what I do

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

The OOP we use today was not defined by any single person; it took shape gradually through the collaborative contributions of many individuals from the late 1980s through the early 1990s.

1985: Stroustrup and C++

Bjarne Stroustrup released C++, which transplanted Simula's class model into the C language.5 C++ was the first decisive language to bring class-based OOP into mainstream industry, and it effectively became the reference point for every major OOP language that followed.

1987: Wegner's Classification

In his OOPSLA 1987 paper "Dimensions of Object-Based Language Design," Peter Wegner proposed the following graduated distinction.6

  • 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 popular three pillars of OOP.

1988: Meyer and OOSC

Bertrand Meyer published Object-Oriented Software Construction (OOSC, 1988). Drawing on his own Eiffel language, he established the formal foundations of OOP, including Design by Contract, invariants, and class invariants. Meyer's OOSC and Booch's OOAD 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).7 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."

This definition can be summarized in three propositions:

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

  2. Each object is an instance of some class.

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

That said, Booch's real contribution 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 Gang of Four and the Age of Patterns

Against the backdrop of class-based OOP taking hold through the 1980s and 1990s, one towering programming classic appeared in 1994: the GoF Design Patterns. Its four authors, Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, gave rise to the nickname 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 of memorizing diagrams and forcing them into code took hold. For details, see the document on the schematization trap of patterns.

After 1995: Java and Enterprise Entrenchment

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

After the 2000s: Reassessment

The rise of functional programming and the emergence of data-oriented design brought OOP's limitations into serious discussion. It was also during this period that Alan Kay himself began distancing class-based OOP from his original intent.

Booch's Object Model: 4 major + 3 minor

Chapter 2, "The Object Model," in Booch's 1991 book explicitly identifies the elements of the object model as follows.78

Category

Element

Description

Major (required)

Abstraction

Extracting essential characteristics

Major (required)

Encapsulation

Hiding the internals of an abstraction

Major (required)

Modularity

Decomposing into units of high cohesion and low coupling

Major (Required)

Hierarchy

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

Minor (Optional)

Typing

Type safety grounded in abstract data types

Minor (Optional)

Concurrency

The distinction between active and passive objects

Minor (Optional)

Persistence

Preserving object state across time and space

There are a few notable points here.

  • Booch did not specify "Polymorphism" as a standalone element of the object model. Polymorphism is only implied within Hierarchy.

  • Booch does not treat "Inheritance" as an independent element; instead, he 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.

  • Booch's model is richer than the popular three-pillars framework in that software engineering concepts such as Modularity, Concurrency, and Persistence are explicitly incorporated into the object model.

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

The origins of the three elements of OOP (Encapsulation, Inheritance, Polymorphism)

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

Formation process

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

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

  3. 1970s CLU, Alphard, and the abstract data type lineage: Anita K. Jones and Barbara Liskov referred to Simula 67, CLU, and Alphard as "object-oriented languages" in 1976.4 In this context, the central concerns were abstract data types, representation hiding, type operations, and access control, rather than class hierarchies.

  4. Peter Wegner (1987): Proposed a graduated distinction among "object-based," "class-based," and "object-oriented" languages, and clearly identified inheritance as the defining characteristic that sets object-oriented programming apart from other paradigms.6

  5. The C++ camp (1985 through the 1990s): Industrial training materials began to circulate the formulation that "a true OOP language is one that possesses all three of encapsulation, inheritance, and polymorphism." Statements like the following became common.

    Using encapsulation alone (that is, defining and using classes without employing inheritance or polymorphism) is commonly called object-based programming. To practice true OOP, all three pillars (encapsulation, inheritance, and polymorphism) must be used.9

  6. The Java (1995~) textbook era: This formulation became entrenched in standard educational materials.

A note on attribution

  • The "three elements" are not Booch's invention. Booch's book presents a model of four major elements plus 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 an industry-consensus vernacular formulation that cannot be traced back to any single book.

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

Personal note: In fact, the more common view of OOP history tends to attribute it primarily to Alan Kay's work alone, so the misconception that it was Booch's story may have been entirely my own perspective.

Message-Based OOP and Class-Based OOP

OOP has effectively branched into two distinct streams.

Distinction

Message-Based OOP

Class-Based OOP

Origin

Smalltalk (1972)

Simula 67 (1967)

Unit

Small computers exchanging messages

Instances of a class

Core Idea

Messaging, Dynamic Binding

Classes, 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, Self, Objective-C

C++, Java, C#, Eiffel

Intellectual Descendants

Actor Model, the messaging aspect of ECS, Erlang/Akka-style message-based concurrency models

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 envisioned loose-coupling systems for the future of personal computing embodied in the Dynabook, while Booch sought to establish analysis and design methodologies for complex systems (such as Ada-based military software). Both used the same term, "OOP," yet 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 unit materialized in memory.

  • Message: the means of interaction between objects. In class-based OOP, this is typically implemented as a method call, though 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. It is used as a means of code reuse, though in modern practice Composition is often recommended instead.

A warning against overusing inheritance: "Composition over Inheritance" is a principle emphasized in the GoF Design Patterns book.10 Side effects of inheritance overuse include the diamond problem and violations of the Liskov Substitution Principle (LSP).

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 makes reuse and extension possible without deepening class hierarchies, and offers the advantage of allowing composed objects to be swapped out at runtime. That said, as delegation relationships among objects multiply, the execution flow 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);
    }
}

Key point: Inheritance is reuse by inheriting a parent class's implementation, while Composition is reuse by assembling and delegating to other objects. The GoF's "favor Composition over inheritance" does not mean inheritance should be prohibited; it means inheritance should not be abused solely for the sake of reusing implementations.

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 representing 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 formulated by Robert Martin.11

Abbreviation

Principle

Description

S

Single Responsibility Principle (SRP)

A class should have only one reason to change

O

Open/Closed Principle (OCP)

Open for extension, closed for modification

L

Liskov Substitution Principle (LSP)

Subtypes must be substitutable for their parent types

I

Interface Segregation Principle (ISP)

Clients should not be forced to 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) serves as the starting point. It is worth noting that these patterns are a direct product of class-based OOP.

Categories

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 taxonomy, see the Design Patterns Index.

Note that in Kay/Smalltalk-style message-oriented OOP, some GoF patterns are absorbed into language features or dynamic message dispatch, allowing them to be expressed more concisely or in forms that differ from class-based C++/Java implementations.

Advantages and Disadvantages

Advantages

  • Intuitive for modeling the real world.

  • Promotes code reuse.

  • Improves maintainability when designed appropriately.

  • Well-suited for large-team development.

  • Enables use of a rich library of design patterns.

Disadvantages

  • Increased complexity from over-abstraction

  • Object creation overhead (memory fragmentation, GC pressure)

  • Reduced data locality (cf. data-oriented design)

  • Method call overhead (virtual function table)

  • Shared mutable state problems in concurrent programming

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" that Alexander warned against. The practice of looking only at GoF diagrams and forcing them into code is called the pattern-matching anti-pattern.

Criticism from the functional programming 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 whole jungle after all. That's what makes programming so hard.

The functional programming camp views mutable state and side effects as fundamental flaws of OOP. Their argument is that reasoning becomes difficult because referential transparency is not guaranteed.

Criticism from the data-oriented design camp

Mike Acton argued in his CppCon 2014 talk that OOP forces data layouts that cause cache misses.12 The AoS vs. SoA debate is the canonical example. In game development and high-performance computing, alternatives such as Entity Component System have risen to prominence.

Personal note: The problem is that data-oriented design (DOP) produces 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 Retrospective Critique

Alan Kay, who is widely credited with coining the term OOP, later distanced his original vision from modern class-based OOP, arguing that it differs from the message-passing-centric model he originally intended.3 The OOP Kay originally envisioned places such emphasis on message passing and loose coupling that it is frequently compared to the Actor model.

See also

  • Design Patterns

  • Design Patterns (Gang of Four)

  • 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 Language

  • 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 central argument of this work is that when design methodology is separated from tangible reality, it becomes 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 catalyst for the emergence of Object-Oriented Programming's core concepts. โ†ฉ
  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 characterizes OOP's essence as messaging, local retention and concealment of state and processing, and extreme late binding. โ†ฉ
  4. Anita K. Jones; Barbara H. Liskov. "An Access Control Facility for Programming Languages", MIT Computation Structures Group Memo 137, 1976. The Memo listing in the MIT CSG Archive shows Memo 136 "An Introduction to CLU" and Memo 137 appearing consecutively. In the listing, Memo 137 is dated April 1976, though the document cover shows May 1976. Memo 137 groups Simula 67, CLU, and Alphard together as "object-oriented languages". โ†ฉ
  5. Stroustrup, Bjarne. "The C++ Programming Language", 1st edition, Addison-Wesley, 1985. โ†ฉ
  6. 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. โ†ฉ
  7. Booch, Grady. "Object-Oriented Analysis and Design with Applications", Benjamin/Cummings, 1991. The OOP definition appears on p. 37; the four major and three minor elements of the object model are presented in Chapter 2, "The Object Model". โ†ฉ
  8. 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 for Booch. โ†ฉ
  9. A representative formulation of the popular three pillars doctrine, which appears frequently in C++ educational materials but is not attributed to a single author. It is reasonable to understand its origins as deriving from Wegner's distinction between object-based, class-based, and object-oriented combined with subsequent simplification in educational materials. โ†ฉ
  10. Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John. "Design Patterns: Elements of Reusable Object-Oriented Software", Addison-Wesley, 1994. โ†ฉ
  11. Martin, Robert C. "Design Principles and Design Patterns", 2000. The acronym SOLID is credited to Michael Feathers, who later codified and popularized it. โ†ฉ
  12. Acton, Mike. "Data-Oriented Design and C++", CppCon 2014. โ†ฉ
Revision history โ€” Object-Oriented Programming