Ada 95 Quality and Style Guide Chapter 9
This chapter recommends ways of using Ada's object-oriented features.
Ada supports inheritance and polymorphism, providing the programmer
some effective techniques and building blocks. Disciplined use
of these features will promote programs that are easier to read
and modify. These features also give the programmer flexibility
in building reusable components.
The following definitions are provided in order to make this chapter
more understandable. The essential characteristics of object-oriented
programming are encapsulation, inheritance, and polymorphism.
These are defined as follows in the Rationale (1995, §§4.1
and III.1.2):
You will find it easier to take advantage of many of the concepts
in this chapter if you have done an
object-oriented design. The results of an object-oriented design
would include a set of meaningful abstractions and hierarchy of
classes. The abstractions need to include the definition of the
design objects, including structure and state, the operations
on the objects, and the intended encapsulation for each object.
The details on designing these abstractions and the hierarchy
of classes are beyond the scope of this book. A number of good
sources exist for this detail, including Rumbaugh et al. (1991),
Jacobson et al. (1992), Software Productivity Consortium (1993),
and Booch (1994).
An important part of the design process is deciding on the overall
organization of the system. Looking at a single type, a single
package, or even a single class of types by itself is probably
the wrong place to start. The appropriate level to start is more
at the level of "subsystem" or "framework."
You should use child packages (Guidelines 4.1.1 and 4.2.2) to
group sets of abstractions into subsystems representing reusable
frameworks. You should distinguish the "abstract" reusable
core of the framework from the particular "instantiation"
of the framework. Presuming the framework is constructed properly,
the abstract core and its instantiation can be separated into
distinct subsystems within the package hierarchy because the internals
of an abstract reusable framework probably do not need to be visible
to a particular instantiation of the framework.
You should use inheritance primarily as a mechanism for implementing
a class hierarchy from an object-oriented design. A
class hierarchy should be a generalization/specialization ("is-a")
relationship. This relationship may also be referred to as "is-a-kind-of,"
not to be confused with "is an instance of." This "is-a"
usage of inheritance is in contrast to other languages in which
inheritance is used also to provide the equivalent of the Ada
context clauses with and use. In Ada, you first
identify the external modules of interest via with clauses
and then choose selectively whether to make only the name of the
module (package) visible or its contents (via a use clause).
9.2.1 Tagged Types
guideline
rationale
guideline
rationale
guideline
guideline
You can use three options when you define the operations on a
tagged type and its descendants. These
categories are primitive abstract, primitive nonabstract, and
class-wide operations. An abstract operation must be overridden
for a nonabstract derived type. A nonabstract operation may be
redefined for a subclass. A class-wide operation cannot
be overridden by a subclass definition. A class-wide operation
can be redefined for the derivation class rooted in the derived
type; however, this practice is discouraged because of the ambiguities
it introduces in the code.
Through careful usage of these options, you can ensure that your
abstractions preserve class-wide properties, as discussed in Guideline
9.2.1. As stated above, this principle requires that any type
that is visibly derived from some parent type must fully support
the semantics of the parent type.
9.3.1 Primitive Operations and Redispatching
guideline
rationale
guideline
rationale
Ada does not define a unique syntax for constructors. In
Ada a constructor for a type is defined as an operation that produces
as a result a constructed object, i.e., an initialized instance
of the type.
guideline
guideline
rationale
guideline
rationale
9.4.1 Derived Tagged Types
guideline
rationale
Ada provides several mechanisms to support multiple inheritance,
where multiple inheritance is a means for incrementally building
new abstractions from existing ones, as defined at the beginning
of this chapter. Specifically, Ada supports multiple inheritance
module inclusion (via multiple with/use clauses),
multiple inheritance "is-implemented-using" via private
extensions and record composition, and multiple inheritance mixins
via the use of generics, formal packages, and access discriminants
(Taft 1994).
9.5.1 Multiple Inheritance Techniques
guideline
tagged type hierarchies
9.1 OBJECT-ORIENTED DESIGN
9.2 TAGGED TYPE HIERARCHIES
example
example
class-wide type T'Class.
example
rationale
9.2.4 Abstract Types
example
rationale
notes
9.3 TAGGED TYPE OPERATIONS
example
example
example
rationale
notes
9.3.4 Equality
(Dewar 1995).
example
example
9.4 MANAGING VISIBILITY
example
9.5 MULTIPLE INHERITANCE
example
rationale
9.6 SUMMARY
tagged type operations
class-wide type T'Class.
managing visibility
(Dewar 1995).
multiple inheritance
In This Guide:
Table of Contents
Chapter 1
Chapter 2
Chapter 3
Chapter 4
Chapter 5
Chapter 6
Chapter 7
Chapter 8
Chapter 9
Chapter 10
Chapter 11
Appendix
References
Bibliography
Index