Contents Index Search Related Documents Previous Next
3.4 Derived Types and Classes
1/2
A
derived_type_definition
defines a
derived type (and its first subtype) whose characteristics
are
derived from those of a parent type, and possibly from progenitor
types.
Syntax
2/2
derived_type_definition
::=
[
abstract] [
limited]
new parent_subtype_indication [[
and interface_list]
record_extension_part]
Legality Rules
3/2
The
parent_subtype_indication
defines the
parent subtype; its type is the
parent type.
The
interface_list defines the progenitor
types (see
3.9.4). A derived type has one
parent type and zero or more progenitor types.
4
A type shall be completely defined (see
3.11.1)
prior to being specified as the parent type in a
derived_type_definition
— the
full_type_declarations
for the parent type and any of its subcomponents have to precede the
derived_type_definition.
5/2
If there is a
record_extension_part,
the derived type is called a
record extension of the parent type.
A
record_extension_part shall be
provided if and only if the parent type is a tagged type. An
interface_list
shall be provided only if the parent type is a tagged type.
5.1/2
If the reserved word limited appears
in a derived_type_definition, the
parent type shall be a limited type.
Static Semantics
6
The first
subtype of the derived type is unconstrained if a
known_discriminant_part
is provided in the declaration of the derived type, or if the parent
subtype is unconstrained.
Otherwise, the constraint
of the first subtype
corresponds to that of the parent subtype
in the following sense: it is the same as that of the parent subtype
except that for a range constraint (implicit or explicit), the value
of each bound of its range is replaced by the corresponding value of
the derived type.
6.1/2
The first subtype of the derived type excludes
null (see
3.10) if and only if the parent
subtype excludes null.
7
The characteristics
of the derived type are defined as follows:
8/2
- Each class of types that includes
the parent type or a progenitor type also includes the derived type.
9
- If the parent type is an elementary
type or an array type, then the set of possible values of the derived
type is a copy of the set of possible values of the parent type. For
a scalar type, the base range of the derived type is the same as that
of the parent type.
10
- If the parent type is a composite
type other than an array type, then the components, protected subprograms,
and entries that are declared for the derived type are as follows:
11
- The discriminants specified
by a new known_discriminant_part,
if there is one; otherwise, each discriminant of the parent type (implicitly
declared in the same order with the same specifications) — in
the latter case, the discriminants are said to be inherited, or
if unknown in the parent, are also unknown in the derived type;
12
- Each nondiscriminant component,
entry, and protected subprogram of the parent type, implicitly declared
in the same order with the same declarations; these
components, entries, and protected subprograms are said to be inherited;
13
- Each component declared in a
record_extension_part, if any.
14
Declarations of components, protected subprograms,
and entries, whether implicit or explicit, occur immediately within the
declarative region of the type, in the order indicated above, following
the parent subtype_indication.
15/2
- This paragraph
was deleted..
16
- For each predefined operator of the
parent type, there is a corresponding predefined operator of the derived
type.
17/2
- For each user-defined
primitive subprogram (other than a user-defined equality operator —
see below) of the parent type or of a progenitor type that already exists
at the place of the derived_type_definition,
there exists a corresponding inherited primitive subprogram of
the derived type with the same defining name. Primitive
user-defined equality operators of the parent type and any progenitor
types are also inherited by the derived type, except when the derived
type is a nonlimited record extension, and the inherited operator would
have a profile that is type conformant with the profile of the corresponding
predefined equality operator; in this case, the user-defined equality
operator is not inherited, but is rather incorporated into the implementation
of the predefined equality operator of the record extension (see 4.5.2).
18/2
The profile of an inherited subprogram (including
an inherited enumeration literal) is obtained from the profile of the
corresponding (user-defined) primitive subprogram of the parent or progenitor
type, after systematic replacement of each subtype of its profile (see
6.1) that is of the parent or progenitor type
with a corresponding subtype of the derived type. For
a given subtype of the parent or progenitor type, the corresponding subtype
of the derived type is defined as follows:
19
- If the declaration of the derived
type has neither a known_discriminant_part
nor a record_extension_part, then
the corresponding subtype has a constraint that corresponds (as defined
above for the first subtype of the derived type) to that of the given
subtype.
20
- If the derived type is a record
extension, then the corresponding subtype is the first subtype of the
derived type.
21
- If the derived type has a new
known_discriminant_part but is not
a record extension, then the corresponding subtype is constrained to
those values that when converted to the parent type belong to the given
subtype (see 4.6).
22/2
The same formal parameters have default_expressions
in the profile of the inherited subprogram. Any type mismatch due to
the systematic replacement of the parent or progenitor type by the derived
type is handled as part of the normal type conversion associated with
parameter passing — see 6.4.1.
23/2
If a primitive subprogram of the parent or
progenitor type is visible at the place of the
derived_type_definition,
then the corresponding inherited subprogram is implicitly declared immediately
after the
derived_type_definition.
Otherwise, the inherited subprogram is implicitly declared later or not
at all, as explained in
7.3.1.
24
A derived type can also be
defined by a
private_extension_declaration
(see
7.3) or a
formal_derived_type_definition
(see
12.5.1). Such a derived type is a partial
view of the corresponding full or actual type.
25
All numeric types are derived types, in that
they are implicitly derived from a corresponding root numeric type (see
3.5.4 and
3.5.6).
Dynamic Semantics
26
The elaboration of a
derived_type_definition
creates the derived type and its first subtype, and consists of the elaboration
of the
subtype_indication and the
record_extension_part, if any. If
the
subtype_indication depends on
a discriminant, then only those expressions that do not depend on a discriminant
are evaluated.
27/2
For the execution of a
call on an inherited subprogram, a call on the corresponding primitive
subprogram of the parent or progenitor type is performed; the normal
conversion of each actual parameter to the subtype of the corresponding
formal parameter (see
6.4.1) performs any
necessary type conversion as well. If the result type of the inherited
subprogram is the derived type, the result of calling the subprogram
of the parent or progenitor is converted to the derived type, or in the
case of a null extension, extended to the derived type using the equivalent
of an
extension_aggregate with the
original result as the
ancestor_part
and
null record as the
record_component_association_list.
28
10 Classes
are closed under derivation — any class that contains a type also
contains its derivatives. Operations available for a given class of types
are available for the derived types in that class.
29
11 Evaluating an inherited
enumeration literal is equivalent to evaluating the corresponding enumeration
literal of the parent type, and then converting the result to the derived
type. This follows from their equivalence to parameterless functions.
30
12 A generic subprogram
is not a subprogram, and hence cannot be a primitive subprogram and cannot
be inherited by a derived type. On the other hand, an instance of a generic
subprogram can be a primitive subprogram, and hence can be inherited.
31
13 If the parent type is
an access type, then the parent and the derived type share the same storage
pool; there is a null access value for the derived type and it
is the implicit initial value for the type. See 3.10.
32
14 If the parent type is
a boolean type, the predefined relational operators of the derived type
deliver a result of the predefined type Boolean (see 4.5.2).
If the parent type is an integer type, the right operand of the predefined
exponentiation operator is of the predefined type Integer (see 4.5.6).
33
15 Any discriminants of
the parent type are either all inherited, or completely replaced with
a new set of discriminants.
34
16 For an inherited subprogram,
the subtype of a formal parameter of the derived type need not have any
value in common with the first subtype of the derived type.
35
17 If the reserved word
abstract is given in the declaration of a type, the type is abstract
(see 3.9.3).
35.1/2
18 An interface type which
has a progenitor type “is derived from” that type. A derived_type_definition,
however, never defines an interface type.
35.2/2
19 It is illegal for the
parent type of a derived_type_definition
to be a synchronized tagged type.
Examples
36
Examples of
derived type declarations:
37
type Local_Coordinate is new Coordinate; -- two different types
type Midweek is new Day range Tue .. Thu; -- see 3.5.1
type Counter is new Positive; -- same range as Positive
38
type Special_Key is new Key_Manager.Key; -- see 7.3.1
-- the inherited subprograms have the following specifications:
-- procedure Get_Key(K : out Special_Key);
-- function "<"(X,Y : Special_Key) return Boolean;
Contents Index Search Related Documents Previous Next Legal