home *** CD-ROM | disk | FTP | other *** search
/ Solo Programadores 22 / SOLO_22.iso / docs / lovelace / lesson7.les < prev    next >
Encoding:
Text File  |  1995-12-08  |  27.0 KB  |  726 lines

  1. <COMMENT This is a lesson file for the Lovelace Ada tutorial>
  2. <COMMENT A program called genlesson is used to transform this file into a set>
  3. <COMMENT of useful HTML files for use by Mosaic & other WWW browsers.>
  4.  
  5. <TUTOR NAME="Lovelace">
  6. <LESSON NUMBER=7>
  7. <AUTHOR NAME="David A. Wheeler" EMAIL="wheeler@ida.org">
  8. <AUTHOR ADDRESS="<A HREF="dwheeler.htm">David A. Wheeler (wheeler@ida.org)</A>">
  9.  
  10. <COMMENT $Id: lesson7.les,v 1.9 1995/05/17 21:25:18 wheeler Exp $ >
  11.  
  12. <COMMENT  <NEXT_LESSON LOCATION="URL_of_directory/" >
  13.  
  14. <COMMENT A lesson is divided into 1 or more "sections".>
  15. <COMMENT Each section has a title; SECTION starts a new section.>
  16.  
  17. <SECTION NAME="Object-Oriented Programming: Overview">
  18. A major new capability of Ada 95 is the addition of direct support for
  19. object-oriented (OO) programming.
  20. Ada has always strongly supported a related approach to software development
  21. called the ``object-based'' approach.
  22. It's important to understand the basics of the OO approach
  23. before learning how Ada now supports OO programming, so this
  24. section provides a basic overview of the OO approach.
  25. If you already understand the OO approach well, feel free to skip to the
  26. next section.
  27. <P>
  28.  
  29. <H2>Functional Decomposition</H2>
  30. First, some history.
  31. Software development has always involved using approaches to
  32. manage complexity.
  33. One well-known approach is called ``functional decomposition.''
  34. In this approach, the program's ``function''
  35. is divided (decomposed) into smaller component functions.
  36. These smaller functions are broken into still smaller functions, and so on.
  37. For example, the function ``eat_lunch'' might be decomposed into the
  38. functions ``remove_packaging'', ``eat_food'', and ``throw_away_trash.''
  39. Functional decomposition can be easily implemented in Ada using subprograms.
  40. Functional decomposition is still a useful technique for some problems,
  41. but it does not work well if the structure of the data is complex.
  42. Thus, other approaches have been developed for systems with nontrivial
  43. data structures.
  44. <P>
  45.  
  46. <H2>Object-Based and Object-Oriented Approaches</H2>
  47. Two of these other approaches are strongly related to each other,
  48. and are called the
  49. ``object-oriented'' (OO) approach and the ``object-based''
  50. approach (the latter is also called the ``abstract data type'' approach).
  51. Both are approaches to managing software complexity that are quite
  52. different from functional decomposition.
  53. In both approaches, a system is described in terms of ``objects'';
  54. each object contains data and has a set of operations that can be
  55. performed on that data.
  56. Objects represent real or abstract things important
  57. to the problem being solved.
  58. The object's structure and its set of operations are defined by
  59. the object's type (also called a <EM>class</EM>).
  60. For example, we might create a type called a <EM>vehicle</EM> with
  61. a data element <EM>amount_of_fuel_left</EM> and
  62. operations <EM>refuel</EM> and <EM>drive_to(location)</EM>.
  63. We could then create two objects of type <EM>vehicle</EM>
  64. called my_vehicle and your_vehicle.
  65. Each vehicle would have its own amount_of_fuel_left, and each
  66. would respond to the operations refuel and drive_to(location).
  67. Ada has always supported this approach with its packages and types.
  68. <P>
  69.  
  70. The difference between the OO and object-based approaches is that
  71. the OO approach adds the concept of <EM>inheritance</EM>
  72. to mimic the way people normally think when they classify objects.
  73. Inheritance permits
  74. new types (also called classes) to be defined as extensions of other
  75. existing types, forming a hierarchy of type definitions.
  76. Inheritance represents the relation ``is a kind of''
  77. (as opposed to the relation ``is a part of'' or some other relation).
  78. To continue our example, we could create two new types called
  79. ``motorcycle'' and ``bus'' as kinds of vehicles.
  80. Thus bus and motorcycle would <EM>inherit</EM> from vehicle.
  81. Note that a type called ``wheel'' should generally
  82. <EM>not</EM> inherit from type vehicle; a wheel
  83. is a part of a vehicle, but a wheel (by itself) is not a vehicle.
  84. <P>
  85.  
  86. A type inherits all of the data structure and operations, so
  87. in our example a bus would also have a <EM>drive_to(location)</EM> operation.
  88. More importantly, once we create a new type,
  89. we can create additional operations that only apply to it, or
  90. redefine existing operations to perform special actions for this type.
  91. For example, we could add operations to a bus to allow it to
  92. <EM>accept_passengers</EM>, and this new operation would apply to
  93. buses, not to motorcycles or to all vehicles.
  94. We could also redefine the ``drive_to(location)'' operation of a bus
  95. so it would do something different with buses.
  96. <P>
  97.  
  98. OO programming is an approach to implementing software using the OO approach.
  99. Grady Booch [1994] defined OO programming this way:
  100. ``OO programming is a method of implementation in which programs
  101. are organized as cooperative collections of objects, each of which
  102. represents an instance of some class, and whose classes are all
  103. members of a hierarchy of classes united via inheritance relationships.''
  104. <P>
  105.  
  106. It is difficult to use OO and object-based
  107. techniques if the underlying programming
  108. language does not support certain capabilities well.
  109. In particular, OO techniques are difficult to use if the
  110. programming language used does not directly support
  111. inheritance (and a related concept called polymorphism or dynamic dispatching,
  112. which will be explained later).
  113. Ada was explicitly designed from the beginning
  114. to support an object-based approach, and
  115. in 1995 Ada was extended to support OO programming.
  116. <P>
  117.  
  118. <H2>Warning: Oversimplification</H2>
  119. It is important to understand that the discussion in this section
  120. is a vast oversimplification.
  121. In particular, defining the term ``object-oriented'' is not easy and has
  122. provoked a great deal of debate; I've chosen to use a ``classical
  123. languages'' kind of definition here.
  124. The document
  125. <A HREF="http://iamwww.unibe.ch/~scg/OOinfo/FAQ/">Object-Oriented
  126. Frequently Asked Questions (OO FAQ)</A> includes some discussion of
  127. various definitions and approaches along with various
  128. technical arguments about OO approaches and implementations.
  129. Note that Ada emphasizes the industrial needs for safety and efficiency,
  130. while some OO languages emphasize other
  131. virtues (such as linguistic power and simplicity)
  132. at the expense of safety and efficiency.
  133. The OO FAQ also includes a bibliography of textbooks for more information
  134. on OO approaches.
  135. <P>
  136.  
  137. The definition of ``functional decomposition'' given above is the
  138. usual approach when it is implemented in Fortran and Pascal, though
  139. again, definitions are not universally agreed upon.
  140. In particular, do not
  141. confuse this with ``functional programming languages'',
  142. which support an approach that is a very different extension of
  143. functional decomposition.
  144. There are other system decomposition approaches, such as logical programming,
  145. that are way beyond the scope of this tutorial.
  146. It can be argued that abstract data types and
  147. object-based approaches aren't identical;
  148. such arguments generally hinge on detailed definitions which have never
  149. had universal agreement.
  150.  
  151. <!-- ?? Someday, provide a short list of recommended OO textbooks? -->
  152. <!-- Or better yet, an on-line OO course. -->
  153.  
  154. <QUESTION Type=Multiple-Choice>
  155. Here are simplified descriptions of two different systems.
  156. Which one is described in a more OO manner?
  157. <P>
  158. <STRONG>System 1</STRONG>
  159. is an anti-missile system with 3 major types of components:
  160. a radar, a launcher, and a missile.
  161. A radar searches the portion of the sky defined
  162. by its area_of_search information.
  163. When a radar sees a target it sends a `target sighting' message
  164. to a launcher.
  165. When a launcher receives a `target sighting' message and that launcher's
  166. combat_state is `armed', it
  167. selects a missile to launch and sends that missile a launch command.
  168. A missile accepts a `launch command', which includes the launch time and
  169. the expected target location; it will then launch at the given time.
  170. There are two kinds of missiles, a long_range_missile and
  171. a short_range_missile.
  172. <P>
  173. <STRONG>System 2</STRONG> is a coin-operated soup dispenser.
  174. It accepts coins, then accepts a user's soup choice, and then dispenses soup.
  175. To accept coins it counts each coin's value until the total equals or
  176. exceeds the cost of a cup of soup.
  177. To accept a user's soup choice, the system waits for a selection
  178. button to be pressed.
  179. To dispense soup, it drops a cup into the
  180. user-accessible cup holder, dispenses the selected powdered soup into the
  181. cup, dispenses boiling water into the cup, and then stirs the soup.
  182. To stir the soup, a plastic stirrer is inserted into the cup,
  183. the stirrer is vigorously moved about inside the cup, and the stirrer
  184. is then removed.
  185. <P>
  186. Which system has been described in a more object-oriented manner?
  187. <CHOICES>
  188. <CHOICE ANS=1>System 1.
  189. <CHOICE ANS=2>System 2.
  190. </CHOICES>
  191. <ANSWER ANS=1>
  192. <RESPONSES>
  193. <WHEN ANS=1>
  194. Right.
  195. Did you notice the inheritance relationship implied at the end of
  196. system 1's description (both short_range_missile and long_range_missile
  197. inherit from missile)?
  198. <P>
  199. More importantly, notice
  200. that neither answer involved any code or
  201. a particular programming language!
  202. The object-oriented, object-based, and functional decomposition approaches
  203. are all approaches to managing system complexity, and
  204. are mainly tools for our minds to help deal with complexity.
  205. You can use any approach in thinking about a problem, however,
  206. it's easier to implement a solution if the programming
  207. language directly supports the approach you choose.
  208. <WHEN ANS=2>
  209. No, sorry.
  210. There are physical objects mentioned in system 2, but note that
  211. the `system' as a whole (as opposed to specific objects)
  212. performs all the activities.
  213. Note that the description focuses on the functions to be
  214. performed (not what does them) and it repeatedly decomposes
  215. the functions to be performed into more detailed functions to be performed.
  216. </RESPONSES>
  217. <SECTION NAME="Object-Oriented Programming in Ada: Inheritance">
  218. One of the major features of OO programming
  219. is its use of <EM>inheritance</EM>.
  220. In 1995 facilities were added to Ada to easily support inheritance.
  221. <P>
  222. Inheritance lets us define new types as extensions of existing types;
  223. these new types inherit
  224. all the operations of the types they extend.
  225. The new types are termed `children' or `derived types', while the types
  226. extended are usually called `parents' or `base types.'
  227. Inherited operations can be overridden with new definitions of those
  228. operations.
  229. Derived types can also add new operations that apply only to them, not
  230. their base types. 
  231. <P>
  232. In Ada 95 terminology, types that can have parents or children
  233. are termed ``tagged types'', and have the keyword ``tagged''
  234. as part of their definition.
  235. <P>
  236. This is probably best shown through an example
  237. (this example is taken from the
  238. <A HREF="http://lglwww.epfl.ch/Ada/LRM/9X/rationale/">Ada Rationale</A>).
  239. Let's imagine that we're writing a program that must deal with
  240. a number of different Alerts with different priorities.
  241. <P>
  242. We could define a general type called an `Alert', and then define
  243. some useful operations applicable to any Alert (let's call them
  244. Display, Handle, and Log).
  245. We could then create two children of Alert, one called Low_Alert
  246. (for an Alert with low priority) and one called Medium_Alert
  247. (for an Alert with medium priority).
  248. Medium_Alerts will have more information - an Action_Officer who
  249. must deal with the alert.
  250. <P>
  251. We can then create yet another type, High_Alert, as a child
  252. of Medium_Alert, and add information on when it should ring
  253. an alarm. Since it's a child of Medium_Alert, High_Alert would
  254. <EM>inherit</EM> the Action_Officer defined by Medium_Alert.
  255. Here's how the hierarchy might look pictorially:
  256. <P>
  257. <PRE>
  258. Alert
  259.  * Low_Alert
  260.  * Medium_Alert
  261.    o High_Alert
  262. </PRE>
  263. <P>
  264. And here's how the package specification could look:
  265. <P>
  266. <PRE>
  267. with Calendar, People;
  268. package Alert_System is
  269.   type Alert is tagged
  270.      record
  271.        Time_Of_Arrival : Calendar.Time;
  272.        Message : Text;
  273.      end record;
  274.   procedure Display(A : in Alert);
  275.   procedure Handle(A : in out Alert);
  276.   procedure Log(A : in Alert);
  277.  
  278.   type Low_Alert is new Alert with null record;
  279.  
  280.   type Medium_Alert is new Alert with
  281.     record
  282.       Action_Officer : People.Person;
  283.     end record;
  284.   -- Override default Handle operation for Medium_Alert
  285.   procedure Handle(MA : in out Medium_Alert);
  286.  
  287.   type High_Alert is new Medium_Alert with
  288.     record
  289.       Ring_Alarm_At : Calendar.Time;
  290.     end record;
  291.   procedure Handle(HA : in out High_Alert);
  292.   procedure Set_Alarm(HA : in High_Alert);
  293.  
  294. end Alert_System;
  295. </PRE>
  296.  
  297. <QUESTION Type=Multiple-Choice>
  298. For type High_Alert in package Alert_System,
  299. how many subprograms are defined as operations of High_Alert
  300. and how many record components are defined <EM>in total</EM> for
  301. type High_Alert?
  302. <CHOICES>
  303. <CHOICE ANS=1>Six subprograms, one record component.
  304. <CHOICE ANS=2>Four subprograms, four record components.
  305. <CHOICE ANS=3>Two subprograms, four record components.
  306. </CHOICES>
  307. <ANSWER ANS=2>
  308. <RESPONSES>
  309. <WHEN ANS=1>
  310. No, sorry.
  311. Some of the subprograms have the same name and parameter structure,
  312. which means some of them <EM>override</EM> others.
  313. Also, High_Alert inherits some additional record components.
  314. Try again!
  315. <WHEN ANS=2>
  316. Right. High_Alert has the following defined operations:
  317. <OL>
  318. <LI>
  319. Handle (an overriding of Medium_Alert's Handle)
  320. <LI>
  321. Set_Alarm (defined specifically for High_Alert)
  322. <LI>
  323. Display (inherited from Alert)
  324. <LI>
  325. Log (inherited from Alert)
  326. </OL>
  327. <P>
  328. High_Alert has the following record components:
  329. <OL>
  330. <LI>
  331. Time_Of_Arrival : Calendar.Time;  -- From Alert
  332. <LI>
  333. Message : Text; -- From Alert
  334. <LI>
  335. Action_Officer : People.Person; -- From Medium_Alert
  336. <LI>
  337. Ring_Alarm_At : Calendar.Time; -- For High_Alert.
  338. </OL>
  339. </RESPONSES>
  340. <SECTION NAME="Dynamic Dispatching (Polymorphism) in Ada">
  341. Ada 95 also includes the concept of a <EM>class</EM>.
  342. For each tagged type T there is an associated type T'Class;
  343. this type comprises the union of all types in the tree of derived types
  344. rooted at T.
  345. For example, in the previous example, Medium_Alert'Class is a class
  346. that includes the types Medium_Alert and High_Alert;
  347. Alert'Class is a class that includes the types
  348. Alert, Low_Alert, Medium_Alert, and High_Alert.
  349. <P>
  350. Note that Ada 95 has a more specific meaning for ``class'' than
  351. some other object-oriented programming languages (such as C++).
  352. In C++, the term <EM>class</EM> may mean either
  353. ``a specific type'' or ``the set of a specific types and all types
  354. that inherit from it, directly and indirectly.''
  355. Ada 95 uses different terms for these different concepts.
  356. <P>
  357. A subprogram can define one or more parameters as a type of the
  358. form T'Class.
  359. Whenever the subprogram is called, it simply takes on the value
  360. of whatever was passed to it.
  361. But what happens if that subprogram then
  362. tries to call some other subprogram that requires
  363. a specific type?
  364. The answer is <EM>dynamic dispatching</EM>.
  365. Ada will take the <EM>tag</EM> associated with the tagged type
  366. and determine at run-time which routine to call.
  367. <P>
  368. This is easier shown than explained.
  369. Let's say that we want to create a subprogram
  370. that takes in a value of any type derived from Alert.
  371. The subprogram is to print
  372. out the phrase "processing alert" and then call the correct Handle
  373. subprogram for the given Alert type. 
  374. Here's an example of how to do that:
  375. <P>
  376. <PRE>
  377.  procedure Process_Alert(AC : in out Alert'Class) is
  378.  begin
  379.    Put_Line("Processing Alert.");
  380.    Handle(AC); -- Dispatch to "correct" Handle.
  381.  end Process_Alert;
  382. </PRE>
  383. <P>
  384. When the Ada program reaches the <EM>Handle</EM> statement,
  385. it will note that the current type is a <EM>Class</EM> type, and
  386. that Handle takes only a specific type, and so it will <EM>dispatch</EM>
  387. to the correct Handle operation depending on its type.
  388. <P>
  389. Dispatching will only occur on subprograms that were defined in the
  390. same package as the tagged type itself.
  391. These subprograms are formally called <EM>primitive subprograms</EM>.
  392.  
  393. <QUESTION Type=Multiple-Choice>
  394. In the following package:
  395. <P>
  396. <TEXT FONT=PRE FILE="critters.ads">
  397. <P>
  398. How many different types does Monster'Class include in
  399. package Critters?
  400. <CHOICES>
  401. <CHOICE ANS=1>1
  402. <CHOICE ANS=2>2
  403. <CHOICE ANS=3>3
  404. <CHOICE ANS=4>4
  405. </CHOICES>
  406. <ANSWER ANS=3>
  407. <RESPONSES>
  408. <WHEN ANS=3>
  409. Right - Monster'Class includes types Monster, Dragon, and Red_Dragon.
  410. It doesn't include Person, since person wasn't derived from Monster.
  411. <WHEN ANS=4>
  412. No, sorry.
  413. Person isn't derived from Monster, so it's not one of the types
  414. in Monster'Class.
  415. Person <EM>is</EM> one of the types in package Critters, but that isn't
  416. what the question asked.
  417. Try again.
  418. </RESPONSES>
  419. <SECTION NAME="Encapsulation">
  420. The ``Alert'' and ``Critters'' examples we've seen
  421. are excessively public.  What does that mean?
  422. Those examples permitted all their users (the ``public'')
  423. to see exactly how their types were defined.
  424. Thus, any user of those packages can read or change any of the data
  425. in those types.
  426. Sometimes that's appropriate, but usually it isn't -
  427. this makes it more difficult to change things later.
  428. <P>
  429.  
  430. Ada provides a number of mechanisms to ``hide'' information from
  431. the users (``clients'') of a given type.
  432. Making information inaccessible to others who should not use it
  433. is called <EM>encapsulation</EM>.
  434. Encapsulation improves a program's maintainability and reliability.
  435. <P>
  436.  
  437. In the lesson on types we saw how Ada permits types to be
  438. declared as ``private.''
  439. This works with tagged types as well, so you can declare tagged
  440. types as ``private'' and then hide the implementation details
  441. from everyone who uses the type.
  442. Ada provides a number of variations on this theme
  443. to provide control over what information
  444. is visible and what is not.
  445. <P>
  446.  
  447. The most common way to hide implementation details is to define a
  448. type publicly in a package declaration as
  449. ``tagged private'' (if you don't want the user to know about its parent) or
  450. ``new <EM>parent_name</EM> with private''
  451. (if you want the user to know what its parent is).
  452. Follow each type declaration with declarations of subprograms
  453. that operate on the type.
  454. In the ``private'' part of the package declaration, define the type.
  455. <P>
  456.  
  457. This is easier to show than explain, so here's an example.
  458. Let's create a type called a `File' with a file name, and a derived
  459. type called an `Ada_File' which also stores whether or not the file
  460. has been compiled. Both have a ``View'' subprogram.
  461. Here's how that might look:
  462. <PRE>
  463.   package File_System is
  464.     type File is tagged private;
  465.     procedure View(F : File);
  466.  
  467.     type Ada_File is new File with private;
  468.     procedure View(F : Ada_File);
  469.  
  470.   private
  471.     type File is tagged
  472.      record
  473.        -- We'll discuss strings later in Lovelace
  474.        Name : String(1..20);
  475.      end record;
  476.  
  477.     type Ada_File is new File with
  478.      record
  479.        Compiled : Boolean := False;
  480.      end record;
  481.   end File_System;
  482. </PRE>
  483. <!-- This example was inspired by Ada Rationale chapter II-4 -->
  484. <P>
  485.  
  486. You would then create a package body to define the subprograms:
  487. <PRE>
  488.   package body File_System is
  489.     procedure View(F : File) is
  490.     begin
  491.       -- ...
  492.     end View;
  493.  
  494.     procedure View(F : Ada_File) is
  495.     begin
  496.       -- ...
  497.     end View;
  498.   end File_System;
  499. </PRE>
  500. <P>
  501.  
  502. In general, in Ada you'd define a package with a set of types
  503. inside it. The package declaration would contain a set of types
  504. declared as ``tagged private'' or ``new Parent_Type with private''.
  505. In the private part of the package declaration you'd define the
  506. type ``for real''.
  507. In the package body you'd define the subprograms.
  508. <P>
  509.  
  510. <QUESTION Type=Multiple-Choice>
  511. Given procedure Try_Stuff:
  512. <PRE>
  513.   with File_System;
  514.   procedure Try_Stuff is
  515.    My_Ada_File : File_System.Ada_File;
  516.   begin
  517.    -- To be done.
  518.   end Try_Stuff;
  519. </PRE>
  520. <P>
  521. Let's say that at the line labelled ``To be done''
  522. you'd like to set My_Ada_File's ``Compiled'' value to ``True''.
  523. How could you do this?
  524. <CHOICES>
  525. <CHOICE ANS=1>Replace the line with <EM>My_Ada_File.Compiled := True;</EM>
  526. <CHOICE ANS=2>Replace the line with <EM>Compiled := True;</EM>
  527. <CHOICE ANS=3>I couldn't - it can't be done using the material presented so far.
  528. </CHOICES>
  529. <ANSWER ANS=3>
  530. <RESPONSES>
  531. <WHEN ANS=1>
  532. No, sorry.
  533. You'd be right if Ada_File wasn't defined as a private type, but
  534. Ada_File was defined as a private type.
  535. <WHEN ANS=3>
  536. Right.
  537. Ada_File is defined as a private type; you'd need to add an operation
  538. to package File_System to make this possible.
  539. Actually, there <EM>are</EM> other ways in Ada to do this, but
  540. we've not discussed them and they're all more complicated.
  541. </RESPONSES>
  542. <SECTION NAME="Standard Object-Oriented Format">
  543. Ada has types, packages, and lots of other things; how do you fit
  544. them all together?
  545. What I suggest is that, barring other information, you use a
  546. standard format for defining object-oriented types in Ada.
  547. <P>
  548. Here's a "standard format" that I use for an OO Ada type definition,
  549. which you can
  550. vary to meet your needs (capitalized italics are what you supply):
  551. <P>
  552. <PRE>
  553.   with <I>PACKAGE_NAME_OF_PARENT</I>;
  554.   use  <I>PACKAGE_NAME_OF_PARENT</I>;
  555.   package <I>PACKAGE_NAME</I> is
  556.     type <I>MY_TYPE</I> is tagged private; -- or, new Parent_Type with private
  557.     type <I>MY_TYPE</I>_Access is access all <I>MY_TYPE</I>'Access;
  558.         -- We'll talk about this in a later lesson; by adding this declaration
  559.         -- here you'll make certain operations easier to do later.
  560.     -- Dispatching operations go here.
  561.   private
  562.     -- Define the details of MY_TYPE here.
  563.   end <I>PACKAGE_NAME</I>;
  564. </PRE>
  565. <P>
  566. For the package name, I generally use the plural of the type name.
  567. Here's an example:
  568. <P>
  569. <PRE>
  570.   with Creatures;
  571.   use  Creatures;
  572.  
  573.   package Players is
  574.     type Player is new Creature with private; -- Player is a type of Creature
  575.     type Player_Access is access all Player'Access;
  576.     -- Dispatching operations go here.
  577.     procedure Look(P : in Player'Class);
  578.   private
  579.     type Player is new Thing with
  580.      record
  581.        Logged_In : Boolean;
  582.      end record;
  583.   end Players;
  584. </PRE>
  585. <P>
  586. Ada permits multiple OO types to be defined in a package, but that
  587. doesn't mean you <EM>must</EM> do so.
  588. Generally I find it easier to put different type definitions in different
  589. packages unless the two types are strongly interrelated.
  590. <P>
  591. <QUESTION Type=Multiple-Choice>
  592. Given the example above, what is the name of the new tagged type defined above?
  593. <CHOICES>
  594. <CHOICE ANS=1>Creatures
  595. <CHOICE ANS=2>Players
  596. <CHOICE ANS=3>Player
  597. </CHOICES>
  598. <ANSWER ANS=3>
  599. <RESPONSES>
  600. <WHEN ANS=1>
  601. No, that's not it.
  602. "Creatures" was used, that's true, but Creatures wasn't defined in the
  603. example.
  604. <WHEN ANS=2>
  605. No, that's the name of the <EM>package</EM> defined, not of the <EM>type</EM>.
  606. In Ada there's a separation between a <EM>type</EM> and how that
  607. type is packaged. Try again.
  608. </RESPONSES>
  609.  
  610. <SECTION NAME="Abstract Types and Subprograms">
  611. It's often useful to declare a tagged type that won't be used directly
  612. to create objects,
  613. but instead will be extended by different types in different ways.
  614. Such types are called ``abstract'' types, reasonably enough.
  615. <P>
  616. Abstract types <EM>must</EM> be tagged types, since only tagged types
  617. can be extended.
  618. To define an abstract type, simply put the keyword <EM>abstract</EM>
  619. in front of the keyword <EM>tagged</EM> in its definition.
  620. <P>
  621. Subprograms can also be declared as <EM>abstract</EM>;
  622. a call to such subprograms would have to dispatch to an overridden
  623. version of the subprogram.
  624. To declare a subprogram as <EM>abstract</EM>,
  625. place the phrase "is abstract" before the last semicolon in its definition.
  626. If you have an abstract subprogram for a given type, the type must also
  627. be abstract.
  628. <P>
  629. When you later create another type that descends from an abstract type,
  630. you <EM>must</EM> define all of its abstract subprograms.
  631. <P>
  632. Here's an example of an abstract type representing a set of natural numbers,
  633. taken directly from the
  634. <A HREF="http://lglwww.epfl.ch/Ada/LRM/9X/rm9x/rm9x-03-09-03.html">Ada
  635. LRM section 3.9.3</A>:
  636. <P>
  637. <PRE>
  638.   package Sets is
  639.     subtype Element_Type is Natural;
  640.     type Set is abstract tagged null record;
  641.     function Empty return Set is abstract;
  642.     function Union(Left, Right : Set) return Set is abstract;
  643.     function Intersection(Left, Right : Set) return Set is abstract;
  644.     function Unit_Set(Element : Element_Type) return Set is abstract;
  645.     procedure Take(Element : out Element_Type; From : in out Set) is abstract;
  646.   end Sets;
  647. </PRE>
  648. <P>
  649. Given the above abstract type, you could then derive various
  650. (nonabstract) extensions of the type, representing alternative
  651. implementations of a set. You might use a bit vector,
  652. but impose an upper bound on the largest element representable,
  653. while another might use a hash table, trading off space for flexibility. 
  654. <P>
  655. Abstract subprograms are equivalent to
  656. ending a C++ function declaration with ``= 0''.
  657.  
  658. <SECTION NAME="User-Controlled Initialization, Finalization, and Assignment">
  659. Three kinds of actions are fundamental to the manipulation of objects:
  660. initialization, finalization, and assignment.
  661. Defaults for these operations are provided by Ada.
  662. If you want more control over these operations, you can declare
  663. objects to be a <EM>controlled</EM> type.
  664. <P>
  665. To create a controlled type, simply declare it as a descendent of the either
  666. the type "Controlled" or the type "Limited_Controlled" from
  667. the predefined package "Ada.Finalization".
  668. Use "Controlled" when you want control over all three operations, and
  669. use "Limited_Controlled" when you don't want control over assignment.
  670. <P>
  671. Here's a partial definition of Ada.Finalization:
  672. <P>
  673. <PRE>
  674.   type Controlled is abstract tagged private;
  675.   procedure Initialize(Object : in out Controlled);
  676.   procedure Adjust    (Object : in out Controlled);
  677.   procedure Finalize  (Object : in out Controlled);
  678.  
  679.   type Limited_Controlled is abstract tagged limited private;
  680.   procedure Initialize(Object : in out Limited_Controlled);
  681.   procedure Finalize  (Object : in out Limited_Controlled);
  682. </PRE>
  683. <P>
  684. Once you've created your own type that's descended from Controlled or
  685. Limited_Controlled, you can override Initialize, Adjust, or Finalize
  686. to do whatever you want.
  687. Whenever an object of your type is created, Ada will do its own
  688. initializations and then call the routine "Initialize" that you have defined.
  689. Whenever an object of your type is about to be destroyed (say,
  690. by exiting the subprogram it was defined in), the "Finalize" routine
  691. will be executed.
  692. <P>
  693. If you use a descendent of type Controlled, you can control assignment (:=)
  694. as well.
  695. Then, when Ada executes a statement like "A := B;",
  696. Ada will execute "Adjust" after the normal assignment Ada will perform.
  697. <P>
  698. Some people (particularly those familiar with C++) will ask,
  699. ``what happens if you assign a variable to itself, like A := A''?
  700. Ada handles this correctly due to a careful definition of assignment
  701. (self-assignment is a well-known source of bugs in C++).
  702. More precisely, Ada must act as though the following steps were performed
  703. when "A := B" is executed:
  704. <UL>
  705. <LI>
  706. an anonymous object is created (invoking Initialize)
  707. <LI>
  708. the value of B is assigned to the anonymous object, and
  709. Adjust is called on the anonymous object
  710. <LI>
  711. the target (A) is finalized (invoking Finalize)
  712. <LI>
  713. the value of the anonymous object is assigned into the target (A), and
  714. Adjust is called on the target (A).
  715. </UL>
  716. <P>
  717. The phrase "act as though" is very important; most compilers will
  718. optimize away the intermediate anonymous object, and may do many other
  719. optimizations as well.
  720. <P>
  721. User defined initialization, assignment and finalization are
  722. defined in great detail in
  723. <A HREF="http://lglwww.epfl.ch/Ada/LRM/9X/rm9x/rm9x-07-06.html">section 7.6
  724. of the Ada LRM</A>.
  725.  
  726.