[ Table of Contents ]
Recall that in Ada terminology the word class (not a reserved word) refers to an entire hierarchy of types derived from a common root type -- a derivation class (tagged or not). When the derivation class is tagged, there is an implicitly declared type known as a classwide type, which comprises the union of all types in the class. (See examples such as "Vehicle'Class" in code below.) A classwide type is an example of an indefinite subtype.
Formal parameters of subprograms associated with tagged types are allowed to belong to a classwide type. When a call is issued to such a subprogram the resulting action is known as a classwide operation and involves an automatic implicit type conversion "toward the root." This is also known as a view conversion because a different view of the object, possibly consisting of fewer components, is generated.
When the formal parameters of subprograms associated with tagged types all have definite types, these become dispatching operations, which may (under certain circumstances) become dynamically dispatched to the appropriate version of the subprogram. Whether or not static dispatching (at compile time) or dynamic dispatching (at run-time) occurs depends on how the client code is written. (See examples in following pages.) In either case it is the "tag" associated with the actual parameters that determines which version is called.
Example Derivation Class of Tagged Types
This subsystem of packages implements the hierarchy modeled in a previous page. It includes the top-level package (Vehicles), two public children, and four public grandchildren. Each package declares one tagged type in the derivation class. Only the package declarations are given here. The seven package bodies are given in the next section. |
The above diagram represents two hierarchies arranged together. One is a module hierarchy of Ada library packages descended from a common ancestor module (Vehicles). The other is a hierarchy of types descended from a common root type (Vehicle).
Source Code Listing
--------------------------------------------------------------------- -- These package declarations define a hierarchy of military -- vehicle types. --------------------------------------------------------------------- package Vehicles is type Str_2 is array(1..2) of Character; type Lat_Type is range -90..90; type Lon_Type is range -180..180; type Hdg_Type is mod 360; type Vehicle is abstract tagged private; -- root type procedure Rename_Reset(V : in out Vehicle'Class;-- classwide op Nm : in Str_2; Lat : in Lat_Type; Lon : in Lon_Type; Hdg : in Hdg_Type); procedure Report_Position(V : in Vehicle'Class); -- classwide op procedure Change_Heading (V : in out Vehicle; -- dispatching op H : in Hdg_Type) is abstract; procedure Deploy_Weapon (V : in Vehicle) is abstract; -- dispatching op private type Vehicle is abstract tagged record Name : String(1..2) := "A1"; Latitude : Lat_Type := 0; Longitude : Lon_Type := 0; Heading : Hdg_Type := 0; end record; end Vehicles; --------------------------------------------------------------------- package Vehicles.Airplanes is type Alt_Type is new Integer range 0..100000; type Airplane is abstract new Vehicle with private; -- extension procedure Change_Altitude(A : in out Aircraft'Class; -- new op Alt : in Alt_Type); procedure Change_Heading(A : in out Aircraft; -- override operation H : in Hdg_Type); private type Airplane is abstract new Vehicle with record Altitude : Alt_Type; -- new component end record; end Vehicles.Airplanes; --------------------------------------------------------------------- package Vehicles.Ships is type Ship is abstract new Vehicle with private;-- extension procedure Change_Heading(S : in out Ship; -- override operation H : in Hdg_Type); private type Ship is abstract new Vehicle with null record; -- no new components end Vehicles.Ships; --------------------------------------------------------------------- package Vehicles.Airplanes.Fighters is type Fighter is new Airplane with private; -- extension procedure Deploy_Weapon (F : in Fighter); -- override operation private type Fighter is new Aircraft with null record; -- no new components end Vehicles.Airplanes.Fighters; --------------------------------------------------------------------- package Vehicles.Airplanes.Bombers is type Bomber is new Airplane with private; -- extension procedure Deploy_Weapon (B : in Bomber); -- override operation private type Bomber is new Aircraft with null record; -- no new components end Vehicles.Airplanes.Bombers; --------------------------------------------------------------------- package Vehicles.Ships.Cruisers is type Cruiser is new Ship with private; -- extension procedure Deploy_Weapon (C : in Cruiser); -- override operation private type Cruiser is new Ship with null record; -- no new components end Class_Vehicle.Class_Ship.Class_Cruiser; --------------------------------------------------------------------- package Vehicles.Ships.Submarines is type Depth_Type is new Integer range 0..1000; type Submarine is new Ship with private; -- extension procedure Change_Depth (Sub : in out Submarine;--new operation D : in Depth_Type); procedure Deploy_Weapon(Sub : in Submarine); -- override operation private type Submarine is new Ship with record Depth : Depth_Type; -- new component end record; end Vehicles.Ships.Submarines; --------------------------------------------------------------------- |
In each of the dispatching operations declared in the above code, there is one controlling parameter. This is the parameter that determines which version of the overloaded operation will be called. In this case it is the V parameter in the Change_Heading and Deploy_Weapon procedures.
Related Topics
4.12 Derived Types |
[ Back to top of page
]