File: AA-3-9-3.html

package info (click to toggle)
ada-reference-manual 20021112web-3
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, lenny, sarge
  • size: 18,652 kB
  • ctags: 8,921
  • sloc: makefile: 52; sh: 20
file content (364 lines) | stat: -rw-r--r-- 26,904 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
    <TITLE>AARM95 - Abstract Types and Subprograms</TITLE>
    <META NAME="Author" CONTENT="JTC1/SC22/WG9/ARG, by Randall Brukardt, ARG Editor">
    <META NAME="GENERATOR" CONTENT="Arm_Form.Exe, Ada Reference Manual generator">
    <STYLE type="text/css">
    DIV.paranum {position: absolute; font-family: Arial, Helvetica, sans-serif; left: 0.5 em; top: auto}
    TT {font-family: "Courier New", monospace}
    DT {display: compact}
    DIV.Normal {font-family: "Times New Roman", Times, serif; margin-bottom: 0.6em}
    DIV.Wide {font-family: "Times New Roman", Times, serif; margin-top: 0.6em; margin-bottom: 0.6em}
    DIV.Annotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
    DIV.WideAnnotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0.6em; margin-bottom: 0.6em}
    DIV.Index {font-family: "Times New Roman", Times, serif}
    DIV.SyntaxSummary {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
    DIV.Notes {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.6em}
    DIV.NotesHeader {font-family: "Times New Roman", Times, serif; margin-left: 2.0em}
    DIV.SyntaxIndented {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
    DIV.Indented {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-bottom: 0.6em}
    DIV.CodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
    DIV.SmallIndented {font-family: "Times New Roman", Times, serif; margin-left:  10.0em; margin-bottom: 0.6em}
    DIV.SmallCodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-bottom: 0.6em}
    DIV.Examples {font-family: "Courier New", monospace; margin-left: 2.0em; margin-bottom: 0.6em}
    DIV.SmallExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left: 7.5em; margin-bottom: 0.6em}
    DIV.IndentedExamples {font-family: "Courier New", monospace; margin-left: 8.0em; margin-bottom: 0.6em}
    DIV.SmallIndentedExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left:  15.0em; margin-bottom: 0.6em}
    UL.Bulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.SmallBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.NestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.SmallNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.IndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.CodeIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.CodeIndentedNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.SyntaxIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.NotesBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.NotesNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
    DL.Hanging {font-family: "Times New Roman", Times, serif; margin-top: 0em; margin-bottom: 0.6em}
    DD.Hanging {margin-left: 6.0em}
    DL.IndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
    DD.IndentedHanging {margin-left: 2.0em}
    DL.HangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
    DD.HangingInBulleted {margin-left: 4.0em}
    DL.SmallHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
    DD.SmallHanging {margin-left: 7.5em}
    DL.SmallIndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-top: 0em; margin-bottom: 0.6em}
    DD.SmallIndentedHanging {margin-left: 2.0em}
    DL.SmallHangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
    DD.SmallHangingInBulleted {margin-left: 5.0em}
    DL.Enumerated {font-family: "Times New Roman", Times, serif; margin-right: 0.0em; margin-top: 0em; margin-bottom: 0.5em}
    DD.Enumerated {margin-left: 2.0em}
    DL.SmallEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
    DD.SmallEnumerated {margin-left: 2.5em}
    DL.NestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
    DL.SmallNestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
    </STYLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFF0" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
<P><A HREF="AA-TOC.html">Contents</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-0-29.html">Index</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-3-9-2.html">Previous</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-3-10.html">Next</A></P>
<HR>
<H1> 3.9.3 Abstract Types and Subprograms</H1>
<DIV Class="Paranum"><FONT SIZE=-2>1</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;[<A NAME="I2120"></A> <A NAME="I2121"></A><A NAME="I2122"></A><A NAME="I2123"></A>An
<I>abstract type</I> is a tagged type intended for use as a parent type
for type extensions, but which is not allowed to have objects of its
own. <A NAME="I2124"></A><A NAME="I2125"></A>An <I>abstract subprogram</I>
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.] </DIV>

