// Target: computer-science.bigb
In Scala, a singleton object associated with a same-named companion class in the required source context. Object members and instance members are distinct:
B.g(x) invokes a member of object B, while b.g(x) invokes an instance member through b. Both can use method overloading, but the instance's members are not automatically part of the companion's overload set.[ref]The operations and behavioral contract exposed by a software object to its clients. Different classes can implement a common interface while hiding different state representations. Correct substitution requires agreement with the contract, not only matching object method names.
An object combines an identity, state and operations exposed through an object interface. Distinct software objects can hold equal data while remaining different by object identity. Reference aliasing occurs when multiple references designate the same object, so a state update through one reference can affect observations through another.
Equality according to the abstract content a software class exposes, rather than object identity. Distinct software objects can be equal by value. A Java
equals(Object) override should define an equivalence relation and agree with its hash code. Equal content can have different internal subdivisions: occupied colour runs, for example, can be equal despite different brick boundaries.A named software object instantiated once in the scope of its definition. A top-level Scala
object can implement the singleton pattern. Nested object definitions can have different instances for different enclosing instances, so the relevant scope matters.An operation invoked on a software object that can read or modify that receiver's state. Its contract specifies accepted inputs and effects. Dynamic dispatch can select an overriding implementation according to the receiver's concrete software class; method overloading instead selects among different signatures using static type information.
Command-query separation distinguishes commands that change state from queries that return observations without changing that state. It permits repeated inspection without further updates, but clients may need a protocol connecting updates and subsequent observations. Combining a command and its resulting observation into one object method can be convenient for transformation object interfaces. Neither organization alone guarantees thread safety.
An immutable object does not change its observable state after construction. Immutable fields prevent reassignment of their stored values, but fields containing references to mutable software objects do not automatically make the reachable software object graph immutable. Read-only generic producers can often support covariant type parameters; publicly writable fields generally cannot.
Object composition builds behavior by storing component software objects and delegating operations to them. A containing software object can expose a distinct object interface and control which operations affect additional state. Exclusive ownership or a specified reference-aliasing discipline may be needed to protect its representation invariant. Unlike subclass overrides, object methods of a separate component do not dynamically dispatch into the containing wrapper.
Class inheritance defines a software class using another software class's implementation and may add or override behavior. When it also establishes subtyping, the derived software class must satisfy the base software class's behavioral contract for clients to substitute it safely. Code reuse alone is not sufficient justification for an inheritance relationship. Object composition often better represents a software object containing a replaceable component.
A software class declared to inherit from another software class. In nominal object-oriented programming, subclass relationships commonly induce subtype relationships. Valid behavioral substitution also requires satisfying the parent's observable contract, beyond merely declaring the inheritance.
A subclass may depend on its superclass's internal calls to overridable object methods. A base implementation change that preserves the base abstraction can then change subclass behavior. For example, a set subclass may count insertion attempts by overriding insertion. If a revised deletion operation rebuilds the set by dynamically dispatched clear and insert calls, it unexpectedly resets and increases that counter. Object composition can isolate the counting wrapper from the component's internal dispatch, provided only wrapper operations can mutate the owned component.
A wrapper component in the Decorator pattern. It implements the same interface as its inner component, delegates existing work, and contributes one additional responsibility. For per-channel message distribution, a wrapper can forward prior sends, add one channel send and add the corresponding cost, keeping behavior and accounting in the same component.
Represent an optional responsibility by an object implementing the same interface as its wrapped component. The wrapper delegates existing work and adds its own behavior. Independent responsibilities can then be assembled as a chain instead of defining a concrete class for every subset of options. Structural induction on the chain proves accumulated behavior, provided each wrapper preserves the base interface contract.
A design in which an originator creates an opaque snapshot of its state, a caretaker retains it, and the originator can later restore it. Encapsulation prevents the caretaker from depending on internal state representation. A memento must freeze the relevant state: references to mutable objects can require a deep copy, while immutable values can safely be shared. Scala's access controls and path-dependent types can restrict snapshot construction and associate it with its originating instance.
A reusable organization of responsibilities and interactions for a recurring software-design problem. The Memento pattern separates snapshot creation/restoration from history management, while the Decorator pattern composes independent responsibilities behind one interface. A pattern specifies an arrangement rather than one mandatory class naming scheme.
A software design pattern concerned with allocating behavior and communication responsibilities among objects. Observer patterns notify dependents, while a command pattern represents a request as an object.
Separate operations from a relatively stable hierarchy of element classes. An element's accept operation calls the visitor overload appropriate to its own concrete type, combining virtual dispatch with static overload selection to obtain double dispatch. New operations can be added as visitors; adding an element type generally requires extending the visitor interface and existing visitors.
Delegate state-dependent behavior to a separate state object. Transitions replace that object, changing how subsequent requests are handled without spreading state tests through every operation.
Interchange algorithms through a common interface, allowing a client or context to select the policy without embedding every alternative in one implementation. Different strategies solve the same kind of task; the selected algorithm can be varied independently of its caller.
A software design pattern organizing composition of classes and objects into larger structures. The decorator pattern wraps a component behind the same object interface, delegating existing work and adding one responsibility. Wrappers can be nested without declaring a new class for each combination.
A software design pattern organizing how software objects are created. A prototype pattern creates an object by asking an existing example to copy itself, letting a client choose a concrete configuration at runtime through an object interface.
Provide an interface for creating a family of related products while hiding their concrete software classes. Unlike a single factory method pattern operation returning one product abstraction, an abstract factory typically exposes several related product-creation operations whose implementations coordinate a consistent family.
Declare a creation operation returning an abstract product interface and let concrete creators specialize how products are built. Clients call the creator interface rather than hard-coding construction of each concrete product. For example two regional manufacturers can implement
build(carType): Car to select a concrete car and apply regional settings; optional wrappers can then be composed independently using the decorator pattern.Provide a shared unique instance of a service or state holder. A Scala
object supplies one instance of that object definition; a top-level object can therefore centralize shared state such as a registry of current scores. A singleton does not by itself implement thread safety, remove stale entries, or define the lifetime of registered objects. Those remain separate design responsibilities.Expose a cloning operation through a common object interface and create new objects by asking a configured prototype for a copy. Concrete prototypes implement the copy operation; the client need not name their concrete software classes. This is useful when creation depends on runtime configuration or expensive reusable initial state. The contract must specify whether nested mutable data requires a deep copy; copying only outer fields can preserve unintended reference aliasing.
Represent a request and the information needed to execute it as a software object with a common command interface. Undoable commands additionally retain enough information to invert their change: an insertion retains its position and value, a deletion retains the removed value, and a positional move retains the source and final destination indices.
For sequential undo/redo, a history manager stores applied commands on one stack and undone commands on another. Undo transfers the most recent applied command to the redo stack; redo transfers its head back after reapplying it. A fresh edit clears the redo branch. Command inverses are valid under this chronological protocol, not generally after unrelated intervening edits. Saving complete immutable versions instead gives a Memento pattern implementation of the same undo/redo interface.
An undoable command records enough information to restore its input state when applied immediately after its corresponding edit. In a sequence, insertion at index is reversed by deletion at ; deletion is reversed by reinsertion of the saved value. If a move places an entry at final index after removing it from index , the inverse moves it from back to . Removing the moved entry recovers the original sequence with exactly that entry missing, which proves the inverse for both directions and for .
These local inverse identities extend to a history by applying inverses in reverse chronological order. A stack of completed commands and a stack of undone commands maintain that order. A fresh command invalidates the old redo branch. Arbitrary inverses after unrelated intervening edits need not satisfy the restoration identity. State snapshots in the Memento pattern supply a different way to realize the same chronological undo/redo contract.
Register consumers through an observation interface so that a producer can notify interested consumers without depending on all of their concrete classes. Registration can change independently of the producer's core state changes. Notifications should expose coherent states, and unregistration or update discipline is still needed to avoid stale subscriptions or notification cycles.
Expose sequential consumption through availability and next-element operations while hiding storage and traversal details. The abstraction supports common clients for arrays, linked structures or generated sequences. A separate iterator can own separate cursor state; an alias of the same iterator does not create an independent traversal.
An adapter presents an object interface expected by clients while delegating to a component with a different object interface. Correct adaptation preserves the meaning and order of operations, not merely object method names. Adapting a combined update-and-result operation to separate update and query operations requires storing the last result and specifying its initial value. An adapter should not perform a hidden dummy update just to manufacture that initial observation.
Reusable behavior composed into a host class in object-oriented programming, often through a trait. Scala allows one superclass and several mixed-in traits. Required abstract members let a mixin depend on host capabilities without fixing one concrete superclass; member conflicts and
super calls are resolved using the language's linearization rules.A Scala trait can intercept a method, call the next implementation through
super, and add behavior before or after it. abstract override marks such an implementation as requiring an appropriate concrete method later in the class linearization. A character-counting plugin can update its cached counts only after a successful underlying document edit, preserving its additional representation invariant without changing the edit's abstract result.A counting trait that increments the original argument to insertion assumes that subsequent traits store that argument unchanged. A later capitalization trait breaks the assumption: the counter can record lowercase
a while the document stores uppercase A. To maintain counts of actual document contents across such a composition, inspect the stored character after delegation or constrain the legal mixin order. Correctness for one base implementation does not establish correctness under every trait combination.To analyze an ordinary overloaded instance call, first enumerate members visible through the receiver's static type and choose the applicable signature using argument static types. Only then use the receiver's runtime type to select the effective override of that signature. This two-stage rule explains why changing a reference's declared type can change the selected overload even when every reference points to the same object. A
super call selects the inherited implementation according to the language's superclass or linearization rules instead of recursively redispatching to the overriding body.Selection of an instance method implementation using the receiver's runtime type. It operates on the method signature already determined by the language's call typing and overload rules. It does not imply dispatch on every argument's runtime type; in particular, method overloading in Scala normally uses static argument types.
Select behavior using the runtime types of two participating software objects, typically through two virtual method calls. A method on the first participant calls a virtual method on the second, passing
this with the concrete static type established in that second method's class. Method overloading there selects a signature, after which dynamic dispatch selects the implementation on the other runtime receiver. This differs from expecting ordinary overload resolution to inspect a method argument's runtime class.A subclass or composed trait supplies an implementation of an inherited method signature. Ordinary instance calls use dynamic dispatch to choose the effective implementation for the receiver, after any overload selection. In Scala, overriding a concrete inherited member requires the
override modifier; a qualified super invocation selects the corresponding inherited implementation.Several callable methods share one name but differ in parameter signatures. In ordinary Scala calls, the compiler chooses among applicable alternatives using the receiver and arguments' static types, preferring a uniquely most-specific applicable alternative. Overloading is therefore a different step from method overriding and receiver-based dynamic dispatch.
In Scala, a class paired with a same-named companion object in the appropriate source context. They can access each other's private members. This permits a companion object to hide implementation-node definitions while the corresponding class creates and manipulates those nodes.[ref]
Scala 2.13 classes and objects specification. Private modifier and companion access
A reusable type and collection of members that can be composed into a class in object-oriented programming. In Scala, a trait can declare required members and provide concrete implementations. Several traits can contribute mixin behavior to one class, subject to linearization and member-conflict rules.
Scala orders a class and its inherited traits to resolve member lookup and
super calls. For two independent traits sharing a base, the rightmost mixed-in trait comes first, followed by the earlier trait and then the common base. Ordinary virtual calls start at the receiver's most specific override; an unqualified super call starts after the implementation's owner in that receiver's linearization. It does not necessarily call the textual parent of the trait in isolation.[ref]In object-oriented programming, encapsulation packages an object's state with the operations that act on it and can restrict direct access to its implementation. It is the object-oriented use of encapsulation.
Protected access permits designated subclass code to use a member while excluding ordinary clients. The precise receiver and scope restrictions depend on the language; it should not be confused with public access to every instance's representation. Access control helps protect representation invariants but does not ensure that authorized subclass code maintains them.
// Target: computer-science.bigb
An operation used when creating and initializing a software class instance. Construction should establish the representation invariant before ordinary clients can access the software object. Class inheritance and initialization order require care if construction invokes overridable object methods before subclass fields are initialized.
An abstract class cannot be instantiated directly and may combine concrete state or behavior with abstract operations that subclasses implement. Concrete object methods can depend on a representation convention that every subclass must maintain. An abstract declaration still has a result type: omitted result types in Scala 2 procedure syntax mean Unit, not an unspecified Boolean query.
Articles by others on the same topic
There are currently no matching articles.