Go to the first, previous, next, last section, table of contents.
-
A derived_type_definition defines a new type (and its first subtype)
whose characteristics are derived from those of a parent type.
Syntax
-
derived_type_definition ::= [abstract] new
parent_subtype_indication [record_extension_part]
Legality Rules
-
The parent_subtype_indication defines the parent subtype; its type is
the parent type.
-
A type shall be completely defined, See section 3.11.1 Completions of Declarations, 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.
-
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.
Static Semantics
-
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.
-
The characteristics of the derived type are defined as follows:
-
Each class of types that includes the parent type also includes the
derived type.
-
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.
-
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:
-
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;
-
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;
-
Each component declared in a record_extension_part, if any.
-
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.
-
The derived type is limited if and only if the parent type is limited.
-
For each predefined operator of the parent type, there is a
corresponding predefined operator of the derived type.
-
For each user-defined primitive subprogram (other than a user-defined
equality operator -- see below) of the parent 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 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 section 4.5.2 Relational Operators and Membership Tests.
-
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 type, after systematic
replacement of each subtype of its profile, See section 6.1 Subprogram Declarations, that is of the
parent type with a corresponding subtype of the derived type. For a
given subtype of the parent type, the corresponding subtype of the
derived type is defined as follows:
-
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.
-
If the derived type is a record extension, then the corresponding
subtype is the first subtype of the derived type.
-
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 section 4.6 Type Conversions.
-
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 type by the derived type is handled as part of
the normal type conversion associated with parameter passing --
See section 6.4.1 Parameter Associations.
-
If a primitive subprogram of the parent 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 See section 7.3.1 Private Operations.
-
A derived type can also be defined by a private_extension_declaration,
See section 7.3 Private Types and Private Extensions, or a formal_derived_type_definition, See section 12.5.1 Formal Private and Derived Types. Such a
derived type is a partial view of the corresponding full or actual type.
-
All numeric types are derived types, in that they are implicitly derived
from a corresponding root numeric type (See section 3.5.4 Integer Types, and See section 3.5.6 Real Types.
Dynamic Semantics
-
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.
-
For the execution of a call on an inherited subprogram, a call on the
corresponding primitive subprogram of the parent type is performed; the
normal conversion of each actual parameter to the subtype of the
corresponding formal parameter, See section 6.4.1 Parameter Associations performs any necessary type
conversion as well. If the result type of the inherited subprogram is
the derived type, the result of calling the parent's subprogram is
converted to the derived type.
NOTES
-
(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.
-
(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.
-
(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.
-
(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 section 3.10 Access Types.
-
(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 section 4.5.2 Relational Operators and Membership Tests. If the parent type is an integer type, the right
operand of the predefined exponentiation operator is of the predefined
type Integer, See section 4.5.6 Highest Precedence Operators.
-
(15) Any discriminants of the parent type are either all inherited, or
completely replaced with a new set of discriminants.
-
(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.
-
(17) If the reserved word abstract is given in the declaration of a
type, the type is abstract, See section 3.9.3 Abstract Types and Subprograms.
Examples
-
Examples of derived type declarations:
-
type Local_Coordinate is new Coordinate; -- two different types
type Midweek is new Day range Tue .. Thu; -- See section 3.5.1 Enumeration Types
type Counter is new Positive; -- same range as Positive
-
type Special_Key is new Key_Manager.Key; -- See section 7.3.1 Private Operations
-- the inherited subprograms have the following specifications:
-- procedure Get_Key(K : out Special_Key);
-- function "<"(X,Y : Special_Key) return Boolean;
- 3.4.1: Derivation Classes
Go to the first, previous, next, last section, table of contents.