3.9.3 Abstract Types and Subprograms
1/2
An
abstract type is a tagged type intended for use as an ancestor
of other types, but which is not allowed to have objects of its own.
An
abstract subprogram
is a subprogram that has no body, but is intended to be overridden at
some point when inherited. Because objects of an abstract type cannot
be created, a dispatching call to an abstract subprogram always dispatches
to some overriding body.
Syntax
1.1/3
Static Semantics
1.2/2
Interface
types (see
3.9.4) are abstract types. In
addition, a tagged type that has the reserved word
abstract in
its declaration is an abstract type. The class-wide type (see
3.4.1)
rooted at an abstract type is not itself an abstract type.
Legality Rules
2/2
Only a tagged type shall have the reserved word abstract
in its declaration.
3/2
4/3
If a type has an implicitly
declared primitive subprogram that is inherited or is a predefined operator,
and the corresponding primitive subprogram of the parent or ancestor
type is abstract or is a function with a controlling access result, or
if a type other than a nonabstract null extension inherits a function
with a controlling result, then:
5/2
If the type is abstract or untagged, the implicitly
declared subprogram is abstract.
6/2
Otherwise, the subprogram shall be overridden with
a nonabstract subprogram or, in the case of a private extension inheriting
a function with a controlling result, have a full type that is a null
extension; for a type declared in the visible part of a package, the
overriding may be either in the visible or the private part. Such a subprogram
is said to
require overriding.
However, if
the type is a generic formal type, the subprogram need not be overridden
for the formal type itself; a nonabstract version will necessarily be
provided by the actual type.
7
A call on an abstract subprogram shall be a dispatching
call; nondispatching calls to an abstract subprogram are not allowed.
8/3
The type of an
aggregate,
or of an object created by an
object_declaration
or an
allocator,
or a generic formal object of mode
in, shall not be abstract.
The type of the target of an assignment operation (see
5.2)
shall not be abstract. The type of a component shall not be abstract.
If the result type of a function is abstract, then the function shall
be abstract. If a function has an access result type designating an abstract
type, then the function shall be abstract. The type denoted by a
return_subtype_indication
(see
6.5) shall not be abstract. A generic
function shall not have an abstract result type or an access result type
designating an abstract type.
9
If a partial view is not abstract, the corresponding
full view shall not be abstract. If a generic formal type is abstract,
then for each primitive subprogram of the formal that is not abstract,
the corresponding primitive subprogram of the actual shall not be abstract.
10/3
For an abstract type declared in a visible part,
an abstract primitive subprogram shall not be declared in the private
part, unless it is overriding an abstract subprogram implicitly declared
in the visible part. For a tagged type declared in a visible part, a
primitive function with a controlling result or a controlling access
result shall not be declared in the private part, unless it is overriding
a function implicitly declared in the visible part.
11/2
Dynamic Semantics
11.1/2
12
79 Abstractness is not inherited; to declare
an abstract type, the reserved word abstract has to be used in
the declaration of the type extension.
13
80 A class-wide type is never abstract.
Even if a class is rooted at an abstract type, the class-wide type for
the class is not abstract, and an object of the class-wide type can be
created; the tag of such an object will identify some nonabstract type
in the class.
Examples
14
Example of an abstract
type representing a set of natural numbers:
15
package Sets is
subtype Element_Type is Natural;
type Set is abstract tagged null record;
function Empty return Set is abstract;
function Union(Left, Right : Set) return Set is abstract;
function Intersection(Left, Right : Set) return Set is abstract;
function Unit_Set(Element : Element_Type) return Set is abstract;
procedure Take(Element : out Element_Type;
From : in out Set) is abstract;
end Sets;
16
81 Notes on the example: Given the
above abstract type, one could then derive various (nonabstract) extensions
of the type, representing alternative implementations of a set. One might
use a bit vector, but impose an upper bound on the largest element representable,
while another might use a hash table, trading off space for flexibility.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe