Skip to content

Object-Oriented Programming

A programming paradigm that organizes computation as interactions among identity-bearing objects that combine state with behavior and respond through method or message dispatch.

Version
v2 · 2026-09-06 · History
Domain-specific #
2408
Origin domain
computer programming
Subdomain
programming paradigms
Aliases
OOP, Object-oriented paradigm

Core Idea

Object-oriented programming organizes a program as a population of objects: computational entities with identity, state, and behavior that collaborate through message sending or method invocation. An object can preserve information across interactions, select behavior according to the message received and its dynamic kind, and hide representation choices behind a behavioral interface. The paradigm is therefore more specific than merely storing records beside procedures.

The stable identity survives differences among languages. Smalltalk emphasizes objects communicating by messages; class-based languages commonly describe method calls and dynamic dispatch; prototype-based languages delegate behavior through objects rather than treating classes as indispensable. Alan Kay's history of Smalltalk makes messaging, state retention, and extreme late binding central to the original lineage.[1] Snyder's analysis shows why encapsulation and inheritance are separable design dimensions rather than synonyms.[2]

Structural Signature

  • Object identity: two objects may have equal visible state yet remain distinguishable participants.
  • Local state: an object retains fields, slots, or another representation across interactions.
  • Behavioral interface: operations are requested without requiring clients to manipulate representation directly.
  • Receiver-directed interaction: a message or method call designates a receiver.
  • Dispatch: the receiver's dynamic class, prototype chain, method table, or equivalent structure selects behavior.
  • Encapsulation boundary: representation and implementation decisions can be localized behind supported operations.
  • Object construction or derivation: objects arise from classes, prototypes, factories, literals, or other object-producing mechanisms.
  • Collaboration: larger behavior emerges from networks of interacting objects.
  • Substitutability mechanism: polymorphism allows different receivers to answer a common protocol.

Recognition test. Ask whether the program's persistent participants are identity-bearing receivers whose state and behavior are governed through dispatch. If data are merely passed to ordinary functions with no receiver identity or behavioral boundary, the system may be modular or abstract-data-oriented without being object-oriented.

What It Is Not

OOP is not identical to classes. Classes are a common organization and construction mechanism, but prototype-based programming obtains sharing, delegation, and specialization from existing objects. Requiring classes would incorrectly exclude a recognized object-oriented branch.

It is not identical to inheritance. A language can support objects, encapsulation, interfaces, composition, and dynamic dispatch while discouraging or severely restricting implementation inheritance. Conversely, a record-extension mechanism does not establish the full object interaction model. Snyder documents that inheritance can conflict with encapsulation when subclasses depend on representation details.[2]

It is not every use of objects in an application domain. A database row, geometric object, or abstract syntax tree node may be modeled without object-oriented execution. It is not functional programming's negation: multiparadigm languages combine first-class functions, immutable values, and object dispatch. It is also not a guarantee of modularity, reuse, or maintainability; those are contingent design outcomes.

Scope of Application

The paradigm structures graphical interfaces, simulations, business applications, operating-system services, games, distributed systems, and language runtimes. It is especially useful when a domain can be represented as long-lived participants with changing local state and negotiated behavior.

Different lineages emphasize different roles. Simula supplied class, object, inheritance, and virtual-operation machinery for simulation. Smalltalk treated nearly all computation as messaging among objects. C++ combined classes and virtual dispatch with procedural and systems-programming facilities. Prototype languages use delegation rather than class instantiation as the main sharing route. These are variants of the paradigm, not evidence that any one language feature is sufficient.

Static and dynamic type systems both support OOP. Cardelli and Wegner distinguish subtyping, polymorphism, and data abstraction, clarifying that type compatibility and runtime object identity are related but independent structures.[3] An untyped message-passing language may be strongly object-oriented; a statically typed language may contain object-oriented and non-object-oriented subsystems.

Clarity

Consider a request \(m(a_1,\ldots,a_n)\) sent to receiver \(o\). Dispatch can be represented abstractly as

\[ \operatorname{body}=\operatorname{lookup}(\operatorname{dynamicKind}(o),m), \]