<H4 ALIGN=CENTER>Language Design Principles</H4>
<DIV Class="Paranum"><FONT SIZE=-2>1.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>An abstract subprogram has no
body, so the rules in this clause are designed to ensure (at compile
time) that the body will never be invoked. We do so primarily by disallowing
the creation of values of the abstract type. Therefore, since type conversion
and parameter passing don't change the tag, we know we will never get
a class-wide value with a tag identifying an abstract type. This means
that we only have to disallow nondispatching calls on abstract subprograms
(dispatching calls will never reach them). </FONT></DIV>

<H4 ALIGN=CENTER>Legality Rules</H4>
<DIV Class="Paranum"><FONT SIZE=-2>2</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;<A NAME="I2126"></A><A NAME="I2127"></A>An <I>abstract
type</I> is a specific type that has the reserved word <B>abstract</B>
in its declaration. Only a tagged type is allowed to be declared abstract.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>2.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>Untagged
types are never abstract, even though they can have primitive abstract
subprograms. Such subprograms cannot be called, unless they also happen
to be dispatching operations of some tagged type, and then only via a
dispatching call.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>2.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>Class-wide types are never abstract.
If T is abstract, then it is illegal to declare a stand-alone object
of type T, but it is OK to declare a stand-alone object of type T'Class;
the latter will get a tag from its initial value, and this tag will necessarily
be different from T'Tag. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;<A NAME="I2128"></A><A NAME="I2129"></A>A subprogram
declared by an <FONT FACE="Arial, Helvetica">abstract_subprogram_declaration</FONT>
(see <A HREF="AA-6-1.html">6.1</A>) is an <I>abstract subprogram</I>.
If it is a primitive subprogram of a tagged type, then the tagged type
shall be abstract. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3.a</FONT></DIV>
<DIV Class="Annotations" Style="margin-bottom: 0.4em"><FONT SIZE=-1><B>Ramification:
</B>Note that for a private type, this applies to both views. The following
is illegal: </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3.b</FONT></DIV>
<DIV Class="SmallExamples"><TT><B>package</B>&nbsp;P&nbsp;<B>is</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;T&nbsp;<B>is</B>&nbsp;<B>abstract</B>&nbsp;<B>tagged</B>&nbsp;<B>private</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>function</B>&nbsp;Foo&nbsp;(X&nbsp;:&nbsp;T)&nbsp;<B>return</B>&nbsp;Boolean&nbsp;<B>is</B>&nbsp;<B>abstract</B>;&nbsp;--<I>&nbsp;Illegal!</I><BR>
<B>private</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;T&nbsp;<B>is</B>&nbsp;<B>tagged</B>&nbsp;<B>null</B>&nbsp;<B>record</B>;&nbsp;--<I>&nbsp;Illegal!</I><BR>
&nbsp;&nbsp;&nbsp;&nbsp;X&nbsp;:&nbsp;T;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;Y&nbsp;:&nbsp;Boolean&nbsp;:=&nbsp;Foo&nbsp;(T'Class&nbsp;(X));<BR>
<B>end</B>&nbsp;P;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3.c</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The full view of T is not abstract,
but has an abstract operation Foo, which is illegal. The two lines marked
&quot;--<I> Illegal!</I>&quot; are illegal when taken together.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3.d</FONT></DIV>
<DIV Class="Annotations" Style="margin-bottom: 0.4em"><FONT SIZE=-1><B>Reason:
</B>We considered disallowing untagged types from having abstract primitive
subprograms. However, we rejected that plan, because it introduced some
silly anomalies, and because such subprograms are harmless (if not terribly
useful). For example: </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3.e/1</FONT></DIV>
<DIV Class="SmallExamples"><TT><B>package</B>&nbsp;P&nbsp;<B>is</B><BR>
&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;Field_Size&nbsp;<B>is</B>&nbsp;<B>range</B>&nbsp;0..100;<BR>
&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;T&nbsp;<B>is</B>&nbsp;<B>abstract&nbsp;tagged</B>&nbsp;<B>null</B>&nbsp;<B>record</B>;<BR>
&nbsp;&nbsp;&nbsp;<B>procedure</B>&nbsp;Print(X&nbsp;:&nbsp;<B>in</B>&nbsp;T;&nbsp;F&nbsp;:&nbsp;<B>in</B>&nbsp;Field_Size&nbsp;:=&nbsp;0)&nbsp;<B>is</B>&nbsp;<U><B>abstract</B></U><S>abstract</S>;<BR>
&nbsp;&nbsp;.&nbsp;.&nbsp;.<BR>
<B>package</B>&nbsp;Q&nbsp;<B>is</B><BR>
&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;My_Field_Size&nbsp;<B>is</B>&nbsp;<B>new</B>&nbsp;Field_Size;<BR>
&nbsp;&nbsp;&nbsp;--<I>&nbsp;implicit&nbsp;declaration&nbsp;of&nbsp;Print(X&nbsp;:&nbsp;T;&nbsp;F&nbsp;:&nbsp;My_Field_Size&nbsp;:=&nbsp;0)&nbsp;<U><B>is&nbsp;abstract</B></U><S>is&nbsp;abstract</S>;</I><BR>
<B>end</B>&nbsp;Q;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3.f</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>It seemed silly to make the derivative
of My_Field_Size illegal, just because there was an implicitly declared
abstract subprogram that was not primitive on some tagged type. Other
rules could be formulated to solve this problem, but the current ones
seem like the simplest. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>4</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em">&nbsp;&nbsp;&nbsp;For a derived type,
if the parent or ancestor type has an abstract primitive subprogram,
or a primitive function with a controlling result, then: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>5</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>If the derived type is abstract or untagged, the inherited
subprogram is <I>abstract</I>. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>5.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>Note that
it is possible to override a concrete subprogram with an abstract one.
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>Otherwise, the subprogram shall be overridden with a nonabstract
subprogram; [for a type declared in the visible part of a package, the
overriding may be either in the visible or the private part.] 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.] </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>6.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>A function that
returns the parent type becomes abstract for an abstract type extension
(if not overridden) because conversion from a parent type to a type extension
is not defined, and function return semantics is defined in terms of
conversion. (Note that parameters of mode <B>in out</B> or <B>out</B>
do not have this problem, because the tag of the actual is not changed.)</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6.b</FONT></DIV>
<DIV Class="Annotations" Style="margin-bottom: 0.4em"><FONT SIZE=-1>Note
that the overriding required above can be in the private part, which
allows the following: </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6.c</FONT></DIV>
<DIV Class="SmallExamples"><TT><B>package</B>&nbsp;Pack1&nbsp;<B>is</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;Ancestor&nbsp;<B>is</B>&nbsp;<B>abstract</B>&nbsp;...;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>procedure</B>&nbsp;Do_Something(X&nbsp;:&nbsp;<B>in</B>&nbsp;Ancestor)&nbsp;<B>is</B>&nbsp;<B>abstract</B>;<BR>
<B>end</B>&nbsp;Pack1;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6.d</FONT></DIV>
<DIV Class="SmallExamples"><TT><B>with</B>&nbsp;Pack1;&nbsp;<B>use</B>&nbsp;Pack1;<BR>
<B>package</B>&nbsp;Pack2&nbsp;<B>is</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;T1&nbsp;<B>is</B>&nbsp;<B>new</B>&nbsp;Ancestor&nbsp;<B>with</B>&nbsp;<B>record</B>&nbsp;...;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--<I>&nbsp;A&nbsp;concrete&nbsp;type.</I><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>procedure</B>&nbsp;Do_Something(X&nbsp;:&nbsp;<B>in</B>&nbsp;T1);&nbsp;--<I>&nbsp;Have&nbsp;to&nbsp;override.</I><BR>
<B>end</B>&nbsp;Pack2;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6.e</FONT></DIV>
<DIV Class="SmallExamples"><TT><B>with</B>&nbsp;Pack1;&nbsp;<B>use</B>&nbsp;Pack1;<BR>
<B>with</B>&nbsp;Pack2;&nbsp;<B>use</B>&nbsp;Pack2;<BR>
<B>package</B>&nbsp;Pack3&nbsp;<B>is</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;T2&nbsp;<B>is</B>&nbsp;<B>new</B>&nbsp;Ancestor&nbsp;<B>with</B>&nbsp;<B>private</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--<I>&nbsp;A&nbsp;concrete&nbsp;type.</I><BR>
<B>private</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;T2&nbsp;<B>is</B>&nbsp;<B>new</B>&nbsp;T1&nbsp;<B>with</B>&nbsp;--<I>&nbsp;Parent&nbsp;different&nbsp;from&nbsp;ancestor.</I><BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>record</B>&nbsp;...&nbsp;<B>end</B>&nbsp;<B>record</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;--<I>&nbsp;Here,&nbsp;we&nbsp;inherit&nbsp;Pack2.Do_Something.</I><BR>
<B>end</B>&nbsp;Pack3;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6.f/1</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>T2 inherits an abstract Do_Something,
but T<U>2</U> is not abstract, so Do_Something has to be overridden.
However, it is OK to override it in the private part. In this case, we
override it by inheriting a concrete version from a different type. Nondispatching
calls to Pack3.Do_Something are allowed both inside and outside package
Pack3. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>7</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;A call on an abstract subprogram shall be a dispatching
call; [nondispatching calls to an abstract subprogram are not allowed.]
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>7.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>If an abstract
subprogram is not a dispatching operation of some tagged type, then it
cannot be called at all. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;The type of an <FONT FACE="Arial, Helvetica">aggregate</FONT>,
or of an object created by an <FONT FACE="Arial, Helvetica">object_declaration</FONT>
or an <FONT FACE="Arial, Helvetica">allocator</FONT>, or a generic formal
object of mode <B>in</B>, shall not be abstract. The type of the target
of an assignment operation (see <A HREF="AA-5-2.html">5.2</A>) 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.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>This ensures that
values of an abstract type cannot be created, which ensures that a dispatching
call to an abstract subprogram will not try to execute the nonexistent
body.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>Generic formal objects of mode
<B>in</B> are like constants; therefore they should be forbidden for
abstract types. Generic formal objects of mode <B>in out</B> are like
renamings; therefore, abstract types are OK for them, though probably
not terribly useful. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;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.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Discussion: </B>By contrast,
we allow the actual type to be nonabstract even if the formal type is
declared abstract. Hence, the most general formal tagged type possible
is &quot;<B>type</B> T(&lt;&gt;) <B>is abstract tagged limited private</B>;&quot;.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>For an abstract private extension
declared in the visible part of a package, it is only possible for the
full type to be nonabstract if the private extension has no abstract
dispatching operations. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;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 shall not be declared in
the private part, unless it is overriding a function implicitly declared
in the visible part. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10.a</FONT></DIV>
<DIV Class="Annotations" Style="margin-bottom: 0.4em"><FONT SIZE=-1><B>Reason:
</B>The ``visible part'' could be that of a package or a generic package.
This rule is needed because a non-abstract type extension declared outside
the package would not know about any abstract primitive subprograms or
primitive functions with controlling results declared in the private
part, and wouldn't know that they need to be overridden with non-abstract
subprograms. The rule applies to a tagged record type or record extension
declared in a visible part, just as to a tagged private type or private
extension. The rule applies to explicitly and implicitly declared abstract
subprograms: </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10.b</FONT></DIV>
<DIV Class="SmallExamples"><TT><B>package</B>&nbsp;Pack&nbsp;<B>is</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;T&nbsp;<B>is</B>&nbsp;<B>abstract</B>&nbsp;<B>new</B>&nbsp;T1&nbsp;<B>with</B>&nbsp;<B>private</B>;<BR>
<B>private</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;T&nbsp;<B>is</B>&nbsp;<B>abstract</B>&nbsp;<B>new</B>&nbsp;T2&nbsp;<B>with</B>&nbsp;<B>record</B>&nbsp;...&nbsp;<B>end</B>&nbsp;<B>record</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;...<BR>
<B>end</B>&nbsp;Pack;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10.c</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The above example would be illegal
if T1 has a non-abstract primitive procedure P, but T2 overrides P with
an abstract one; the private part should override P with a non-abstract
version. On the other hand, if the P were abstract for both T1 and T2,
the example would be legal as is. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;A generic actual subprogram shall not be an abstract
subprogram. The <FONT FACE="Arial, Helvetica">prefix</FONT> of an <FONT FACE="Arial, Helvetica">attribute_reference</FONT>
for the Access, Unchecked_Access, or Address attributes shall not denote
an abstract subprogram. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>An <FONT FACE="Arial, Helvetica">abstract_subprogram_declaration</FONT>
is not syntactically a <FONT FACE="Arial, Helvetica">subprogram_declaration</FONT>.
Nonetheless, an abstract subprogram is a subprogram, and an <FONT FACE="Arial, Helvetica">abstract_subprogram_declaration</FONT>
is a declaration of a subprogram.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The part about generic actual
subprograms includes those given by default. </FONT></DIV>
<DIV Class="NotesHeader"><FONT SIZE=-1>NOTES</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>12</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>74&nbsp;&nbsp;Abstractness is not inherited;
to declare an abstract type, the reserved word <B>abstract</B> has to
be used in the declaration of the type extension. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>12.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>A derived
type can be abstract even if its parent is not. Similarly, an inherited
concrete subprogram can be overridden with an abstract subprogram. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>13</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>75&nbsp;&nbsp;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. </FONT></DIV>

