Object-Orientation FAQ

1.1) What Is An Object?

There are many definitions of an object, such as found in [Booch 91, p77]:
"An object has state, behavior, and identity; the structure and behavior of
similar objects are defined in their common class; the terms instance and
object are interchangeable".  This is a "classical languages" definition, as
defined in [Coplien 92, p280], where "classes play a central role in the
object model", since they do not in prototyping/delegation languages.
"The term object was first formally applied in the Simula language, and
objects typically existed in Simula programs to simulate some aspect of
reality" [Booch 91, p77].  Other definitions referenced by Booch include
Smith and Tockey: "an object represents an individual, identifiable item,
unit, or entity, either real or abstract, with a well-defined role in the
problem domain." and [Cox 91]: "anything with a crisply defined boundary"
(in context, this is "outside the computer domain".  A more conventional
definition appears on pg 54).  Booch goes on to describe these definitions
in depth.  [Martin 92, p 241] defines: "An "object" is anything to which a
concept applies", and "A concept is an idea or notion we share that applies
to certain objects in our awareness".  [Rumbaugh 91] defines: "We define an
object as a concept, abstraction or thing with crisp boundaries and meaning for
the problem at hand." [Shlaer 88, p 14] defines: "An object is an abstraction
of a set of real-world things such that:
  * all of the real-world things in the set - the instances - have the same
    characteristics
  * all instances are subject to and conform to the same rules"
and on identifying objects: "What are the *things* in this problem?  Most of
the things are likely to fall into the following five categories: Tangible
things, Roles, Incidents, Interactions, and Specifications."  [Booch 91, 4.3]
covers "Identifying Key Abstractions" for objects and classes based on an
understanding of the problem domain and [Jacobson 92] provides a novel approach
to identifying objects through use-cases (scenarios), leading to a use-case
driven design.  Jacobson also calls for managing complexity with specialized
object categories [Jacobson 94]:
  Ordinary Objects     - Typical OOPL objects
  Use-Cases and Actors - Actors <--> Use-Cases <--> Object Model Objects
  Megaobjects          - Composite objects (~ subsystems with inheritance)
    Frameworks*(Typical) - Abstract MO meant for reuse and extension
    Patterns** (Typical) - Framework-like, crsp. classes and comm patterns only
  Application Objects  - In the Object Model
    Interface            - E.g. GUI
    Control              - Introduced in design for control purposes
    Entity               - Correspond to real-world objects
  Component Objects    - Utility and Implementation hiding objects
    Utility              - Set, Array, ...
    Impl. Hiding         - Distr. Arch., specific DBMS, OS
  Unrelated to Ivar Jacobson but relevant to the topic:
  * There was a Software Frameworks Assoc. and magazine until last year, but
    a review of their last conference is available by email thanks to Adam
    Wildavsky, send requests to adamw@panix.com.
  **There is a patterns mailing list, email: patterns-request@cs.uiuc.edu.
    See also st.cs.uiuc.edu for some info on patterns.