followed by execution with \(o\) bound as the current receiver. The object's state may change from \(\sigma_o\) to \(\sigma'_o\), while clients need only the operation's contract. This receiver-sensitive lookup distinguishes polymorphic dispatch from selecting an ordinary overloaded function solely from static argument types.

Encapsulation is a permission and dependency boundary, not physical secrecy. Reflection, serialization, debuggers, or language visibility rules may expose representation. The structural question is whether clients are expected to rely on supported behavior rather than directly coordinate every internal state transition.

Manages Complexity

OOP localizes change by assigning responsibilities to objects and exposing limited protocols. A caller that depends on a protocol can ignore whether the receiver stores a table, computes a value lazily, or delegates to another object. Dynamic dispatch replaces some explicit type tests with extensible behavior selection.

The same mechanisms can amplify complexity. Mutable aliasing makes state changes nonlocal; deep inheritance couples subclasses to ancestors; identity makes copying and equality subtle; distributed objects add partial failure and latency. Object decomposition can also scatter one workflow across many tiny methods. The paradigm manages complexity only when object boundaries align with real responsibilities and interactions.

Abstract Reasoning

An object may be modeled as a labeled transition system

\[ (\sigma,m,\vec a)\longmapsto(\sigma',r,e), \]

where \(\sigma\) is private state, \(m\) a requested operation, \(\vec a\) arguments, \(r\) a result, and \(e\) externally visible effects. Clients reason from admissible message traces and contracts rather than the full representation.

Subtyping asks when an object supporting protocol \(P'\) can be used where \(P\) is expected. The answer depends on behavioral compatibility, not merely matching field layouts. Inheritance may help implement that compatibility, but it neither guarantees nor defines it. Cardelli and Wegner's type-theoretic treatment is therefore a boundary source rather than evidence that OOP collapses into type theory.[3]

Knowledge Transfer

The structural roles transfer across class-based, prototype-based, actor-like, component, and distributed-object settings. The concrete meanings of identity, state, and dispatch change: identity may be a memory reference, stable handle, actor address, or persistent key; state may be mutable fields or an encapsulated evolving process; dispatch may be a virtual table, dictionary lookup, multimethod, or delegation chain.

Transfer has limits. Actors enforce stronger isolation and asynchronous messaging than ordinary objects. Abstract data types can hide representation without runtime receiver identity. Closures can preserve state and behavior without organizing the system as interacting objects. The OOP label is useful when the complete role package, not a superficial implementation resemblance, survives.

Examples

  1. Class-based account: each account has identity and balance state; deposit and withdrawal requests dispatch to methods while representation remains hidden.
  2. Polymorphic renderer: a collection holds shapes; a render request selects behavior from each receiver's dynamic kind without a central type switch.
  3. Prototype delegation: an object missing a method delegates lookup to a prototype, retaining object identity without class instantiation.
  4. Graphical widget system: buttons, windows, and layouts retain state and collaborate through events and dispatched operations.
  5. Not sufficient: a C record and unrelated functions that receive its address do not become OOP merely because programmers call the record an object.
  6. Hybrid: a functional core may compute immutable transformations while an object-oriented shell manages identity, resources, and external interaction.

Structural Tensions

  • Encapsulation vs. inheritance: subclass reuse can expose superclass representation. Diagnostic: change a private representation and measure subclass breakage.
  • Identity vs. value semantics: persistent identity supports evolving entities but complicates equality and copying. Diagnostic: state whether equality follows identity, structural value, or domain keys.
  • Dynamic dispatch vs. traceability: extensibility removes central conditionals but obscures the invoked implementation. Diagnostic: inspect runtime receiver kinds and method-resolution paths.
  • Mutable state vs. local reasoning: objects localize ownership yet aliases can create hidden interference. Diagnostic: map all references capable of mutating the same object.
  • Fine-grained responsibility vs. scattered behavior: small objects improve separation but can fragment workflows. Diagnostic: trace one use case across receiver transitions.
  • Class taxonomy vs. composition: inheritance expresses substitutable kinds but composition often reduces coupling. Diagnostic: test whether the proposed subclass truly satisfies the parent's behavioral contract.

Structural–Framed Character

The abstraction is structural because the same identity-state-behavior-dispatch organization recurs across unrelated programming languages and application types. It is framed because “object,” “message,” “method,” and “dispatch” have technical meanings within programming-language and software-design practice.

Wegner treats object-based and object-oriented language families through characteristic support for objects, classes, and inheritance, while later practice includes classless prototype systems.[4] The dossier therefore locks a narrower invariant than “all customary OOP features”: receiver identity, behavior-bearing objects, and interaction through dispatch, with class and inheritance explicitly variant.

Structural Core vs. Domain Accent

The core is distributed responsibility among identity-bearing participants that encapsulate evolving state and select behavior in response to requests. The programming accent supplies executable state, method bodies, dispatch rules, object creation, aliasing, and language-level visibility.

Removing the programming roles produces broader ideas such as agency, modularity, or encapsulation. Removing receiver identity and dispatch produces abstract data types or modules. Because the full package does not recur literally outside software and programming-language design, Object-Oriented Programming remains domain-specific rather than prime.

Abstract Data Type is the proposed minimal parent through a typical composition/presupposition relation. OOP characteristically uses the ADT idea that clients invoke supported behavior without depending on representation, then adds runtime identity, receiver-directed dispatch, collaboration among objects, and usually evolving local state. The qualifier is typical rather than strict because reflective or weakly encapsulated object systems may expose representation. The edge is not specialization: a programming paradigm is not a subtype of one data type.

Prototype-Based Programming is a strict object-oriented branch whose derivation and lookup are organized around prototype delegation. Object Graph describes the reference topology created by object relations, not the execution paradigm. Design Patterns are reusable design descriptions that often operate inside OOP but do not define it.

Relationships to Other Abstractions

Local relationship map for Object-Oriented ProgrammingParents appear above the current abstraction, mutual partners to the right, and children below. Node labels state whether each abstraction is prime or domain-specific; colors identify relation types.Object-OrientedProgrammingDOMAINPrime abstraction: Abstract Data Type — presupposes, typicalAbstractData TypePRIME

Current abstraction Object-Oriented Programming Domain-specific

Parents (1) — more general patterns this builds on

  • Object-Oriented Programming presupposes, typical Abstract Data Type Prime

    Abstract Data Type is the proposed minimal parent through a typical composition/presupposition relation.

Hierarchy paths (3) — routes to 2 parentless roots

Neighborhood in Abstraction Space

Object-Oriented Programming sits in a sparse region of the domain-specific corpus (83rd percentile for distinctiveness): few abstractions share its structure, so a faithful description tends to retrieve it precisely.

Family — Unclustered & Miscellaneous (1565 abstractions)

Nearest neighbors

Computed from structural-signature embeddings · 2026-09-08

Not to Be Confused With

  • Object-based programming: may support objects and encapsulation without inheritance or the stronger conventions attached to OOP; usage varies.
  • Prototype-Based Programming: a branch of OOP, not its synonym.
  • Abstract Data Type: hides representation behind operations but need not provide runtime identity or dispatch.
  • Actor model: identity-bearing actors communicate asynchronously and isolate state under stronger concurrency rules.
  • Component-based software: composes deployable or replaceable units at a different granularity.
  • Object Graph: represents reference relationships among objects.
  • Design Patterns: names recurring design structures rather than the paradigm itself.

References

[1] Alan C. Kay, “The Early History of Smalltalk,” ACM SIGPLAN Notices 28, no. 3 (1993): 69–95, https://doi.org/10.1145/155360.155364. registry

[2] Alan Snyder, “Encapsulation and Inheritance in Object-Oriented Programming Languages,” in OOPSLA '86 Conference Proceedings (1986): 38–45, https://doi.org/10.1145/28697.28702. registry ↩a ↩b

[3] Luca Cardelli and Peter Wegner, “On Understanding Types, Data Abstraction, and Polymorphism,” ACM Computing Surveys 17, no. 4 (1985): 471–523, https://doi.org/10.1145/6041.6042. registry ↩a ↩b

[4] Peter Wegner, “Dimensions of Object-Based Language Design,” in OOPSLA '87 Conference Proceedings (1987): 168–182, https://doi.org/10.1145/38765.38823. registry