Search the FAQ Archives

3 - A - B - C - D - E - F - G - H - I - J - K - L - M
N - O - P - Q - R - S - T - U - V - W - X - Y - Z
faqs.org - Internet FAQ Archives

Comp.Object FAQ Version 1.0.9 (04-02) Part 1/13

( Part1 - Part2 - Part3 - Part4 - Part5 - Part6 - Part7 - Part8 - Part9 - Part10 - Part11 - Part12 - Part13 )
[ Usenet FAQs | Web FAQs | Documents | RFC Index | Cities ]
Archive-name: object-faq/part1
Last-Modified: 04/02/96
Version: 1.0.9

See reader questions & answers on this topic! - Help others by sharing your knowledge
COMP.OBJECT FAQ
Version: 1.0.9
Date:    4/2/96


Author:
  Bob Hathaway
  Geodesic Systems, Inc.
  Cyberdyne Systems Corporation
  rjh@geodesic.com
  http://www.geodesic.com/people/Bob
  75027.1663@compuserve.com

Copyright 1992-1995  Bob Hathaway
All rights reserved.

Permission is granted to freely copy and distribute this document but only
with this full header attached and at no cost to others with the exception
of a nominal distribution fee, if any.  No sale, resale or reprinting is
granted without the explicit written permission of the author.


