SECTION 1: BASICS

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

0.1) What Is Object-Orientation? A High-Level View.

Object-orientation is a new technology based on objects and classes. It presently represents the best methodological framework for software engineering and its pragmatics provides the foundation for a systematic engineering discipline. By providing first class support for the objects and classes of objects of an application domain, the object-oriented paradigm precepts better modeling and implementation of systems. Objects provide a canonical focus throughout analysis, design, and implementation by emphasizing the state, behavior, and interaction of objects in its models, providing the desirable property of seamlessness between activities.

Object-orientation proceeds from the very beginning of the enginnering, problem/solution, or needs fulfillment process to the very end and comprises a complete and comprehensive systemic approach replete with a paradigm of techniques, methods, processes, standards, models, notations, tools, components, languages, environments, examples, community, practice, and skills. Its application domain is very large and ranges from real-world application domain modeling and enterprise engineering to the use of polymorphism in programs and the architecture, modeling and implementation of the systems that run beneath them and the distributed systems that connect them. Object-orientation offers a better paradigm, a pattern of practice and thought through which we apply the traditions of the discipline, a means through which we can view the world, and a fundemental shift in the philosophies of computer science and engineering, replacing the older paradigm of structured techniques by providing fundemental improvement and superior solution spaces.

As building blocks, object-orientation is providing improvement in basic component definition and interfacing. This new technology of objects is perhaps most evident in superior computer-human interfaces, as interface objects provide windows to underlying objects that represent the conceptually complete components of a system and that can be individually understood and then combined, integrated, and arranged in multitudes of configurations. This represents a fundemental change and improvement in the way software, if not the world, can be understood by reconstituting the basic principles of the science. And object-orientation provides for better modeling of the real world by providing a much needed improvement in domain analysis and then integration with system design, which is itself improved by the same technique.

0.2) What Is Object-Orientation? A Low-Level View.

Object-orientation is the use of objects and classes in analysis, design, and programming.

The use of objects distinguishes object-orientation from other techniques such as traditional structured methods (process-based: data and function are separate) or other techniques such as knowledge based systems (logic progamming, rules: Prolog) or mathematical methods (functional programming: fp, ML, Haskell).

Object-orientation is:

  • View Of The World - A Better Approach
  • Process
  • Evolutionary - Boehm’s Spiral Model and Prototyping
  • Iterative/Incremental - Easy to add to systems
  • Methods
  • Analysis
  • Design
  • Implementation
  • Languages
  • Components/Middleware (Corba, EJB/Java, Microsoft/COM)
  • Programming Technique
Object-oriented programming languages provide full support for object design. Many object-oriented languages are discussed in the following sections.

0.3) Why Did OO Arise?

Modeling in analysis and software design and languages for programming originally focused on process. But many metrics and results indicated the process approach was problematic and a limiting factor in what could be achieved, perhaps by several orders of magnitude, which led to the software crisis [Booch 87]. Software engineering then began striving to achieve an industrial strength process and degree of advancement and object-orientation provided the means. The inclusion of objects to better represent concepts and process offers a superior capability that can be viewed as an improvement over the older (structured) techniques, or as a totally reengineered breakthrough advance resulting from philisophical inquiry and methodological improvement, the latter in terms of both pedagogy and pragmatics.

0.4) Why Does My Organization Need Object-Orientation?

Organizationally, OO provides a superior means of:
  • Problem/Business Analysis and Requirements
  • Better Software Development/Modern programming practice
  • Superior Software Engineering Metrics
  • Web Presence and Utilization
  • Software Reuse
  • Software Use
  • Enterprise Engineering
  • Modern 3rd Party Software Is Object-Oriented (Distributed, TP, Etc).

All organizations make great use of software, as users or developers, and as employed as either a means of providing higher quality systems to customers or as a necessary competitive advantage and enabler of business process and function.

As OO provides for better software and analysis models, it is an important reusable asset for any organization. Objects are most important to business analysis and software design and implementation as an improvement of technique.

It could also be speculated that as the number of reusable components begins to increase, users of software will become increasingly responsible for system configuration and customization, and this may replace some programming going on today.

0.5) Where Did Object-Orientation Come From?

Simula was the first object-oriented language providing objects, classes, inheritance, and dynamic typing in 1967 (in addition to its Algol-60 subset). It was intended as a conveyance of object-oriented design. Simula 1 was a simulation language, and the later general-purpose language Simula 67 is now referred to as simply Simula. Smalltalk was the next major contributor including classes, inheritance, a high-powered graphical environment and a powerful dynamic typing mechanism (which existed to some extent in Simula). Self is somewhat of a Smalltalk-based next generation language, as is BETA a followup to Simula (by its original designers).

