
1.
Basic Concepts
The
term object model, as used throughout this document,
refers to the collection of concepts used to describe objects in
a particular object-oriented language, specification, or
analysis and design methodology, and corresponds closely to the
use of the term data model in "the relational data
model". Thus, we speak of "the Smalltalk object
model" or "the OMG object model". This is
in contrast to the use of object model to describe the
collection of objects created to model a particular system or
application, as in "the Automatic Teller Machine object
model" or "the object model of a windowing
system". From our point of view,
defines a particular object model (our sense), which includes
concepts like object, inheritance, attribute, and so on,
and uses it to define the object models (second sense) of
various applications. This dual usage is unfortunate, but
is common in the literature.
2.
Objects
2.1.
Operations
Various
object models embody various concepts of "object".
All models consider an "object" to be an identifiable
thing which plays a role with respect to a "request"
for an "operation". The request invokes the
operation which defines some service to be performed. From
a user's viewpoint, an object may be a "recipient" of
the request, a parameter in the request, or something returned
as a result of the request.
There
are two broad categories of object models, which we refer to as
"generalized" and "classical object models".
Classical models are, in many ways, subsets of generalized
object models but they are founded on different metaphors.
"generalized
object models" do not distinguish a recipient from other
request parameters. In generalized models, a request is
defined as an event which identifies an operation and optional
parameters. For example, an Add To Inventory (part1,
lot2, bin3) request does not give special significance to
either the part, the lot, or the bin. These objects
participate uniformly in the request.
"Classical"
or "messaging object models" do distinguish a
recipient. In classical models, a request is defined as an
event which identifies and operation, a recipient, and optional
parameters. Either the part, the lot, or the bin could be
designed to be the recipient of the Add To Inventory
request. The request to a specific recipient is called a message.
A common syntax places the recipient first: part1. Add To
Inventory (lot2, bin3).
The
"protocol"5, or "interface", of
an object describes the operations in which the object can
participate. In classical models, the interface of an
object includes the operations for which it can be a recipient.
In generalized models, the interface includes operations for
which the object can play the role of any parameter. The
protocol completely specifies the behavior of an object but does
not provide visibility to the implementation of the object's
operations. Only operations specified in the protocol are
allowed.
Objects
may be static ("passive") recipients of requests or
dynamic ("active") agents capable of such activities
as sending requests.
5-
here, the term "protocol" is used as a synonym for
"interface". This usage is different from the
usage in communications.
2.2.
Requests
2.3.
Messages
2.4.
Specification of Behavioral Semantics
Object
models differ in how and to what extent the behavior of objects
is specified. Most object models limit the declarative
specification of object behavior (operations) to the
specification of a signature for each operation.
The signature consists of the name of the operation, and the
argument and result types. The semantics of the operations
are often defined operationally (by means of the code of the
methods provided to implement the operations). Other
object models allow declarative specification of behavioral
semantics, in the form of invariants that should be preserved by
all operations, pre-and post-conditions for operations, other
forms of constraints on the operations' behavior, or by a
declarative specification of the methods themselves. These
models specify behavioral semantics in a precise and
implementation-independent manner. Some of the models use
formal notations based on mathematics (like Z, Object Z, LOTOS,
etc.) for doing so. These formal specifications may be
translated into stylized English, in order to enhance their
understanding by customers who are not mathematically-trained.
2.5.
Methods
A
"method" provides the implementation of an operation
for certain objects. Different objects may have different
methods for the same operation.
In
the classical object model, a method is considered to implement
the interfaces of operation recipients, but not the interfaces
of other parameters. In generalized models, a method is
considered to implement the interfaces of all parameters.
2.6.
State
Some
operations alter the behavior of future requests. For
example, if the ContainsPart operation returns TRUE or FALSE
depending on whether a certain bin contains a certain part, then
the result of ContainsPart (bin1, part2) may be changed by the
request StorInBin (bin1, part2).
The
general concept of "state" concerns the information
that must be remembered when a request alters the future
behavior of other requests. Some models equate state with
structural "attributes", i.e., state consists of the
current values of attributes. In other models state may be
defined as the results returned by certain operations, or state
may not be precisely defined.
2.7.
Object Lifetime
The
"life" of an object is the period during which it
exists. An object's life begins as the result of a
"create" operation. An object's life ends as the
result of a "destroy" operation. An object whose
life begins and ends within a single process is called a
"transient". An object which lives longer than
the execution of the process that created it is called a
"persistent". Some primitive objects such as
literals, have eternal lives, are neither created nor destroyed,
and represent themselves.
An
object is "reachable" if and only if there is an
operation that returns the object as a result. The
"transitive closure" of an object is al objects
contained directly or indirectly within the object, or more
generally all objects reachable from the object directly or
indirectly by repeated application of some filtering predicate.
The term "navigation" is often used when moving from
object to object, possibly through a sequence of move
operations.
An
object is perceived to exist if and only if it is reachable.
If no operation exists that will return the object as a result,
then the object is "unreachable" (though it may or may
not be physically destroyed and system-internal operations may
or may not still keep track of the object.) Destruction of
an object makes it unreachable. Operations which render an
object unreachable have the effect of destroying the object.
Rules
for creating and destroying objects are system dependent.
In some object models systems, the application explicitly
invokes creation and destruction operations; in others, some
sort of implicit scheme based on "referential
integrity" insures that objects that other objects depend
on cannot be explicitly destroyed as long as the other objects
continue to exist.
At
the implementation level, destruction of deletion of objects may
involve reclaiming the storage space occupied by such objects.
Some systems allow a destroyed object's object identifier to be
reclaimed for later reuse; others do not. Schemes like
"garbage collection" or "reference count"
may be used to manage and reclaim space associated with
destroyed objects.
2.8
Behavior / state grouping
As
noted in the OODBTG Reference Model
there are two broad categories of object models, which we refer
to as "generalized" an "classical object
models." Classical models are, in many ways, subsets
of generalized object models but they are founded on different
metaphors. "Generalized object models" do not
distinguish a recipient from other request parameters. In
generalized models, a request is defined as an event which
identifies an operation and optional parameters. For
example, an Add To Inventory (part1, lot2, bin3) request
does not give special significance to either the part, the lot,
or the bin. These objects participate uniformly in the
request. An object in a classical model can be thought of
as a "hunk of state", with a collection of methods
grouped around it. An object in a generalized model can
also be thought of as a "hunk of state" with a
collection of methods, but a given method may be related to
multiple hunks of state. For example, the Add To
Inventory method handling the request above would be related
to the part, lot, and bin objects.
By
using a generalized object model, the complexity of a real-world
situation does not have to be always carved up into discrete
self-contained objects. In other words, relationships or
complex operations do not have to be artificially packaged as
part of one particular object. The generalized object
model considers a complex operation as jointly owned by all its
parameters and considers a relationship as shared by its
participating collection of objects. Therefore there is no
need to artificially choose a distinguished owner of an
operation or of a relationship.
2.9
Communication model
2.10
Events
2.11
Transition rules
3.
Binding
"Binding
chooses a method or methods to be executed in response to a
request, based on the operation and objects in the request.
Note:
CLOS allows method combination and may bind to multiple methods.
In
classical models, the binding choice is based on the class of
the recipient. In generalized models, the binding choice
may depend on the classes of several parameters.
Different
object languages support different criteria and times for
binding an operation to a method for execution. Examples
are "early binding" at compile-time and "late
binding" at run-time.
4.
Polymorphism
"Polymorphism"
means that the binding of a request involves a choice among
alternative implementations of the operation. Polymorphism
allows "overloading" of operations, which means that
an operation may be implemented in several alternative methods,
associated with different classes of parameters.
5.
Encapsulation
A
key concept of the object paradigm is "encapsulation",
which is defined as a kind of abstraction that enforces a clean
separation between the external interface of an object and its
internal implementation.
Users
of objects are people or programs which send requests to
objects. Users of objects observe the behavior of objects
in terms of the operations which may be applied to objects, and
in terms of the result objects returned by such operations.
An operation may be implemented (i.e., supported or realized) by
a variety of different program code and data structures.
Encapsulation means that these implementations are not visible
to the user of the object, hiding details of whether and what
data structures or code are used in an implementation. The
importance of encapsulation is that it insulates applications
from object implementations allowing them to be modified without
requiring applications that use them to be modified.
Some
classical object models define a stronger form of encapsulation,
in which the states of objects are isolated from each other; the
implementation of objects is disjoint between objects; all
methods and states belong exclusively to individual objects.
An
assumption that attributes or other structural constructs are
necessarily implemented as stored data would violate
encapsulation. An attribute such as the age of a person,
the weight of an assembled object, the circumference of a
circle, or the font of a word within a document might be stored
in some implementations and computed in others. Violations
of encapsulation, if allowed at all, should be made explicit
(e.g. PUBLIC data in C++).
6.
Identity, Equality, Copy
Each
object has a unique, immutable "identity" which
provides a means to denote or refer to the object independent of
its state or behavior. The definition of identity includes
the concepts of identity compare operation, logical identifiers,
object identifiers, and object creation.
The
identity concept can be described in terms of a primitive
"identity compare operation" "==" such that,
if X and Y are the same object, X == Y. Some consequences
of identity compare are:
o
h(X) and h(Y) have the same result for any operation h(), where
h() has no "side effects" (i.e., h() is not a
state-changing method), and
o
the mathematical set {X, Y} has cardinality 1.
An
abstract representation of object identity is by means of a
"logical identifier" ("LID"), which is an
implementation-free token that is uniquely associated with a
specific object. The term "object identifier"
("OID") refers to a specific implementation of a
logical identifier. OIDs are normally system-generated,
with a fixed format, and are not changeable by the user.
In models which consider literals or extensional sets to be
objects, such objects have LIDs but possibly not OIDs.
An
LID is meaningful within some limited scope which we shall call
an "object space". Object creation occurs within
an object space. Each creation event results in a LID that
identifies the created object uniquely within that space.
The creation event creates a representation of the object in the
space.
An
LID is unique within a particular object space. If X and Y
are objects within an object space, X == Y if X and Y have the
same LID. In many implementations, simple comparison of
OID and literal representations is used as the basis for
"==". An LID from one object space is not a
valid LID in another object space. Identity comparison
between LIDs only makes sense when they are defined in the same
object space. Object identifiers are handled differently
in different systems when objects are exported, imported,
replicated, versioned, or distributed.
7.
Types and Classes
The
object paradigm deals with both abstract, external behavior, and
implementation. Objects may be grouped into types by
commonality of behavior (interface), and into classes by
commonality of implementations7.
A
"type" defines a protocol shared by a group of
objects, called "instances" of the type. The
type itself may be an object.
A
"class" defines an implementation (methods and data
structures) shared by a group of objects. A class may be
considered an implementation of a type. There may be
several classes (implementations) per type. The class
itself may be an object; methods may also be objects.
The
"signature" of an operation identifies the number and
types of the operation's arguments and results. In
classical object models, an operation is associated with the
type of its recipient, and a method is associated with the class
of its recipient. In generalized models, an operation is
associated with the types of its parameters, and a method is
associated with the classes of its parameters. Thus, in
generalized models, operations and methods may be "jointly
owned" by multiple types and classes. In general,
objects can have multiple types and classes, and these can
change. Not all models permit this.
A
"parameterized type" is the result of a compile-time
operation that takes classes as parameters and returns one or
more derived classes, e.g., set<employee> might return
"class set-employee," the definition of a set class
corresponding to a set of employee class instances.
7:
Within this section, the terms "type" and
"class" are used prescriptively. While it is
important to define precisely the terms "type" and
"class", almost everywhere in this document except
this section, the terms are used interchangeably. The term
"class" is used uniformly in the rest of the document
because it is used in X3J13 Common Lisp (CLOS), X3j136 C++, and
Smalltalk. Some programming languages like C++ define
"type" to be a restricted form of class without
encapsulation inheritance, and behavior and "class" to
include these object concepts.
8.
Inheritance and Delegation
"Inheritance"
and "delegation" both involve deriving new definitions
from existing ones.
In
"class-class inheritance", classes are arranged as
nodes in a graph, with unidirectional links between nodes
defining inheritance paths. "Subclasses"
("derived classes") are "specializations" of
their more general parent classes. "Superclasses"
("Base classes") represent "generalization"
of their child classes.
Conflicting
definitions of protocol, behavior, and state may be inherited
along paths of the inheritance graph and are resolved in
system-dependent ways. Different "conflict
resolution" and "method combination" strategies
are used in different systems to define the semantics of
inheritance. when creating a subclass, attributes and
operations may be added to those inherited from the superclasses,
or they may selectively "override" (replace), or
"block" (hide) those from the superclass.
The
two most common forms of class-class inheritance are
"single inheritance", where the graph is a tree, and
"multiple inheritance", where the graph is a directed
acyclic graph.
In
"class-instance inheritance", instances of a class
inherit a common interface and an initial state (default of
initial values of certain attributes) from the class.
In
"delegation", which can be characterized as
"instance-instance inheritance", an object assigns or
transfers behavioral definitions or implementations or state to
another object. Some delegation-based systems do not
differentiate between class and instances.
Object-to-object delegation generalizes both class-class
inheritance and class-instance inheritance.
9.
Noteworthy Objects
Different
object models may distinguish or provide special support for the
noteworthy objects identified in the following subsections.
The list is not exhaustive nor are the objects with the
characteristics identified here necessarily mutually exclusive.
Some may not be treated as objects in all object models.
9.1
Relationships
A
"relationship" ("association") is a logical
relation between instances of one or more classes of objects.
Relationships can be binary or n-ary. Binary relationships
may be one-to-one, one-many, or many-many.
In
generalized object models, a relationship may be realized as a
separate class, as an operation along with its result, as a
separate modeling construct, or not at all. In different
object systems, relationships can be established, traversed, or
removed, and may be system or user defined. In different
systems, the implementation of relationships may be
unidirectional or bi-directional.
9.2
Attributes
In
some object models, object interfaces only contain explicitly
defined operations. In other models, interfaces include
operations which are implicitly defined in terms of logical
"attributes" ("properties", "instance
variables", "data members") or other structural
constructs (independent of implementation). Typically,
defining an attribute A implicitly defines the inclusion of
operations such as Get A and/or Set A in the interface of an
object.
Attribute
values are defined by a class which constrains possible values.
Attribute values may be single- or multi-valued.
Attributes are sometimes used to represent binary relationships.
9.3
Literals
"Literals"
are objects such as numbers and character strings. Literal
values are similar to created objects in that both may occur as
operands of operations. Literal values are different from
created objects in the they have immutable state and they do not
have a create operation because their representations are
explicitly recognized. For example, multiple occurrences
of the same literal number are all references to the same point
on the number line. Operations which return literal values
are constructing references to objects, not creating objects.
In most object systems, if X and Y are literals, X == Y only if
X and Y represent the same literal.
9.4
Containment
There
are various sorts of "containment constructs" in
object models. They can be characterized by how
containment is established and what it signifies. Models
which support an attribute concept sometimes consider all the
values of an object's attributes to be contained in the object.
Some models assume that objects have a natural intrinsic
content, in the sense that a document consists of some text, or
a file consists of a byte string. In other models, literal
values are considered to be contained in the object, while
non-literals are not. In some models, attribute values may
be either objects or pointers to objects; objects which are
pointed to are not considered part of the object. There
may be an explicit "contains" relationship among
objects, so that an object contains those objects which are so
related to it. Containment may be treated as a property of
a relationship, allowing various relationships to be designated
as implying containment. \footnote {The notion of containment
captures the implementation notion of "reference".}
Abstractly,
the semantics of containment can be described in terms of
"propagation" of operations, resembling a form of
inheritance. A request to print or move a document is
expected to print or move the text of the document, along with
any diagrams or other sub-objects contained in it. Thus,
for certain operations "f", if "x"
"contains" "y" then "f(x)" is
expected to cause "f(y)". Details vary.
There may be different decompositions of a given object into
constituents: a book may be composed of chapters and paragraphs,
and also of pages and lines. Different operations may
propagate in different ways along different containment paths.
Destroying an object might or might not destroy a contained
object. The authors and font of a book may or may not be
the authors and font of its chapters.
Object
systems often support value-based "equality comparison
operations" which allow objects to be "equal"
even if they are not identical. Equality is defined
differently in different systems, may be system- or
user-defined, and may be class-dependent. Equality
comparison operations may be depend on the primitive identity
comparison operation"==", on value comparison
operations, on containment comparison operations, or in terms of
equivalent behavior.
9.5
Aggregates
"Aggregate
objects" such as sets, bags, lists, tuples, arrays, etc., \footnote{These
are logical constructs distinct from implementation-specific
data structures.} are containment constructs that group other
objects organized in some manner. Aggregates typically
support operations to access individual members, and to iterate
over all members, as in queries. Aggregates may be
"homogeneous", containing only objects from the same
class or from classes inheriting from the class, or they may be
"heterogeneous", containing objects from any class.
With
respect to identity, there are two kinds of aggregate objects.
"Intensional" aggregates have an identity based upon
their creation event. "Extensional" aggregates
have an identity based upon their membership. If X and Y
are the LIDs of extensional sets, then X == Y is equivalent to X
and Y having the same members. For an intensional set, the
membership at any time corresponds to an extensional set.
Two intensional sets remain distinct objects if they have the
same members. If the membership of an intensional set
changes, the identity of the set does not change.
9.6
Other
In
various object models, the following may not be treated as
objects