The implementation of objects could roughly be categorized into descriptor-
based, capability-based, and simple static-based approaches.  Descriptor-
based approaches (e.g. Smalltalk handles) allow powerful dynamic typing, as
do the capability-based approaches which are typically found in object-
oriented databases and operating systems (object id's).  A "proxy" based
approach with an added layer of indirection to Smalltalk's handles is found
in Distributed Smalltalk which allows transparent, distributed, and migrating
objects [Kim 89, ch 19 and Yaoqing 93].  Simple static approaches are found in
languages such as C++, although the new RTTI facility will supply simple
dynamic typing (checked downcasting) similar to those introduced by Eiffel
in 1989 through the notion of assignment attempt, also known as type narrowing.
Descriptor-based approaches can have pointer semantics and can be statically
typeless (or just "typeless", as in Smalltalk) where references (variables)
have no type, but the objects (values) they point to always do.  An untyped
pointer (such as void* in C++) and an embedded dynamic typing scheme are used
in more conventional languages to fully emulate this style of dynamically typed
programming (see sections 2.3, 4.3, and [Coplien 92]).
Below is a simple example to show a most trivial case of OO implementation.
It is primarily intended to introduce new terms.  See [Cardelli 85] for
another semantic definition of OO using functions for methods and for
a view of types as sets of values.
Simple statically-typed objects (static and auto vars and temps in C++ and
expanded types in Eiffel) can be viewed as instances of a record type,
whose record fields are called instance variables (Smalltalk) or member data
(C++).  The record (class) may also contain operations which are called
methods (Smalltalk) or member functions (C++) which are equivalent to a
function taking an object of the record type, called the receiver, as the
first parameter.  The receiver is called self (Smalltalk) or this (C++).
Members will denote both instance variables and methods.  Inheritance is
roughly equivalent to a loosely coupled variant record, with derived classes
as variant parts and with multiple-inheritance concatenating several records
to serve as a base.
A virtual member in statically typed languages is a base class member that can
be set or respecified by a derived class.  This is roughly equivalent to a
pointer or function pointer in the base class being set by the derived class.
[Stroustrup 90] covers the implementation details of virtual member functions
in C++, which also involve an offset for the receiver to handle multiple-
inheritance.  This is an example of dynamic binding, which replaces a
switch statement on variant parts with a single call, reducing code size
and program complexity (fewer nested programming constructs) and allowing
variants to be added without modifying client code (which causes higher defect
injection rates during maintanance and debugging).
Virtual members in dynamically typed languages are more flexible because
static typechecking requirements are dropped.  See section 2.5.
The terms method/member function, instance variable/member data, subclass/
derived class, parent class/base class, and etc. will be used interchangeably.
As pointed out in [Stroustrup 90, p197], the base/derived class terminology
may be preferable to the sub/super-class terminology, and is preferred in
this document also.
Delegation/prototyping languages [Kim 89, ch3; Ungar 87, Sciore 89] have a more
flexible kind of object which can play the role of classes in classical OO
languages.  Since there is no separate class construct in these languages, and
only objects, they are referred to as single-hierarchy, or 1 Level systems.
Objects contain fields, methods and delegates (pseudo parents), whereas
classical object-oriented languages associate method, field and parent
definitions with classes (and only associate state and class with objects,
although vtables of function pointers for dynamic binding is an exception).
However, one-level objects often play the role of classes to take advantage of
sharing and often instances will simply delegate to parents to access methods
or shared state, otherwise idiosyncratic objects, a powerful and natural
concept, will result.  Typical 1 Level objects can contain any number of
fields, methods and parents and any object can be used as a template/exemplar,
thus performing the classical role of a class.  In typical prototyping systems,
parents (as any other member) can be added or changed dynamically, providing
dynamic multiple inheritance (or more typically simple delegation).  Here, the
term "Prototype" usually refers to prototype theory, a recent theory of
classification where any object can be inherited from or cloned to serve as a
prototype for newly created instances.  [The Author also uses the term for
languages providing high quality support for rapid prototyping, although this
usage is atypical]  See [Booch 94, pp 154-155] for a brief discussion of
prototype theory in the context of OOA and OOD.
It is common in such systems for an object to "become" another kind of object
by changing its parent.  A good example is a window becoming an icon, as
window and icon objects display different behavior (although cognitive
differences are significant too:-)  Delegation refers to delegating the
search for an attribute to a delegate, and is therefore more of a pure
message passing mechanism (as with dynamic scoping) than inheritance, which
also typically specifies non-shared state when used for representation.
Chambers has proposed an interesting variation called "Predicate Classes"
[Chambers 93] as a part of his Cecil language.  These classes will only be
parents when certain predicates are true.  This can support a types/classes
as collections of objects view, which is the same as the types as sets of
values view taken by [Cardelli 85].  [Martin 92] provides some examples of
this view applied during OOA.
1 level systems therefore provide the most flexible and powerful capabilities.
Self is a good example of a delegation-based single hierarchy language [Ungar
87].

This document was translated by ms2html v1.8 on 01.06.95.