[Meyer 88] contains a brief summary and history of Simula and Smalltalk, among other OO languages.

0.6) What Are The Primary Object-Oriented Languages Today?

C++ added classes to C as early as 1985 and by the 1990s had emerged as the market leader in object-oriented languages (if not all of programming) with powerful features including multiple inheritance, exceptions, templates, operator overloading, and namespaces. It's popularity was due in part to compatibility with the large existing base of C programmers and the widespread use of Unix, which ran on many machines.

Java is now vying with C++ as the most popular object-oriented programming language. Java was created as a simplification of C++ that could run on any machine, providing a write-once/run anywhere capability. This development was originally to support multitudes of devices (still true today) and with the rise of the WWW enabled Java to become the defacto Web programming language with applets that could run in a browser on any platform. Java provides first class support for object-orientation rather than the hybrid approach of C++, which added object-orientation to C but retained the underlying C structured programming base language. Java also has several advanced capabilities, including reflection and support for graphics, distributed programming (RMI, Remote Method Invocation), components and distributed middleware (EJB, Enterprise JavaBeans), threading, and the WWW (Applets). Java is now used in most application programming areas, but does not have the low-level facilities required for systems programming. It was originally interpreted, although some vendors now provide native-compiled executables and Sun provides Hot Spot runtime optimized runtime environments (JRE, Java Runtime Environment).

Sun's JDK 1.3 defines the latest release of Java, and EJB 2.0 is the new standard for the J2EE, or Java 2 Platform, Enterprise Edition.

0.7) What Are The Primary Object-Oriented Methodologies Today?

While there are many object-oriented methodologies (see What Are The Current Object-Oriented Methodologies?), the Unified Modeling Language, or UML, has become the industry standard design and analysis notation, which lends itself to a methodology.

0.8) What Are The Benefits Of Object-Orientation?

Reuse, quality, an emphasis on modeling the real world (or a "stronger equivalence" with the RW than other methodologies), a consistent and seamless OOA/OOD/OOP package, naturalness (our "object concept"), resistance to change, encapsulation and abstraction (higher cohesion/lower coupling), and etc.

On resistance to change, system objects change infrequently while processes and procedures (top-down) are frequently changed, providing object-oriented systems with more resilient system organization.

[Harmon 93]:

  • Faster development
  • Increased Quality
  • Easier maintenance
  • Enhanced modifiability
