Cloud Parts

Object-oriented programming

Bundle data with the code allowed to change it into objects, and let callers ask an object to do something without knowing how it does it.

3 technologies on this page ↓

How it works

An object holds some state (its fields) together with the operations allowed on that state (its methods). Four ideas usually come with it. Encapsulation: outside code can only go through the methods, so the object can keep its own rules true; a cart can refuse a quantity of zero, and nothing else can reach in and set one. Polymorphism: many classes implement the same interface, say PaymentMethod.charge(), and the caller just calls the method; the language picks the right code at run time, which is called dynamic dispatch. Inheritance: a subclass reuses a parent class’s code and overrides parts of it. That ties the child to the parent’s internals, so the usual advice since the Design Patterns book is to favour composition: build objects out of smaller objects behind small interfaces and hand them in. Most mainstream languages (Java, C#, C++, Python, TypeScript) build all this on classes, but not all do: Go has methods and interfaces with no type hierarchy at all. Alan Kay, who coined the term, meant something narrower and more radical: objects as little computers that only talk by sending messages.

Think of it as

A vending machine. You press buttons and get a drink; you can’t reach in and rearrange the coins, and any machine with the same buttons works the same way for you, whatever is inside.

Reach for it when

  • Long-lived things with rules to protect: an account, a cart, a document being edited
  • Many variants behind one interface: payment methods, storage backends, UI widgets
  • GUIs, games and simulations, where the program models things that each keep their own state

Think twice when

  • Data pipelines and calculations, where data flows through steps and plain functions are simpler
  • Deep inheritance trees built for code reuse; compose small objects instead
  • Wrapping every action in a class (OrderProcessorManagerFactory) when a function would do

A real example

A checkout accepts cards and bank transfers. Each is a class that implements PaymentMethod with one method, charge(cents). The Cart keeps its lines in a private field and exposes add(sku, qty), which refuses a quantity of 0 or less, so no other code can put a cart into a broken state. At checkout the cart is handed a PaymentMethod and calls charge; adding a wallet later means writing one new class, with no change to the cart.

Technologies

Specific products, and what each does differently.

What people mean by “object-oriented”#

The word covers several ideas that arrived at different times. Languages pick different subsets.

Encapsulation

Simula, 1967

State is private and changed only through methods, so the object can enforce its own rules. TypeScript’s private is checked only at compile time; its #field is private at run time too.

Polymorphism

late binding

Callers depend on an interface, not a class. Which method runs is decided at run time by the object that receives the call.

Inheritance

subclassing

A subclass reuses and overrides a parent’s code. Simula introduced it; Kay left it out of early Smalltalk until he understood it better. It couples child to parent, which is why it fell out of favour as the main reuse tool.

Composition

Design Patterns

Build behaviour by plugging small objects into bigger ones through interfaces. Erich Gamma calls this black-box reuse, and the Strategy pattern his prototypical example.

Messaging

Kay’s definition

Objects as cells or networked computers that only exchange messages, with state hidden and everything bound as late as possible. Closer to actors than to most class-based code.

In code · ts

interface PaymentMethod {
  charge(cents: number): Promise<string>; // returns a receipt id
}

class Card implements PaymentMethod {
  constructor(private token: string) {}
  async charge(cents: number) { return `card:${this.token}:${cents}`; }
}

class BankTransfer implements PaymentMethod {
  constructor(private iban: string) {}
  async charge(cents: number) { return `transfer:${this.iban}:${cents}`; }
}

class Cart {
  #lines = new Map<string, number>(); // hidden: only methods below can touch it

  add(sku: string, qty: number) {
    if (qty <= 0) throw new Error("qty must be positive"); // the cart guards its own rule
    this.#lines.set(sku, (this.#lines.get(sku) ?? 0) + qty);
  }

  // composition: the cart is handed a PaymentMethod instead of subclassing one
  async checkout(pay: PaymentMethod, priceOf: (sku: string) => number) {
    let total = 0;
    for (const [sku, qty] of this.#lines) total += priceOf(sku) * qty;
    return pay.charge(total); // which charge() runs is decided at run time
  }
}

const cart = new Cart();
cart.add("sku-17", 2);
cart.checkout(new Card("tok_9f3a"), () => 1250).then(console.log);         // card:tok_9f3a:2500
cart.checkout(new BankTransfer("DE89..."), () => 1250).then(console.log); // transfer:DE89...:2500

Often confused with

Where it came from1961–2014

Object-oriented programming started as a way to simulate the world. In 1961 Ole-Johan Dahl and Kristen Nygaard, at the Norwegian Computing Center in Oslo, began designing a language for describing simulations made of many dissimilar interacting parts. Simula I followed, and then Simula 67, a general-purpose language completed in 1967. Building on Algol 60’s blocks and Tony Hoare’s proposal for records, it introduced classes that bundle data with procedures, subclasses for reusing code, late binding, and objects created at run time. Dahl and Nygaard received the 2001 Turing Award “for ideas fundamental to the emergence of object oriented programming”.

Alan Kay, a graduate student at Utah after November 1966, saw Simula and Ivan Sutherland’s Sketchpad and imagined programs made of objects like biological cells or computers on a network, communicating only by messages. He says it was probably in 1967 that he first called it “object-oriented programming”. At Xerox PARC his group built Smalltalk (Smalltalk-72, then the release version, Smalltalk-80), a system built from objects that do everything by sending each other messages. Kay deliberately left inheritance out at first, and in 2003 he summed up: “OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.”

The mainstream took Simula’s version. Bjarne Stroustrup wanted to write efficient systems programs in the style Simula encouraged, and started “C with Classes” in 1979; it became C++, first released commercially in October 1985. Sun announced Java on 23 May 1995, a language where every function had to live in a class. By the 1990s objects were the default way to teach and structure software, and the criticism grew with them: Erich Gamma and his co-authors advised favouring composition over inheritance, Joe Armstrong of the Erlang team argued that data and functions should never have been bound together, and Steve Yegge’s 2006 “Execution in the Kingdom of Nouns” mocked Java for wrapping every verb in a noun. Java itself added lambdas in Java 8 (2014), and most languages today are a mix of objects and functions.

Why it’s built this way

Classes that bundle data with the procedures that act on it
Simula was built to describe systems of many interacting parts. Making each part a class instance with its own data and procedures let a program mirror the system it simulated.
Subclasses for reuse
Simula 67 added subclasses, so a general class could be specialised without copying its code. Later practice found the coupling between parent and child brittle, which is why Gamma recommends small interfaces and composition.
Messages and late binding instead of procedure calls
Kay wanted objects that behaved like independent computers on a network, so representation could be hidden and changed. Deciding at run time which code answers a message is what makes that possible.
Classes as the only unit of code (Java)
Java followed Simula’s mechanisms more closely than C++ and had no free functions. It made programs uniform, and it is exactly what critics like Yegge attacked, until Java 8 added lambdas.

Timeline

  1. 1961

    Dahl and Nygaard start work on a simulation language at the Norwegian Computing Center

  2. 1967

    Simula 67 introduces classes, subclasses and objects; Kay coins “object-oriented”

  3. 1972

    Smalltalk-72, the first real Smalltalk, runs at Xerox PARC

  4. 1979

    Stroustrup starts “C with Classes”, which becomes C++ (released 1985)

  5. 1995

    Sun announces Java

  6. 2001

    Dahl and Nygaard receive the Turing Award for Simula

  7. 2014

    Java 8 adds lambda expressions

Sources9

Improve this page on GitHub