5.2 Type Extension

[ Table of Contents ] Prev ] Chapter Overview ] Next ] [ Glossary/Index ]

This section covers tagged types, Ada's means of fully supporting inheritance and dynamic polymorphism. Every tagged type is a record type, although it may initially be declared simply as "tagged private" and later fully declared (in the private part of a package declaration) as a record type. Whenever an object of a given tagged type is created it is assigned a "tag" (known to the run-time system) associating it with that type -- and the tag cannot be changed as long as that object exists. Note that there is an attribute Tag such that S'Tag provides the tag of a subtype, S, of a tagged type.

Once a tagged type has been declared, a new tagged type may be derived from it, and the new type may be given added record components as well as added operations. Thus, the new type may be an "extended" version of the former, root type. Each tagged type and its associated operations must be declared together in a package declaration, as illustrated below.

Example root tagged type declaration

package Root_Pkg is
  type Root_Type is tagged
      -- component1
      -- component2
      -- etc
    end record;
  procedure Op1(params);
  procedure Op2(params);
  function Op2(params) return Return_Type;
  -- etc
end Root_Pkg.

Example extended tagged type declaration

with Root_Pkg; use Root_Pkg;
package Extended_Pkg is
  type Extended_Type is new Root_Type with
      -- component3 (extension)
    end record;
  procedure Op1(params); -- override Op1
  procedure Op4(params); -- new operation
end Extended_Pkg; 

Lifetime Rule for Tagged Types

There is a lifetime rule that says: a parent tagged type may not outlive any type derived from it. This prevents situations where a dispatching operation might select a tag corresponding to a no-longer existing type.

Modules and Classes as Separate Concepts

Note that Ada's way of supporting inheritance is different from that of several other popular languages. In Ada the concept of module (Ada package) and class (Ada tagged type) are separate, and it is legal, for example, to declare several types of a hierarchy in a single package. (In C++ the reserved word "class" denotes both a module and a type. C++ proponents might say that the two concepts have been "unified." An Ada proponent might say that the two concepts are better treated as "orthogonal" and that other languages have "confused" them.)

Other Forms of Tagged Type Declarations

A tagged type can be declared as limited, or abstract, or private, or any combination of these. If all three are included, the syntax rules require that the declaration have the following order.

type Root_Type is abstract tagged limited private;

If the derived type has no added record components, the following syntax is required.

type Derived_Type is new Root_Type with null record;

If the derived type does have added components and the details are to be kept private, -- a "private extension" -- the following syntax is required.

type Derived_Type is new Root_Type with private;

Information Hiding with Tagged Types

There are a number of possible combinations regarding information hiding -- the extent to which client modules can directly access the data structures of the type hierarchy. Here is a relevant quote from [Cohen96].

"... we may have a tagged record type ... extended with a record extension, a tagged private type with a private extension, a tagged record type with a private extension, or a tagged private type with a record extension. Indeed, a hierarchy of tagged types derived from a common ancestor can have an arbitrary mixture of visible and private components introduced at various points in the hierarchy."

We will illustrate just one combination when we implement the hierarchy rooted at the type called Vehicle, pictured in the previous section. All record components in our examples will be private, and thus accessed only through the operations declared in the visible parts of the package declarations.

Related Topics

4.12 Derived Types

[ Back to top of pagePrev ] Next ]