[Booch 94]:
  • Exploit power of OOPs
  • Reuse of software and designs, frameworks
  • Systems more change resilient, evolvable
  • Reduced development risks for complex systems, integration spread out
  • Appeals to human cognition, naturalness
  • 0.9) What is Open Source Software?

    Open source software is a relatively new phenomenon where software systems and their source code is given away freely. Most open source today comprises large-scale distributed object-oriented software systems. Often these systems are Java based and platform independent. Licenses may be required when redistributing this source code as part of a commercial system and support may be available for a price, often only affordable by corporations. Email distribution lists are also freely available for support. These systems have their market niche and are recently among the most powerful (and best?) systems available. They can be self-supported and installed by most professionals making some of the most powerful object-oriented software systems freely available. This site is now run under full J2EE (JSP/servlet/EJB/database) with open source including Linux, JBoss, and struts.

    Open Source includes:

    1. Linux operating system. (If you can tell it isn't Unix (w/bash), you're an expert). rpmfind.net.
    2. Apache - Web Server (largest use of any Web Server), Jakarta Tomcat reference Web container, Geronimo J2EE/EJB container, Axis reference Java Web Services (also C++).
      • Ant Java build tool (platform independent, extensible)
      • Struts Model 2 - J2EE Front Controller Archtecutral pattern.
      • JSP Taglibs and JSTL reference implementation (next generation JSP).
      • Lots more
    3. Source Forge - Largest open source collection.
    4. JBoss - Open source EJB container.
      • Full package comes with Jetty Web Server/Container and database in 1 process (no connector headaches/low overhead) and Apache Axis. Also bundled with Tomcat/Axis.
      • This site is now run on JBoss. JSP/servlet/EJB implementation in progress, soon to server as tutorial examples.
      • Free email support.
      • New EJB 3.0 draft implementation
    5. Java Data Objects (JDO) - Alternative to CMP, gens interface code with tools.
    6. ACE TAO, JacORB - CORBA ORBs. Many sites with support.
    7. Relational Databases include MySql.com, hypersonic Java SQL Database, PostgreSQL.
    8. Quality Software Engineering (Engineering Management)
    9. Java & C++
    Open Source Advantages:
    1. Open source software is often the most widely used in their market, e.g. Apache Web Server.
    2. Open sources are often donated by large corporations and are often still a part of their commercial offering.
      • Tomcat Web Container (servelts, JSP) is from Sun
      • Apache SOAP is from IBM, IBM research still offers help on newer Axis rewrite
    3. Open Source is often the reference implementation for standards, Tomcat has been the reference implementation for JSP and servlets.
    4. Open source is often Java-based and operating system independent, allowing for example development on Intel/MS then production versions on Unix/Linux.
    5. Open source means bugs can be fixed (I've even fixed one in an Axis prerelease!) when required.
    6. Open source allows API semantics to be fully understood when complete documentation is not available.
    7. Most Open Source software has mailing lists with high quality support.
    8. New research can be performed by extending open source software.

    0.10) What are the Major New Distributed Object Oriented Technologies?

    J2EE and .net have become the new standards for Web/distributed programming and object-oriented systems. A Gartner report has projected that within a few years .net and J2EE will each have 40% of the distributed systems markets. It is assumed Corba (and perhaps C++ Web Services) would fall somewhere in the remaining 20%. J2EE is the Java platform now embraced by Sun, IBM/Websphere, Bea Weblogic (although Tuxedo C++ Web Services are still available), among many others. It comprises JSP for dynamic html views from the server side, servlets for control, and beans and EJB for business logic. Much recent work has gone into J2EE patterns (Core Patterns, [Alur 03], [Marinescu 02]), integratable open source (Apache Jakarta), and add-ons (JDO).

    .net is the Microsoft platform supporting distributed programming and supporting Web Services. .net's primary programming language is C# (similar to Java and C++ with extensions), but also supports C++, Java, J#, and VB. .net's primary intention is to provide a strong integrated development environment (IDE) to facilitate rapid development in a distributed environment (Web Services). .net from Microsoft is platform dependent, although open source efforts are underway including mono and MS shared source. Both .net and J2EE support Web Services, the new SOAP standard for dynamic distributed systems.

    Java Tiger release has improvements that will impact J2EE, such as AOP (a few implementations already exist), and also language addons including generics and an ongoing prototype compiler to prepare for the new facilities. While the first major upgrade for the Java language proper, the tiger metadata facility will be similar to .net's attributes, and may improve J2EE by not requiring 4 or 5 interfaces per EJB, which while usually generated by an IDE (integrated development environment) still require updating. Aspect-oriented programming (AOP) decorates object-oriented constructs with metadata, extending them for almost any purpose. JBOSS 4.0 shows the potential for AOP:

    The Aspect-Oritented Programming architecture of JBoss 4.0 enables it to provide a wide range of services, including object persistence, caching, replication, acidity, remoteness, transactions and security. The framework allows developers to write plain Java objects and apply these enterprise-type services later on in the development cycle -- without changing a line of Java code. This new concept of programming provides a clean separation between the system architect and the application developer. The iterative development process becomes more fluid as architectural design decisions can be made later on in the development process without changing any of your Java code. Entirely unique among Java-based application servers today, this architecture combines the simplicity of standard Java with the power of J2EE.

    JBoss 4.0 brings Aspect-Oriented technology to Java through a pure 100% Java interface. Base on the new JBoss.org project Javassist, JBoss-AOP allows you to apply interceptor technology and patterns to plain Java classes and Dynamic Proxies.

    It is important to perceive as technology changes, good architectures and designs are prepared for and welcome almost daily additions to available technology and even major changes to technology itself. Good object-oriented architecture and design patterns provide the best abstraction and information hiding facilities to easilty accommodate such changes. Examples include business delegates, session facades, service locators, and many more . [These architectural patterns are referenced by the free patterns resources available by logging in and participating in an Object FAQ survey]

    Xdoclet provides another approach to metadata and generation of EJB-like facilities to POJOs (Plain Old Java Objects) with attribute-oriented programming.

    OMG MDA MOF ([Kleppe 03], [Frankel 03])provides another approach to handling change, by providing the capability to generate some or all of an implementation from a design model. Now, this could include generating a J2EE implementation today, a .net implementation tomorrow (running on MS), both, a hacker's 2 tier implementation at some point, and then a J2EE AOP implementation sometime after without ever changing a single line of application code. Sun Ace provides a similar example of a mostly translational design, requiring only 224 lines of code (in addition to models) to completion by one programmer in one week (and not 6 months by a J2EE programmer, apparently without IDE) as opposed to 3,484 for .net and 14,273 for the standard J2EE Pet Store example. However, the FAQ author notes that the amount of IDE generated J2EE code from a modern IDE (IBM WSAD, Jbuilder, Jdeveloper, Sun ONE, etc.) is not specified. Steve Mellor's Executable UML describes an implementation of Executable UML called xtUml (executable translatable) using model compilers to translate design models to implementation. Kennedy Carter has another fullimplementation of xUML (and iUML), another OMG MOF implementation. See also Object FAQ OO CASE appendix, Full Execution.

    This section will soon have running J2EE examples. Until then here's a pretty cool intro aspect in AspectJ 1.1. It'll be moved to a new home shortly (within hours) but it had to go somewhere in the meantime;-)

    class A {
        	public void setX(int i){
        	}
    	public int setXYZ(int x, int y, int z){
    		return y;
    	}
    	public static void s(){
    		System.out.println("in s");
    	}
         	public static void main(String args[]){
    		A a = new A();
    		a.setX(5);
    		int r = a.setXYZ(1, 2, 3);
    		a.setXYZ(4, 5, r);
    		s();
    	}
    }
    
    aspect asp {
    	static String printArgs(Object []args){
    		StringBuffer	buffer = new StringBuffer();
    		for(int j=0; j<args.length; ++j)
    			buffer.append(args[j].toString() + ", ");
    		return buffer.toString();
    	}
    	// Match all Method calls except in this class, java package calls, and calls on instances of this class.
    	pointcut methodCall(): call(* *(..)) 
    				&& !within(asp)
    				&& !call(void java.*.*.*(..))
    				&& !target(asp);
    /*
    	before() : methodCall() {
    	    	System.out.println("Entering: " + thisJoinPoint + "=" + printArgs(thisJoinPoint.getArgs())); 
    	}
    
    	after() returning (Object o) : methodCall()  {
    	    	System.out.println("Exiting: " + thisJoinPoint + "=" + o); 
    	}
    */	// Identical to before and after above.
    	Object around()  : methodCall() {
    		System.out.println("Entering: " + thisJoinPoint + "=" + printArgs(thisJoinPoint.getArgs())); 
    		Object o = proceed();
    		System.out.println("Exiting: " + thisJoinPoint + "=" + o); 
    		return o;
    	}
    }
    

    0.11) What are Web Services?

    Web Services are a (or the) new object-oriented technology based on SOAP XML/Schemas for distributed application computing. Its goal is to provide dynamic distributed computing independent of platform or programming language. CORBA has been only partially successful at this task. Web Services are based on internet/Web standards (http (default transport), SOAP, WSDL, UDDI) and are available to all systems that can access the Web. J2EE and .net support Web Services and .net uses Web Services as the primary distributed application protocol. A single class makes up a Web Service and it's methods are available as remote operations. The class can be written in any language and is automatically deployed as a Web Service accessible to any client. Parameters are serialized into SOAP XML and deserialized at the other end transparently to both client and service. Primitive types, classes, inheritance, enumerations and arrays are supported, see jax-rpc for the Java specification. XML Schemas describe parameter data in the WSDL types section. A dynamic invocation interface is available to clients to generically handle any Web Service and call, or stubs can be generated to make the Web Service completely transparent. Data is passed by value, references must be handled manually.

    Web Services are simpler than CORBA and send data as XML typically over http. For large data sets with complex requirements, CORBA may be more suitable. Web Services can provide for MIME attachments to handle such data sets as black boxes. Types available for data use XML schemas, which supercede XML DTDs. While multiple namespaces are a powerful mechanism in XML Schemas, they can be confusing to the uninitiated.

    Web Services are:

    1. Soap. Soap messages are sent between client and server.
    2. WSDL. Web Service Description Language. Defines the Web Service and possible Soap messages. This is an application class, it's available methods, and the types of data transmitted (XML schema). Also bindings for translation.
    3. UDDI Universal Description, Discovery, and Integration. A means of looking up Web Services of interest. Structures include Business Entities, Business Services, and categories of types for lookup. Further work on Universal Interoperability protocols is expected, such as Sangam.
    Author's Note:
    This section will soon be and expanded and have working examples of Web Services and typical clients.

    0.12) What is available on Software Architectures?

    A lot lately.

    Author's Note:
    This section is NYI. New sections including an architectural approaches comparison matrix and design patterns summary will soon appear.

    1.1) What Is An Object?

    There are many definitions of an object, such as found in [Booch 94, p83]: "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 94, p82]. 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 94, 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. Use cases have become very important and popular today, providing an easy way to identify objects and methods by their use in satisfying system requirements and uses. Uses cases occur throughout the development lifecycle. A new section on use cases is forthcoming. Jacobson has also called 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           - Abstract MO meant for reuse and extension
        Patterns*            - Framework-like, crsp. classes and comm patterns only
      Analysis Model Objects - In the Object Model
        Interface              - E.g. GUI
        Control                - Control (or use) entity objects - Process logic
        Entity                 - Typically Correspond to real-world objects,
    			     - Business objects
      Component Objects    - Utility and Implementation hiding objects
        Utility              - Set, Array, ...
        Impl. Hiding         - Distr. Arch., specific DBMS, OS
     
      **To join a patterns  mailing list
          with the HEADING "subscribe".
        See also http://st-www.cs.uiuc.edu/users/patterns/patterns.html
        See also Organization Patterns
    

    Since the analysis portion of Jacobson's OOSE has been incorporated into the UML, objects found in the analysis model (interface, control, and entity), are now stereotypes in the new OMG standard for methodologies, the Unified Modeling Language.

    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.

    The new object language Java uses pointer semantics where all variables are references and are assigned to objects, which ultimitly begins with a call to new with constructor parameters (or else an error would occur). There are no pointers in Java and Java objects are garbage collected. Since references are passed by value (and objects by reference), it is not possible to write a simple swap routine in Java!

    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. A better general reference is The C++ Programming Language, 3rd Edition, which contains the ISO standard draft and Standard Library. Virtual functions are 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. Children of a base class are referred to as siblings. An interesting case of siblings occurs with multiple-inheritance and virtual base classes in C++ [Stroustrup 97, p397+].

    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 94] defines: "The process of compartmentalizing the elements of an abstraction that constitute its structure and behavior; encapsulation serves to separate the contractual interface of an abstraction and its implementation."

    [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. Java encapsulation is very similar to C++ (as Java was originally based on C++), and also has public, private, and protected access. Java also offers final, which is similar to const in C++, but final classes cannot be subclassed.

    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).

    A typical C++ class specification:

    
      template <class BASE>		// Template - a parameterized class
      class Stack {
      public:
        Stack();
        BASE *push(BASE *);
        BASE *pop (BASE *);		// Returns element pushed
        int   size();
      private:
        List<BASE *>   l;   // None of a user's business, except for the
        			/// performance metrics of the class specification.
      };
    
      Stack<int>            intStack;               // Stack of ints
      Stack<MyClass>        myClassStack;           // Stack of MyClass objects 
      Stack<Stack<double>>  doubleStackStack;       // Stack of Stacks of doubles
    
    A typical Java interface:
    
      /**
       * Specifies a stack of any kind of Object(s).  Java supports
       * a poor-man's polymorphism model with respect to generics.
       */
      public interface IStack {
        public Object push(Object);	
        public Object pop (Object);
        public int     size();
      }
    
    As shown above, a class has two components: type (interface) and class (representation). This is discussed in depth in section 2.7. Java would also define implementations of Stack as a class implementing the IStack interface, similar to the C++ class, although Java does not as yet support generics.

    Original Aristotlean classification defines a "class" as a generalization of objects: [Booch 94, p103] "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 Metaclass 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 Metaclasses. 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 "MetaClass", or class Class in Java. The Class class can also provide services to application programs, such as returning a set of all methods, instances or parents for review (or even modification), as found in Java. Java's metaclass Class provides some degree of reflection, including retrieving methods, fields, nested classes, loader, and also the ability to generically create new instances of a class and generically invoke methods on an object. Click for a running JApplet (swing) example in Java.

    Very short Java example code:

      import java.lang.reflect.*;
    
      class A{
        public void fn(){}
        public int  fn(A a, int i){ return 5; }
      }
    
      Class       aClass     = A.class;                     // Get A's class
      try{
          Class       aClass2     = Class.forName("A");          // Get A's class
      }catch(ClassNotFoundException e){
      }
      Method      methods[]  = aClass.getMethods();         // Get A's public methods
    
      Class       getClassBack = methods[0].getDeclaringClass();  // Get class A again.
    
      Object      instance    = null;  
      A           instance2   = null;
      try{
          instance    = aClass.newInstance();       // Create a new object with class A
          instance2   = (A)aClass.newInstance();    // Create a new object with class A
      }catch(InstantiationException e){
      }catch(IllegalAccessException e){
      }
      Method method = null;
      try{
          method = aClass.getDeclaredMethod("fn", null);   // Get fn with no parameter
      }catch(NoSuchMethodException e){
      }
      try{
          Object result = method.invoke(instance, null);          // Invoke fn
      }catch(IllegalAccessException e){
          System.err.println("caught e=" + e);
      }catch(InvocationTargetException e){
          System.err.println("caught e=" + e);
      }
    
    [Booch 94, 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 (C++)
      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 (Java)
      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 (Smalltalk)
      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?

    [See also Section 1.6]

    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. Please see Click for a running JApplet (swing) example in Java demonstrating reflection.

    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/superclass. For example, a person is a mammal and an intellectual_entity, and a document may be an editable_item and a kind of literature.

    If the above Computer class hierarchy were required to inherit from several new classes, such as ManufactureItem, SaleItem, and ElectronicDevice, multiple inheritance is appropriate because the is-a replationship holds for polymorphism and because the Computer class (and its derived classes) do not require change other than inheriting from the parents, which themselves inherit from abstract class/interface type definitions to provide loosly coupled polymorphism in clients. These new base classes provide default implementations of their interfaces, which is typically sufficient for most subclass'es needs.

    As shown in the following example, the Java code without Multiple inheritance requres a fat class to hold all of the details of code, which is low in the class design metric of cohesion. In this case, it may be better to have ManufactureItem and SaleItem (or perhaps derived classes) have a reference to the Computer or ElectronicDevice interface, which in the real world and in other cases may or may not be possible.

    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 parent member functions with matching names; Java does not). 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.

    Java does not support multiple-inheritance and the pragmatics of the language are against the facility. Java does provide multiple inheritance of interfaces, which provides for typing but requires implementation classes along the single inheritance superclass line to become fat with all routines necessary to implement all interfaces. With multiple inheritance, classes can be more cohesive by only declaring methods for routines directly implemented by themselves, and not for classes delegated to for implementing required interfaces. C++ and other languages supporting multiple inheritance still consider it to be a very useful facility.

    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 multiple inheritance, a class which should inherit from more than one class must textually include all but one of those classes in its interface, causing either a lot of messy wrapper methods or code duplication.

    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++.

    See also the following article on Dynamic Inheritance, which provides examples.

    1.11) What Is Shared (Repeated or virtual) Inheritance?

    Multiple Inheritance allows 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 base classes (p 396)) 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.

    The following example shows the effective structure for virtual inheritance. In figure 1, all parents are shared, indicating an instance of Cyborg will only contain the data for a single instance of each shared base class, Movable and Displayable. Only a single instance of Graphics will exist whenever virtual inheritance is specified anywhere in the class hierarchy, which is true of any virtual inheritance. Figure 2. shows the structure with no shared inheritance, two instances of Movable, Displayable, and Graphics exist for each instance of Cyborg. Figure 3. displays both shared and non-shared inheritance, with only a sngle shared instance of Movable and 2 instances of Displayable (and therefore Graphics). Not shown is the case of a single class which is shared thru the virtual specifier in C++ in a number of places, but not shared (not virtual) in other superclass lists.

    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 MultiMethods 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 89, 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 89, 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.

    OOA and OOD stand for Object-Oriented Analysis and Object-Oriented Design, respectively. OOA strives to understand and model, in terms of object-oriented concepts (objects and classes), a particular problem within a problem domain (from its requirements, domain and environment) from a user-oriented or domain expert's perspective and with an emphasis on modeling the real-world (the system and its context/(user-)environment). The product, or resultant model, of OOA specifies a complete system and a complete set of requirements and external interface of the system to be built, often obtained from a domain model (e.g. FUSION, Jacobson), scenarios (Rumbaugh), or use-cases (Jacobson).

    [Shlaer 88] is often credited as the first book on OOA, although their method adds OO techniques to the traditional structured analysis principles of Yourdon and Constantine. Their complete approach ([Shlaer 88, 92]) consists of information modeling and recursive design, or OOA/RD and represents a recent addition to the structured analysis family (as does Martin and Odell). [Yourdon 92] provides a critique, although may only refer to their earlier work. Many other methodologies including Rumbaugh's OMT, Martin and Odell's OOA/D, and many others, also share common ground with SA and other existing analysis methodologies with such constructs as associations (E-R), functional models, and even DFD's. Booch, Jacobson, and Wirfs-Brock are examples of OO methodologies representing a greater departure from the conventional "structured" techniques, with greater emphasis on objects. OOram [Reenskaug 91] provides support and emphasis on types and roles as guiding principles, which is quite powerful. [Booch 94] presents a methodology which is an evolutionary step beyond the first edition by incorporating a collection of the best features from several of the major OO methodologies, as does HP's new FUSION methodology.

    A new Unified Modeling Language (previously Unified Method) is now being worked on by Grady Booch, James Rumbaugh, and Ivar Jacobson at Rational Software which should be made into a public standard, perhaps to be adopted by the OMG. The latest docs can be found online from the Rational home page.

    The usual progression is from OOA to OOD to OOP (implementation) and this Universal Process Model roughly corresponds to the Waterfall Model [Royce 70]. See [Humphrey 89] and [Yourdon 92] for a few of many discussions on software life-cycle models and their use. Humphrey also details Worldy and Atomic Process Models for finer grained analysis and design in the Defined Process (see below) and discusses other alternatives to the task oriented models. He also provides the following critisisms on the Waterfall Model which had led to Boehm's seminal work on the Spiral Model:

    • It does not adequately address changes
    • It assumes a relatively uniform and orderly sequence of development steps
    • It does not provide for such methods as rapid prototyping or advanced languages
    Modern OO methodologies directly address these points and emphasize the incremental, iterative, evolutionary, concurrent and situational nature of software development. [Boehm 86] presents a seminal spiral life-cycle model with a risk-driven incremental prototyping approach. [Booch 91, 6.1] proposes a "round-trip gestalt" design with analyze-design iterations and an overall system perspective and [Berard 93] proposes an (incremental) "parallel-recursive design" with analyze-design-implement-test iterations. [Coad 91b] presents the following development cycle breakdown:
      Waterfall-
        Analysis
        Design
        Programming
    
      Spiral-
        Analysis, prototyping, risk management
        Design, prototyping, risk management
        Programming, prototyping, risk management
        [Boehm, 1988]  
    
      Incremental-
        A little analysis
        A little design
        A little programming
        Repeat
        [Gilb 88]
    
    [Author's note: The spiral model is often incremental and may waterfall if called for.]

    Since classes and objects are used in all phases of the OO software life-cycle, the process is often referred to as seamless, meaning there is no conceptual gap between the phases as is often the case in other software development methodologies, such as the analysis (DFD's) to design (structure charts) to programming gaps found in traditional structured analysis and design. Seamlessness together with naturalness is a big advantage for consistency.

    A problem domain has many realizations, or differing OOAs. An OOA has many realizations, or differing OODs, but a similar notation is often used for the two. An OOD also has many realizations, or differing OOPs, but allows a selection from among various languages for implementation (choosing the best language to implement the design). But some, such as Bjarne Stroustrup, don't like OOA and OOD getting too far from OOP (implementation independent), for fear that great discrepancies could occur between OOD and OOP by losing sight of the implementation language, which in some cases is predetermined. See also [Stroustrup 97].

    From a greater perspective, the SEI has developed the Capability Maturity Model (CMM), a process-based TQM model for assessing the level of an organization's software development and which is often required of government contractors in the US [Humphrey 89]. The CMM also serves as a 5 level improvement process by specifying steps for organizations to progress to the next level, ultimately leading to statistical (process) control and sustained improvement. Watts S. Humphrey is now working on the Personal Software Process (PSP), a scaled down version of the CMM for individuals [Humphrey 95]. Next should follow a team- based software process (TSP?). Other CMM's in the works at the SEI include a personnel management CMM (PM-CMM).

     Level 1: Initial:    Every project is handled differently; ad hoc and chaotic.
     Level 2: Repeatable: Every project is handled similarly.
     Level 3: Defined:    Standard processes are defined and used for all projects.
     Level 4: Managed:    A measurable basis for all improvements to the process.
     Level 5: Optimizing: Emphasis on defect prevention and optimizing/continually
                          improving the process.
    

    CMM documentation is available online from: http://ricis.cl.uh.edu/CMM and ftp.sei.cmu.edu/pub/cmm/.

    See also:

    Kitson, D.H. and Masters, S. "An Analysis of SEI Software Process Assessment Results 1987-1991", CMU/SEI-92-TR-24

    Humphrey, W., Snyder, T. and Willis, R. "Software Process Improvement at Hughes Aircraft", IEEE Software, July 1991

    Dion, R., "Elements of a Process Improvement Program," IEEE Software, July 1992.

    "Concepts on Measuring the Benefits of Software Process Improvement," CMU/SEI-93-TR-9.

    See also [Yourdon 92], [Wilkie 93], and [Booch 94] for discussions on this often cited model. There is also an ISO 9000 standard [ISO] applicable to software quality and ami working group in Europe helping to creat the ISO SPICE [Rout 95] standard (among other work), which is similar in scope to the CMM. To join the ami mailing list email to:
    ami-request@aut.alcatel.at
    with the following message:
    subscribe firstname, lastname, e-mail address.
    Object-oriented analysis now includes "Enterprise Modeling" [Martin 92], also found in [Jacobson 92], and along with recent business process "reengineering" efforts places information systems within an organizational perspective by modeling entire organizations or a large part of them, with the information processing system and software products development as integrated components. [Yourdon 92] even calls for "global modeling"!

    1.22) What Other FAQs Are Available?

    FAQ's are cross-posted to news.answers and are archived on anonymous ftp from:
    rtfm.mit.edu:/pub/usenet (also usenet-by-hierarchy, etc.)
    rtfm archives several FAQs pertinent to OO (alternative/original sites are listed).
    comp.lang.ada ajpo.sei.cmu.edu:public/comp-lang-ada/cla-faq[12]
    comp.lang.beta ftp.daimi.aau.dk:pub/beta/faq/beta-language-faq.txt
    comp.lang.c++ sun.soe.clarkson.edu:pub/C++/FAQ [128.153.12.3]
    comp.lang.clos  
    comp.lang.eiffel ftp.cm.cf.ac.uk:/pub/eiffel/eiffel-faq
    comp.lang.modula3  
    comp.lang.oberon  
    comp.lang.objective-c http://www.marble.com/people/dekorte/Objective-C/objc.html
    comp.lang.sather ftp.ICSI.Berkeley.EDU:pub/sather [not on rtfm]
    comp.lang.scheme ftp.think.com:/public/think/lisp/scheme-faq.text
    comp.lang.smalltalk xcf.Berkeley.EDU:misc/smalltalk/FAQ/SmalltalkFAQ.entire
    comp.object zaphod.uchicago.edu:/pub/CompObj8.faq(.Z) (also www)
    comp.object.logic ftp.cs.cmu.edu:(2)prg_1.faq,prg_2.faq [128.2.206.173]
    comp.software-eng  

    Notes:

    1. xcf.Berkeley.EDU is 128.32.138.1
    2. /afs/cs.cmu.edu/project/ai-repository/ai/pubs/faqs/prolog/
    3. BETA FAQ www (most current): http://www.daimi.aau.dk/~beta/FAQ http://www.daimi.aau.dk/~beta/info Email: info@mjolner.dk with body: send BETA beta-faq
    4. Modula-3: ftp.vlsi.polymtl.ca:pub/m3/m3-faq.ps. http://froh.vlsi.polymtl.ca/m3/m3-faq.html. Archives: gatekeeper.dec.com:pub/DEC/Modula-3/comp.lang.modula3 Newsgroup relay mailing list; message to m3-request@src.dec.com
    5. comp.lang.eiffel archive: http://www.cm.cf.ac.uk/CLE/archive_index.html
    See APPENDIX E: 60 for a CDROM with Internet FAQs.

    A new C++ libraries FAQ is posted monthly to comp.lang.c++ and should be on rtfm soon. Contact cpplibs@trmphrst.demon.co.uk. It contains anonymous ftp sites and commercial libraries and may be merged with this FAQ eventually.

    Many FAQs are also available from mail-servers, however most can be accessed by the rtfm mail-server. Mail to mail-server@rtfm.mit.edu with help and index in the body with no leading spaces and on separate lines for more information.

    Example Unix Command (will retrieve this FAQ in about 26 pieces (and growing)):

      mail mail-server@rtfm.mit.edu
      Subject:
      send usenet/comp.object/*
    

    There is also a great ftp site for sci.virtual-worlds on:

    stein.u.washington.edu (140.142.56.1)
    [While VR may not be directly related to comp.object, it is most interesting! - The Author]