Anonymous FTP Sites and Hypertext Server:
  anonymous@ftp://zaphod.uchicago.edu/pub/(.Z)     (128.135.72.61)
  anonymous@rtfm.mit.edu:/pub/usenet/comp.object/*_Part_* (18.181.0.24 Tmp)
  http://iamwww.unibe.ch/~scg/OOinfo/FAQ/index.html       (new IAM location)

Mail Server:  (See also section 1.24)
  mail mail-server@rtfm.mit.edu
  Subject:
  send usenet/comp.object/*

Zaphod is preferred over rtfm for anonymous ftp retrieval, as it provides a
single file.  Rtfm contains the FAQ as posted.

To use the hypertext system, see APPENDIX E, entries 27.

Comp.Object Archive:
  A new and workable comp.object archive is now available on the www, with
  much thanks to Markus A. Beckmann, beckmann@informatik.mathematik.uni-mainz.de.
http://aaimzb.mathematik.uni-mainz.de/Personal/Mitarbeiter/comp.object.idx.html

Object Currents:
  A related and free new on-line Object resource edited by yours truly:
http://www.sigs.com/objectcurrents - Please take a look!

Contributors:  Per Abrahamsen, Margaret Burnett, Edwardo Casais, Stewart
  Clamen, Dennis De Champeaux, Mike DeVaney, Eric Dujardin, Piercarlo Grandi,
  Tim Harvey, Brian Henderson-Sellers, Urs Hoelzle, Paul Johnson, Bill
  Kinnersley, Oscar Nierstrasz, James Odell, David Wheeler, Eoin Woods, and
  many others whose contributions have helped this document to fulfull its
  objective of bringing object-oriented concepts and systems to everyone.
  
  Special thanks to Object Systems, Geodesic Systems and Cyberdyne Systems for
  providing the support and resources needed to make this effort possible.
  Object Systems was primarily a "think tank" and producer of object-oriented
  technologies, Geodesic Systems brings the latest in object-oriented theory
  and technique to practical and widespread use, as does Cyberdyne.

  And to kick off the new Appendix G, Commercial OO Libraries and Systems, I'm
  introducing our own new product (partly developed by me:-), the Great Circle
  (TM) automatic memory management system for C and C++.  I've used it on
  several of my own projects where it automatically fixed all memory leaks
  instantly.
  
  New formatted and submitted entries for Appendix G are most welcome.

Objective:
  In the spirit of other FAQs, to provide a simple document to answer the most
  frequently asked and recurring questions and to allow new users to understand
  frequently discussed topics and terms used in comp.object.   This should
  bring new comp.object readers and/or writers to at least an introductory
  level of comprehension as soon as possible.  Other goals (hopes) are to
  provide a quick and current reference on available systems such as object-
  oriented languages, CASE, OODB and etc. and to provide good references to
  current and relevant OO systems, groups, texts and literature.

Disclaimer:
  This document does not necessarily reflect the opinions of the author's or
  any contributor's companies.  There are no explicit or implicit guarantees
  implied by this document.

While object systems are a constantly changing and moving target with a broad
diversity of often conflicting methodologies, constructs, terminologies,
approaches, languages, implementations and etc. and comp.object has a wide
diversity of readers and writers ranging from students, professors and
researchers in academia to beginners, professionals, top-notch experts and
leaders in industry with a broad range of experience and backgrounds ranging
across many paradigms, this FAQ can certainly not aspire to satisfy all of them
completely but instead attempts to provide the most well-rounded treatment of
object-oriented concepts and realizations primarily from the mainstream and
popular authors and systems and further to provide a collection of available
systems and tools in the appendices.

Several improvements are planned for future FAQs, including a glossary.


SECTION 1:  BASICS
  1.1)  What Is An Object?
  1.2)  What Is Object Encapsulation (Or Protection)?
  1.3)  What Is A Class?
  1.4)  What Is A Meta-Class?
  1.5)  What Is The Infinite Regress Of Objects And Classes?
  1.6)  What are MOPs and Reflection?
  1.7)  What Is Inheritance?
  1.8)  What Is Multiple Inheritance?
  1.9)  Does Multiple Inheritance Pose Any Additional Difficulties?
  1.10) What Is Dynamic Inheritance?
  1.11) What Is Shared (Repeated) Inheritance?
  1.12) Why Use Inheritance?
  1.13) Why Don't Some People Like Inheritance?
  1.14) What Is Specialization/Generalization/Overriding?
  1.15) What Is The Difference Between Object-Based And Object-Oriented?
  1.16) Is A Class An Object?
  1.17) Is An Object A Class?
  1.18) What Is A Method? (And Receiver And Message)
  1.19) What Are Multi-Methods And Multiple-Polymorphism?
  1.20) What Is OOP?
  1.21) What Is OOA/OOD (And Where Can I Get What I Need On It)?
  1.22) Where Did Object-Orientation Come From?
  1.23) What Are The Benefits Of Object-Orientation?
  1.24) What Other FAQs Are available?

SECTION 2:  TYPING
  2.1)  What Is Polymorphism?
  2.2)  What Does Polymorphism Boil Down To In OO Programming Languages?
  2.3)  What Is Dynamic Binding?
  2.4)  Is There A Difference Between Being A Member Or Instance Of A Class?
  2.5)  What Is This I Read About ML And Functional Programming Languages?
  2.6)  What Is the Difference Between Static And Dynamic Typing?
  2.7)  What Is A Separation Between Type And Class (Representation)?
  2.8)  What Are Generics And Templates?

SECTION 3:  GENERAL
  3.1)  What Is The "Classical" Object-Oriented Paradigm?
  3.2)  What Is The "Delegation/Prototyping" Object-Oriented Paradigm?
  3.3)  Are There Any Other Object-Oriented Paradigms?
  3.4)  What Are The Major Object-Oriented Programming Languages Today?
  3.5)  What Are Object-Oriented Databases And Persistence?
  3.6)  What Are Object-Oriented Operating Systems?
  3.7)  What Are The Current Object-Oriented Methodologies?
  3.8)  What Is The OMG/OMA/ORB/CORBA?
  3.9)  Why Is Garbage Collection A Good Thing?
  3.9b) Why is Garbage Collection Necessary For Object-Oriented Programming?
  3.10) What Can I Do To Teach OO To The Kids?
  3.11) What Is Available On Object-Oriented Testing?
  3.12) What Distributed Systems Are Available?
  3.13) What Is The MVC Framework?
  3.14) What Is Real-Time?
  3.15) What Is Available on OO Metrics?
  3.16) What Are Visual Object-Oriented Programming Systems?
  3.17) What Tutorials Are Available On Object-Oriented Concepts and Languages?

SECTION 4:  COMMONLY ASKED LANGUAGE SPECIFIC QUESTIONS
  4.1)  What Is Downcasting?
  4.2)  What Are Virtual Functions?
  4.3)  Can I Use Multiple-Polymorphism Or Multi-Methods In C++?
  4.4)  Can I Use Dynamic Inheritance In C++?

ANNOTATED BIBLIOGRAPHY

APPENDIXES
  APPENDIX A  VIPS
  APPENDIX B  OBJECT-ORIENTED DATABASES AND VENDORS
  APPENDIX C  OBJECT-ORIENTED LANGUAGES AND VENDORS
  APPENDIX D  OBJECT-ORIENTED CASE (OOA/D/P TOOLS) AND VENDORS
  APPENDIX E  ANONYMOUS FTP SITES
  APPENDIX F  MAGAZINES, JOURNALS AND NEWSLETTERS
  APPENDIX G  COMMERCIAL OBJECT-ORIENTED LIBRARIES AND SYSTEMS

[Another appendix on commercial object-oriented class libraries should be
 added soon]


SECTION 1:  BASICS
==================

Suggested Readings:
  [Booch 91, 94]
  Others to be added...


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,
      with the HEADING "subscribe".
    See also st.cs.uiuc.edu for some info on patterns.
    See also http://st-www.cs.uiuc.edu/users/patterns/patterns.html

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 are 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].


1.2)  What Is Object Encapsulation (Or Protection)?
---------------------------------------------------

[Booch 91, p. 45] defines: "Encapsulation is the process of hiding all of the
details of an object that do not contribute to its essential characteristics."

[Coad 91, 1.1.2] defines: "Encapsulation (Information Hiding).  A principle,
used when developing an overall program structure, that each component of a 
program should encapsulate or hide a single design decision...  The interface
to each module is defined in such a way as to reveal as little as possible
about its inner workings.  [Oxford, 1986]"

Some languages permit arbitrary access to objects and allow methods to be
defined outside of a class as in conventional programming.  Simula and
Object Pascal provide no protection for objects, meaning instance variables
may be accessed wherever visible.  CLOS and Ada allow methods to be defined
outside of a class, providing functions and procedures.  While both CLOS
and Ada have packages for encapsulation, CLOS's are optional while Ada's
methodology clearly specifies class-like encapsulation (Adts).

However most object-oriented languages provide a well defined interface to
their objects thru classes.  C++ has a very general encapsulation/protection
mechanism with public, private and protected members.  Public members (member
data and member functions) may be accessed from anywhere.  A Stack's Push and
Pop methods will be public.  Private members are only accessible from within
a class.  A Stack's representation, such as a list or array, will usually be
private.  Protected members are accessible from within a class and also from
within subclasses (also called derived classes).  A Stack's representation
could be declared protected allowing subclass access.  C++ also allows a
class to specify friends (other (sub)classes and functions), that can access
all members (its representation).  Eiffel 3.0 allows exporting access to
specific classes.

For another example, Smalltalk's class instance variables are not accessible
from outside of their class (they are not only private, but invisible).
Smalltalk's methods are all public (can be invoked from anywhere), but a
private specifier indicates methods should not be used from outside of the
class.  All Smalltalk instance variables can be accessed by subclasses, 
helping with abstract classes and overriding.

Another issue is per-object or per-class protection.  Per-class protection
is most common (e.g. Ada, C++, Eiffel), where class methods can access any
object of that class and not just the receiver.  Methods can only access the
receiver in per-object protection.  This supports a subtyping model, as any
object other than the receiver is only satisfying an abstract type interface,
whereby no method or object structure can be inferred in the general case.


1.3  What Is A Class?
--------------------

A class is a general term denoting classification and also has a new meaning
in object-oriented methods.  Within the OO context, a class is a specification
of structure (instance variables), behavior (methods), and inheritance
(parents, or recursive structure and behavior) for objects.  As pointed out
above, classes can also specify access permissions for clients and derived
classes, visibility and member lookup resolution.  This is a feature-based or
intensional definition, emphasizing a class as a descriptor/constructor of
objects (as opposed to a collection of objects, as with the more classical
extensional view, which may begin the analysis process).

Original Aristotlean classification defines a "class" as a generalization of
objects:
[Booch 91, p93]
  "a group, set, or kind marked by common attributes or a common attribute; a
   group division, distinction, or rating based on quality, degree of
   competence, or condition".
   
[Booch's definition in the context of OOD]
  "A class is a set of objects that share a common structure and a common
  behavior."  "A single object is simply an instance of a class."

The intension of a class is its semantics and its extension is its instances
[Martin 92].

[Booch 94, 4.2] proposes 3 views of classification as useful in OO analysis and
design: classical categorization (common properties), conceptual clustering
(conceptual descriptions), and prototype theory (resemblance to an exemplar).
He advocates starting with the former approach, turning to the second approach
upon unsatisfactory results, and finally the latter if the first two approaches
fail to suffice.


1.4)  What Is A Meta-Class?
---------------------------

[See also section 1.6]
 
A Meta-Class is a class' class.  If a class is an object, then that object
must have a class (in classical OO anyway).  Compilers provide an easy way to
picture Meta-Classes.  Classes must be implemented in some way; perhaps with
dictionaries for methods, instances, and parents and methods to perform all
the work of being a class.  This can be declared in a class named "Meta-Class".
The Meta-Class can also provide services to application programs, such as
returning a set of all methods, instances or parents for review (or even
modification).  [Booch 91, p 119] provides another example in Smalltalk with
timers.  In Smalltalk, the situation is more complex.  To make this easy, refer
to the following listing, which is based on the number of levels of distinct
instantiations:

1 Level System
  All objects can be viewed as classes and all classes can be viewed as
  objects (as in Self).  There is no need for Meta-Classes because objects
  describe themselves.  Also called "single-hierarchy" systems.
  There is only 1 kind of object.
2 Level System
  All Objects are instances of a Class but Classes are not accessible to
  programs (no Meta-Class except for in the compiler and perhaps for type-safe
  linkage, as in C++).
  There are 2 kinds of distinct objects: objects and classes.
3 Level System
  All objects are instances of a class and all classes are instances of
  Meta-Class.  The Meta-Class is a class and is therefore an instance of
  itself (really making this a 3 1/2 Level System).  This allows classes to
  be first class objects and therefore classes are available to programs.
  There are 2 kinds of distinct objects (objects and classes), with a
  distinguished class, the metaclass.
5 Level System
  What Smalltalk provides.  Like a 3 Level System, but there is an extra level
  of specialized Meta-Classes for classes.  There is still a Meta-Class as in 
  a 3 Level System, but as a class it also has a specialized Meta-Class, the
  "Meta-Class class" and this results in a 5 Level System: 
    object
    class
    class class (Smalltalk's Meta-Classes)
    Meta-Class
    Meta-Class class

  The "class class"es handle messages to classes, such as constructors and
  "new", and also "class variables" (a term from Smalltalk), which are
  variables shared between all instances of a class (static member data in
  C++).  There are 3 distinct kinds of objects (objects, classes, and
  metaclasses).


1.5)  What Is The Infinite Regress Of Objects And Classes?
----------------------------------------------------------

In the authors opinion, a myth.  The story goes an object is an instance of a
class (Meta-Object), a class is an instance of a Meta-Class, which must also
be an instance of a Meta-Meta-Class, which must also be an instance of a Meta-
Meta-Meta-Class, ...  Closure can be achieved with an instance-of loop, as with
a Meta-Class being an instance of itself or with a "Meta-Class - Meta-Class
class" instance-of loop (as in Smalltalk).


1.6)  What Are MOPs And Reflection?
-----------------------------------

MOP is an acronym for Meta-Object Protocol.  This is a system with
Meta-Classes accessible to users [Kiczales 92, Paepcke 93].  In CLOS
terminology, an introspective protocol provides a read only capability (e.g.
what is this object's class, give info on this class, etc.) and an
intercessory protocol provides a write capability which allows system
modification (e.g. add the following method or instance to this class,
perform inheritance this way, etc.).  Because inheritance can be used to
perform differential changes, intercessory protocols allow users to not
only define new frameworks but to specialize existing system frameworks
differentially without affecting them and their extant objects.  Thus, many
frameworks can interoperate together simultaneously.  This is a good example
of object-oriented reuse, since the compiler itself is reused thru
specialization to provide new frameworks.

"Reflective" systems are systems with MOPs (not to be confused with reflexive
systems, which often refer to systems implemented in terms of themselves, or
bootstrapped).  Reflective systems are inevitably reflexive (as are most
quality compilers), providing a direct program interface to the system.


1.7)  What Is Inheritance?
--------------------------

Inheritance provides a natural classification for kinds of objects and allows
for the commonality of objects to be explicitly taken advantage of in modeling
and constructing object systems.  Natural means we use concepts,
classification, and generalization to understand and deal with the complexities
of the real world.  See the example below using computers.

Inheritance is a relationship between classes where one class is the parent
(base/superclass/ancestor/etc.) class of another.  Inheritance provides
programming by extension (as opposed to programming by reinvention
[LaLonde 90]) and can be used as an is-a-kind-of (or is-a) relationship or
for differential programming.  Inheritance can also double for assignment
compatibility (see section 2.7).

In delegation languages, such as Self, inheritance is delegation where objects
refer to other objects to respond to messages (environment) and do not
respecify state by default.

Inherited parents can specify various flavors of state.  Delegation languages
don't specify new state by default (to do so requires cloning), C-based (C++,
Objective-C, etc.), lisp-based (CLOS, Flavors, Scheme, etc.), and Pascal-based
(Ada95, Modula-3, Object Pascal, etc.) OO languages do, but with multiple-
inheritance can also share parents within a class lattice (CLOS and Eiffel
provide this as a default at the level of slots and features, respectively).

Inheritance also provides for member lookup, or internal environment.  Various
schemes exist, for example C++ finds the closest match within a scope but
causes an ambiguity error iff more than one parent has match, CLOS creates
a linear precedence list, Self provides parent priorities, and Eiffel forces
renaming for any parent member conflicts.

Defining inheritance (with a thorough description or denotational semantic
definition, or both) can avoid confusion about which inheritance scheme is
being used (especially in OOD), because inheritance has many variations and
combinations of state and environment (sometimes with complex rules).
Inheritance can also be used for typing, where a type or class can be used to
specify required attributes of a matching object (see sections 2.1, 2.7 and
[Cardelli 85]).  It would be more judicious to have discussions on how
inheritance should be defined instead of over what it is, since it has many
existing uses and semantics.

An example of the is-a-kind-of relationship is shown below.  Is-a is often
used synonymously, but can be used to show the "object is-a class"
instantiation relationship.  In classical OO, inheritance is a relationship
between classes only.  In one-level systems, is-a (object instantiation) and
is-a-kind-of (inheritance) are merged into one [Ungar 87, Madsen 93, Sciore
89].

                               Computer
                              /    |     \
                       Mainframe  Mini    Personal
                        /    \    ...       /   \
                  Data Proc  Scientific   PC    Workstation

Class hierarchies are subjective [Booch 91, 4.2; Lakoff 87] and usually drawn
with the parent class on top, but more demanding graphs (as is often the case
in [Rumbaugh 91]) allow any topology, with the head of an arrow indicating the
base class and the tail indicating the derived class.

Differential programming is the use of inheritance to reuse existing classes
by making a small change to a class.  Creating a subclass to alter a method
or to add a method to a parent class is an example.


1.8)  What Is Multiple Inheritance?
-----------------------------------

Multiple Inheritance occurs when a class inherits from more than one parent.
For example, a person is a mammal and an intellectual_entity, and a document
may be an editable_item and a kind of literature.

Mixin's is a style of MI (from flavors) where a class is created to provide
additional attributes or properties to other classes.  They are intended to be
inherited by any class requiring them.  Method combination, or calling
sequences of before, after, and around methods or even several primary methods
[Kim 89, ch 4], make good use of mixins by invoking their methods without
explicitly calling them, allowing client class code to remain unchanged [Booch
91, p 113].


1.9)  Does Multiple Inheritance Pose Any Additional Difficulties?
-----------------------------------------------------------------

Yes, it does.  Any name can be simply resolved to a class member with single
inheritance by simply accessing the first name encountered for data members
and by accessing the first signature match (or ambiguity) encountered for
methods (at least one way, C++ hides some member functions).  Since several
distinct parents can declare a member within a multiple inheritance hierarchy,
which to choose becomes an issue.  Eiffel forces derived classes to rename
parent members that conflict.  Self prioritizes parents.  CLOS merges member
"slots" (instance variables) with the same name into a single slot, as did
the earlier flavors.  C++ declares an error iff a conflict arises, but a
class qualifier can be used to explicitly disambiguate.  Smalltalk renders
same names for instance variables of subclasses illegal.

On the other hand, multiple-inheritance can be seen as required for basic
object-oriented programming, because many objects in the real world belong to
several classes.  In classical systems without MI, a class which should inherit
from more than one class must textually include all but one of those classes in
its interface, causing code duplication (and a messy interface).


1.10)  What Is Dynamic Inheritance?
-----------------------------------

Dynamic inheritance allows objects to change and evolve over time.  Since base
classes provide properties and attributes for objects, changing base classes
changes the properties and attributes of a class.  A previous example was a
window changing into an icon and then back again, which involves changing a
base class between a window and icon class.

More specifically, dynamic inheritance refers to the ability to add, delete,
or change parents from objects (or classes) at run-time.  Actors, CLOS, and
Smalltalk provide dynamic inheritance in some form or other.  Single hierarchy
systems, such as Self, provide dynamic inheritance in the form of delegation
[Ungar 87].

See also [Kim 89, chs 1, 3] for a discussion and [Coplien 92] for some
implementation discussion in C++.


1.11)  What Is Shared (Repeated) Inheritance?
---------------------------------------------

Multiple Inheritance brings up the possibility for a class to appear as a
parent more than once in a class graph (repeated inheritance), and there is
then a potential to share that class.  Only one instance of the class will
then appear in the graph (as is always the case in CLOS, because all *members*
with the same name will be shared (receive a single slot) with the greatest
common subtype as its type).  C++ provides an alternative, where only parents
specified as virtual (virtual bases) are shared within the same class lattice,
allowing both shared and non-shared occurrences of a parent to coexist.  All
"features" in Eiffel (C++ members) of a repeated parent that are not to be
shared must be renamed "along an inheritance path", else they are shared by
default.  This allows a finer granularity of control and consistent name
resolution but requires more work for parents with many features.


1.12)  Why Use Inheritance?
---------------------------

Inheritance is a natural way to model the world or a domain of discourse,
and so provides a natural model for OOA and OOD (and even OOP).  This is
common in the AI domain, where semantic nets use inheritance to understand
the world by using classes and concepts for generalization and categorization,
by reducing the real-world's inherent complexity.

Inheritance also provides for code and structural reuse.  In the above Computer
class diagram, all routines and structure available in class Computer are
available to all subclasses throughout the diagram.  All attributes available
in Personal computers are also available to all of its subclasses.  This kind
of reuse takes advantage of the is-a-kind-of relationship.  Class libraries
also allow reuse between applications, potentially allowing order-of-magnitude
increases in productivity and reductions in defect rates (program errors),
as library classes have already been tested and further use provides further
testing providing even greater reliability.

With differential programming, a class does not have to be modified if it is
close to what's required; a derived class can be created to specialize it.
This avoids code redundancy, since code would have to be copied and modified
otherwise.  See [Raj 89] for an alternative approach as found in Jade.

Polymorphism is often explicitly available in many OO languages (such as C++,
CLOS, Eiffel, etc.) based on inheritance when type and class are bound together
(typing based on subclassing, or subclass polymorphism), since only an object
which is a member of (inherits from) a class is polymorphically assignment
compatible with (can be used in place of) instances or references of that
class.  Such assignment can result in the loss of an object's dynamic type in
favor of a static type (or even loss of an object's representation to that of
the static class, as in C++ slicing).  Maintaining the dynamic type of objects
can be provided (and preferred); however, C++ provides both sliced and non-
sliced replacement in a statically typed environment (see section 2.1).


1.13)  Why Don't Some People Like Inheritance?
----------------------------------------------

Some people complain that inheritance is hierarchical (which is what most
object-oriented languages provide).  They would also like to see more
operations available (set operations are quite common in specialized systems).
The former is a kind of language dependent feature commonly found in object-
oriented languages which are then associated with the term "inheritance"
(although they don't need to be.  For example, delegation languages allow graph
inheritance stuctures).  Some don't like the coupling of classes (as in Jade),
but in the author's opinion many of their complaints are easily answered.  In
systems that provide inheritance, inheritance provides a simple and elegant way
to reuse code and to model the real world in a meaningful way.

Others complain multiple inheritance is too complicated because it brings up
the issues of shared bases and member conflict resolution.  But most modern
systems support Multiple Inheritance by employing semantic resolution
strategies or renaming, and most consider MI to be highly desirable.  See the
latter part of section 1.9 for an example of why MI is important.

Some prefer association to MI, claiming "roles" (as defined in [Rumbaugh 91])
should be associations and inheritance should be reserved for a single
hierarchy "creation" mechanism, however this loses polymorphism and loses the
use of inheritance for typical classification.  Representation "roles" can be
supported by dynamic multiple inheritance (DMI) in many situations.


1.14)  What Is Specialization/Generalization/Overriding?
--------------------------------------------------------

To create a subclass is specialization, to factor out common parts of
derived classes into a common base (or parent) is generalization [Booch 91,
p56].  Overriding is the term used in Smalltalk and C++ for redefining a
(virtual in Simula and C++) method in a derived class, thus providing
specialized behavior.  All routines in Smalltalk are overridable and non-
"frozen" features in Eiffel can be "redefined" in a derived class.  Whenever
a method is invoked on an object of the base class, the derived class method
is executed overriding the base class method, if any.  Overriding in Simula
is a combination of overloading and multiple-polymorphism because parameters do
not have to be declared.  Eiffel and BETA are examples of languages allowing
any member to be redefined and not just methods, as is typical.


1.15)  What Is The Difference Between Object-Based And Object-Oriented?
-----------------------------------------------------------------------

Object-Based Programming usually refers to objects without inheritance
[Cardelli 85] and hence without polymorphism, as in '83 Ada and Modula-2.
These languages support abstract data types (Adts) and not classes, which
provide inheritance and polymorphism.  Ada95 and Modula-3; however, support
both inheritance and polymorphism and are object-oriented.  [Cardelli 85, p481]
state "that a language is object-oriented if and only if it satisfies the
following requirements:

  - It supports objects that are data abstractions with an interface of named
    operations and a hidden local state.
  - Objects have an associated type.
  - Types may inherit attributes from supertypes.

  object-oriented = data abstractions + object types + type inheritance

These definitions are also found in [Booch 91, Ch2 and Wegner 87].

[Coad 91] provides another model:

  Object-Oriented = Classes and Objects 
                    + Inheritance 
                    + Communication with messages

Stroustrup's first edition of [Stroustrup 91, '86 p. 37] defines object based
as: "... storing type identification in each object, brings us to a style of
programming often referred to as "object based"", which is quite different
from C+W's.

A more modern definition of "object-oriented" includes single-hierarchy
languages and perhaps object id's for unique objects.  Object id's support the
modern notion of relocatable, persistent and distributed objects that can
even migrate across machines.  Distributed Smalltalk's proxy objects [Kim 89,
ch 19 and Yaoqing 93] provide another example of a distributable and migratable
object facility.  Separate type system support is another extension.

[Booch 94, 2.2] proposes 7 "Elements of the Object Model"; 4 major and 3 minor:
  Major:
    Abstraction
    Encapsulation
    Modularity
    Hierarchy  (Inheritance)
  Minor:
    Typing
    Concurrency
    Persistence


1.16)  Is A Class An Object?
----------------------------

In C++ no, because C++ classes are not instances of an accessible class (a
Meta-Class) and because C++ classes are not accessible to programs.  Classes
are objects in 3 Level Systems and above because classes are instances of
meta-classes.  But classes play a dual role, because objects can only be
declared to be instances of a class (and class objects instances of a
meta-class).  In 1 Level (single-hierarchy) systems, all classes are objects.


1.17)  Is An Object A Class?
----------------------------

In a Level 3 System and above yes, but only instances of a Meta-Class are
Classes.  Instances of a Class (ordinary objects) are not classes (excluding
hybrid systems).  However, all objects may be classes in single hierarchy
systems, since any object may act as a class (provide object instantiation or
act as a shared parent).


1.18)  What Is A Method? (And Receiver And Message)
---------------------------------------------------

A method implements behavior, which is defined by [Booch 91, p80]:

  Behavior is how an object acts and reacts, in terms of its state changes
  and message passing.

A method is a function or procedure which is defined in a class and typically
can access the internal state of an object of that class to perform some
operation.  It can be thought of as a procedure with the first parameter as
the object to work on.  This object is called the receiver, which is the object
the method operates on.  An exception exists with C++'s static member functions
which do not have a receiver, or "this" pointer.  The following are some common
notations for invoking a method, and this invocation can be called a message
(or message passing, see below):

  receiver.message_name(a1, a2, a3)   
  receiver message_name: a1 parm1: a2 parm3: a3

Selector would be another good choice for message_name in the above examples,
although keywords (or formal parameter names, like named parameters) are
considered part of the selector in Smalltalk (and hence Objective-C).

If done statically, this can be referred to as invocation, and message passing
if done dynamically (true dynamic binding).  Statically typed dynamic binding
(e.g. C++ and Eiffel) is really in between (checked function pointers).

See also section 1.19 below for a discussion on the functional (prefix) verses
message based (receiver based) notation.


1.19)  What Are Multi-Methods And Multiple-Polymorphism?
--------------------------------------------------------

Multi-methods involve two primary concepts, multiple-polymorphism and lack of
encapsulation.  These issues are orthogonal.  Multiple-polymorphism implies
more than one parameter can be used in the selection of a method.  Lack of
encapsulation implies all arguments can be accessed by a multi-method (although
packages can be used to restrict access, as in CLOS).  Multi-methods can also
imply a functional prefix notation, although the CLOS designers (who coined the
term "multi-method") consider the functional and receiver based forms
(messages) equivalent.  Functional syntax was chosen "in order to minimize the
number of new mechanisms added to COMMON LISP" [Kim ch 4, p70 (D. Moon)].
[Chambers 93] discusses multi-methods in his new OO language, Cecil.

Multiple-polymorphism allows specialized functions or methods to be defined to
handle various cases:

  +(int, int)
  +(int, float)
  +(int, complex)
  +(int, real)
  +(float, complex)
  +(float, real)
  +(float, float)

The above functions are specialized to each of the cases required allowing
single, highly cohesive and loosely coupled functions to be defined.  This is
also the true essence of object-oriented polymorphism, which allows objects to
define methods for each specific case desired.  In addition to better coupling
and cohesion, multiple-polymorphism reduces program complexity by avoiding
coding logic (switch statements) and because small methods further reduce
complexity, as code complexity doesn't grow linearly with lines of code per
method, but perhaps exponentially.  This should be distinguished from double
dispatch, a fancy name for single dispatch after a call, which only provides
switching on a single argument per call (but for 2 levels), consistently
ignoring the inherent type of parameters in messaging.  Double dispatch is
used in languages with static typing for simplicity and efficiency
considerations.

If all of the above types are Numbers, code can be written without concern for
the actual classes of objects present:

  fn(one, two: Number): Number
    return one + two;

The addition expression above will invoke the correct "+" function based on the
inherent (true, actual, or dynamic) types of one and two.  Only the inherent
type of "one" would be used with double dispatch!  In the author's opinion,
this is a serious shortcoming.  Further, double dispatch would only allow
switching to the "fn" function based on the type of "one" also.  This could
lead to the use of switch statements based on type or complex coding in many
real-world programming situations, unnecessarily.  In the author's opinion,
this should only be used as necessary, e.g. if the implementation language
doesn't support multiple-polymorphism and either efficiency considerations
dominate and double dispatch can be suffered, or an embedded dynamic typing
scheme is used.

Why do multi-methods allow open access to parameters?  It allows efficient
handling, like C++ friends, usually by allowing representation details of more
than one object to be exposed.  See [Kim ch 4, pp70-71 (D. Moon)] for an
alternative explanation.  While open access can be useful in some cases, it
typically isn't recommended as a general OO practice (see section 1.15, C+W's
requirement 1 for OO languages and Section 1.2 on Encapsulation) and also
violates subtype polymorphism, because only subclass polymorphism is based on
representation and not type.

Polymorphic languages can be statically typed to provide strong type checking,
efficiency, and to support a static programming idiom, but require restrictions
in many cases, such as requiring overriding methods to have identical
signatures with the methods they substitute (as in C++) or allowing covariant
parameters but limiting base class usage (as in Eiffel).  If these restrictions
are dropped, multiple-polymorphism results.  Thus a single overridable function
declared in a base class may have several functions overriding it in a derived
class differentiated only by their formal argument types.  This therefore
requires both static and dynamic typing, because no formal argument
differentiation is possible without static types, as in Smalltalk, and no
actual argument differentiation is possible without dynamic types (as in C++
and Eiffel).  See section 2.3 for another example of multiple-polymorphism.

There is some concern about the efficiency of run-time method selection as
can occur with multiple-polymorphism (or even dynamic message passing).
However, static analysis optimizations are commonly available in the
literature, potentially providing a single static selection in many cases
[See Agrawal 91, Chambers 92, Mugridge 91, and etc.].

But coupling the two cases of selector variables (as found in CLOS,
Objective-C, and etc.) and several possible known selectors together with the
general undecidability of dynamic types at compile-time renders dynamic typing
and run-time selection (or checking) as unavoidable in the general case [a
point often mistaken in comp.object.  E.g. simple statically/strongly typed
multi-methods still require dynamic types!]

See [Booch 91], multiple-polymorphism, for a good CLOS example.


1.20)  What Is OOP?
-------------------

OOP stands for Object-Oriented Programming, the usual programming/hacking and
etc. most programmers think of.  Modern software engineering methodologies;
however, consider OOP as the implementation/evolution of an OOD.


1.21)  What Is OOA/OOD (And Where Can I Get What I Need On It)?
---------------------------------------------------------------

  See also section 3.7, the Annotated Bibliography, and APPENDIX D.  The
  classified bibliography in [Booch 94] also contains entries on OOA(B), OOD(F)
  and OOP(G).

[Booch 91]
  "In OOA, we seek to model the world by identifying the classes and objects
  that form the vocabulary of the problem domain, and in OOD, we invent the
  abstractions and mechanisms that provide the behavior that this model
  requires."

[Coad 91]
  "OOA is the challenge of understanding the problem domain, and then the
  system's responsibilities in that light".
  "To us, analysis is the study of a problem domain, leading to a specification
  of externally observable behavior; a complete, consistent, and feasible
  statement of what is needed; a coverage of both functional and quantified
  operational characteristics (e.g. reliability, availability, performance)".
  "Design.  The practise of taking a specification of externally available
  behavior and adding details needed for actual computer system implementation,
  including human interaction, task management, and data management details."

And on Domain Analysis:

  "Whereas OOA typically focuses upon one specific problem at a time, domain
   analysis seeks to identify the classes and objects that are common to all
   applications within a given domain, [...]".  - [Booch 91]

  [The following quotes on domain analysis are from [Berard 93]]

  "An investigation of a specific application area that seeks to identify the
   operations, objects, and structures that commonly occur in software systems
   within this area.  - Dan McNicholl

  "Systems analysis states what is done for a specific problem in a domain
   while domain analysis states what can be done in a range of problems in a
   domain.  ...A domain analysis is only useful in many similar systems are to
   be built so that the cost of the domain analysis can be amortized over the
   cost of all the systems.

   The key to reusable software is captured in domain analysis in that it
   stresses the reusability of analysis and design, not code. - Jim Neighbors

  "The process of identifying, collecting, organizing, and representing the
  relevant information in a domain based on the study of existing systems and
  their development histories, knowledge captured from domain experts,
  underlying theory, and emerging technology within the domain."  - Kang et al.

  Object-oriented domain analysis (OODA) seeks to identify reusable items
  localized around objects, e.g., classes, instances, systems of interacting
  objects, and kits [frameworks]. OORA analysts and OOD designers will
  interact on a fairly frequent basis with the domain analysis effort.

User Contributions:

Comment about this article, ask questions, or add new information about this topic:




Part1 - Part2 - Part3 - Part4 - Part5 - Part6 - Part7 - Part8 - Part9 - Part10 - Part11 - Part12 - Part13

[ Usenet FAQs | Web FAQs | Documents | RFC Index ]

Send corrections/additions to the FAQ Maintainer:
Bob Hathaway <rjh@geodesic.com>





Last Update March 27 2014 @ 02:11 PM