<H4 ALIGN=CENTER>Examples</H4>
<DIV Class="Paranum"><FONT SIZE=-2>14</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em">&nbsp;&nbsp;&nbsp;&nbsp;<I>Example of an
abstract type representing a set of natural numbers:</I> </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>15</FONT></DIV>
<DIV Class="Examples"><TT><B>package</B>&nbsp;Sets&nbsp;<B>is</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>subtype</B>&nbsp;Element_Type&nbsp;<B>is</B>&nbsp;Natural;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;Set&nbsp;<B>is&nbsp;abstract&nbsp;tagged&nbsp;null&nbsp;record</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>function</B>&nbsp;Empty&nbsp;<B>return</B>&nbsp;Set&nbsp;<B>is&nbsp;abstract</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>function</B>&nbsp;Union(Left,&nbsp;Right&nbsp;:&nbsp;Set)&nbsp;<B>return</B>&nbsp;Set&nbsp;<B>is&nbsp;abstract</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>function</B>&nbsp;Intersection(Left,&nbsp;Right&nbsp;:&nbsp;Set)&nbsp;<B>return</B>&nbsp;Set&nbsp;<B>is&nbsp;abstract</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>function</B>&nbsp;Unit_Set(Element&nbsp;:&nbsp;Element_Type)&nbsp;<B>return</B>&nbsp;Set&nbsp;<B>is&nbsp;abstract</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>procedure</B>&nbsp;Take(Element&nbsp;:&nbsp;<B>out</B>&nbsp;Element_Type;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;From&nbsp;:&nbsp;<B>in&nbsp;out</B>&nbsp;Set)&nbsp;<B>is&nbsp;abstract</B>;<BR>
<B>end</B>&nbsp;Sets;</TT></DIV>
<DIV Class="NotesHeader"><FONT SIZE=-1>NOTES</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>16</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>76&nbsp;&nbsp;<I>Notes on the example:</I>
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. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>16.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Discussion: </B>One way to
export a type from a package with some components visible and some components
private is as follows: </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>16.b</FONT></DIV>
<DIV Class="SmallExamples"><TT><B>package</B>&nbsp;P&nbsp;<B>is</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;Public_Part&nbsp;<B>is</B>&nbsp;<B>abstract</B>&nbsp;<B>tagged</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>record</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>end</B>&nbsp;<B>record</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;T&nbsp;<B>is</B>&nbsp;<B>new</B>&nbsp;Public_Part&nbsp;<B>with</B>&nbsp;<B>private</B>;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;...<BR>
<B>private</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;T&nbsp;<B>is</B>&nbsp;<B>new</B>&nbsp;Public_Part&nbsp;<B>with</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>record</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>end</B>&nbsp;<B>record</B>;<BR>
<B>end</B>&nbsp;P;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>16.c</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The fact that Public_Part is abstract
tells clients they have to create objects of type T instead of Public_Part.
Note that the public part has to come first; it would be illegal to declare
a private type Private_Part, and then a record extension T of it, unless
T were in the private part after the full declaration of Private_Part,
but then clients of the package would not have visibility to T. </FONT></DIV>

<HR>
<P><A HREF="AA-TOC.html">Contents</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-0-29.html">Index</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-3-9-2.html">Previous</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-3-10.html">Next</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-TTL.html">Legal</A></P>
</BODY>
</HTML>