home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / tutorial / cpptutor / text / chap07.txt < prev    next >
Encoding:
Text File  |  1994-05-15  |  22.0 KB  |  464 lines

  1.  
  2.  
  3.  
  4.                                                         Chapter 7
  5.                                                       INHERITANCE
  6.  
  7. One reason to use inheritance is that it permits you to reuse 
  8. code from a previous project, but gives you the flexibility to 
  9. slightly modify it if the old code doesn't do exactly what you 
  10. need for the new project.  It doesn't make sense to start every 
  11. new project from scratch since some code will certainly be 
  12. repeated in several programs and you should strive to build on 
  13. what you did previously.  Moreover, it is easy to make an error 
  14. if you try to modify the original class.  You are less likely to 
  15. make an error if you leave the original alone and only add to it.  
  16. Another reason for using inheritance is if the project requires 
  17. the use of several classes which are very similar but slightly 
  18. different.
  19.  
  20. In this chapter we will concentrate on the mechanism of 
  21. inheritance and how to build it into a program.  A better 
  22. illustration of why you would use inheritance will be given in 
  23. later chapters where we will discuss some practical applications 
  24. of object oriented programming.  The principle of inheritance is 
  25. available with several modern programming languages and is 
  26. handled slightly differently with each.  C++ allows you to 
  27. inherit all or part of the members and methods of a class, modify 
  28. some, and add new ones not available in the parent class.  You 
  29. have complete flexibility, and as usual, the method used with C++ 
  30. has been selected to result in the most efficient code execution.
  31.  
  32.  
  33. A SIMPLE CLASS TO START WITH
  34. -----------------------------------------------------------------
  35. Examine the file named VEHICLE.H for a simple   =================
  36. class which we will use to begin our study of       VEHICLE.H
  37. inheritance.  There is nothing unusual about    =================
  38. this class header, it has been kept very 
  39. simple.  It consists of four simple methods which can be used to 
  40. manipulate data pertaining to our vehicle.  What each method does 
  41. is not especially important at this time.  We will eventually 
  42. refer to this as a base class or parent class, but for the time 
  43. being, we will simply use it like any other class to show that it 
  44. is indeed identical to the classes already studied.  Note that we 
  45. will explain the added keyword protected shortly.  Figure 7-1 is 
  46. a graphical representation of the vehicle class.
  47.  
  48. Ignore lines 4, 5, and 18 until the end of this chapter where 
  49. they will be explained in detail.  This file cannot be compiled 
  50. or executed because it is only a header file.
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.                                                          Page 7-1
  58.  
  59.                                           Chapter 7 - Inheritance
  60.  
  61. THE IMPLEMENTATION FOR VEHICLE
  62. -----------------------------------------------------------------
  63. Examine the file named VEHICLE.CPP and you    ===================
  64. will find that it is the implementation of        VEHICLE.CPP
  65. the vehicle class.  The initialize() method   ===================
  66. assigns the values input as parameters to 
  67. the wheels and weight variables.  We have methods to return the 
  68. number of wheels and the weight, and finally, we have one that 
  69. does a trivial calculation to return the loading on each wheel.  
  70. We will have a few examples of methods that do some significant 
  71. processing later, but at this point, we are more interested in 
  72. learning how to set up the interface to the classes, so the 
  73. implementations will be kept trivial.
  74.  
  75. As stated above, this is a very simple class which will be used 
  76. in the next program.  Later in this tutorial we will use it as a 
  77. base class.  You should compile this class at this time in 
  78. preparation for the next example program, but you cannot execute 
  79. it because there is no entry point.
  80.  
  81.  
  82. USING THE VEHICLE CLASS
  83. -----------------------------------------------------------------
  84. The file named TRANSPRT.CPP uses the vehicle   ==================
  85. class in exactly the same manner as we            TRANSPRT.CPP
  86. illustrated in the last chapter.  This should  ==================
  87. be an indication to you that the vehicle 
  88. class is truly nothing more than a normal class as defined in C++.  
  89. We will make it a little special, however, by using it unmodified 
  90. as a base class in the next few example files to illustrate 
  91. inheritance.  Inheritance uses an existing class and adds 
  92. functionality to it to accomplish another, possibly more 
  93. complex job.
  94.  
  95. You should have no problem understanding the operation of this 
  96. program.  It declares four objects of the vehicle class, 
  97. initializes them, and prints out a few of the data values to 
  98. illustrate that the vehicle class can be used as a simple class 
  99. because it is a simple class.  We are referring to it as a simple 
  100. class as opposed to calling it a base class or derived class as 
  101. we will do shortly.
  102.  
  103. If you thoroughly understand this program, you should compile and 
  104. execute it, remembering to link the vehicle object file with this 
  105. object file.
  106.  
  107.  
  108. OUR FIRST DERIVED CLASS
  109. -----------------------------------------------------------------
  110. Examine the file named CAR.H for our first      =================
  111. example of the use of a derived class or              CAR.H
  112. child class.  The vehicle class is inherited    =================
  113. due to the ": public vehicle" added to line 
  114.  
  115.                                                          Page 7-2
  116.  
  117.                                           Chapter 7 - Inheritance
  118.  
  119. 7.  This derived class named car is composed of all of the 
  120. information included in the base class vehicle, and all of its 
  121. own additional information.  Even though we did nothing to the 
  122. class named vehicle, we made it into a base class because of the 
  123. way we are using it here.  To go a step further, even though it 
  124. will be used as a base class in an example program later in this 
  125. chapter, there is no reason it cannot continue to be used as a 
  126. simple class in the previous example program.  In fact, it can be 
  127. used as a single class and a base class in the same program.  The 
  128. question of whether it is a simple class or a base class is 
  129. answered by the way it is used.
  130.  
  131. A discussion of terminology is needed here.  When discussing 
  132. object oriented programming in general, a class that inherits 
  133. another is often called a derived class or a child class, but the 
  134. most proper term as defined for C++, is a derived class.  Since 
  135. these terms are very descriptive, and most writers tend to use 
  136. the terms interchangeably, we will also use these terms in this 
  137. tutorial.  Likewise the proper C++ terminology for the inherited 
  138. class is to call it a base class, but parent class and super 
  139. class are sometimes used also.
  140.  
  141. A base class is a rather general class which can cover a wide 
  142. range of objects, whereas a derived class is somewhat more 
  143. restricted but at the same time more useful.  For example if we 
  144. had a base class named programming language and a derived class 
  145. named C++, then we could use the base class to define Pascal, 
  146. Ada, C++, or any other programming language, but it would not 
  147. tell us about the use of classes in C++ because it can only give 
  148. a general view of each language.  On the other hand, the derived 
  149. class named C++ could define the use of classes, but it could not 
  150. be used to describe the other languages because it is too narrow.  
  151. A base class tends to be more general, and a derived class is 
  152. more specific.
  153.  
  154. In this case, the vehicle base class can be used to declare 
  155. objects that represent trucks, cars, bicycles, or any number of 
  156. other vehicles you can think up.  The class named car however can 
  157. only be used to declare an object that is of type car because we 
  158. have limited the kinds of data that can be intelligently used 
  159. with it.  The car class is therefore more restrictive and 
  160. specific than the vehicle class.  The vehicle class is more 
  161. general than the car class.
  162.  
  163. If we wished to get even more specific, we could define a derived 
  164. class using car as the base class, name it sports_car, and 
  165. include such information as red_line_limit for the tachometer 
  166. which would be silly for the family station wagon.  The car class 
  167. would therefore be used as a derived class and a base class at 
  168. the same time, so it should be clear that these names refer to 
  169. how a class is used.
  170.  
  171.  
  172.  
  173.                                                          Page 7-3
  174.  
  175.                                           Chapter 7 - Inheritance
  176.  
  177. HOW DO WE DECLARE A DERIVED CLASS?
  178. -----------------------------------------------------------------
  179. Enough generalities about classes, let's get down to the 
  180. specifics.  A derived class is defined by including the header 
  181. file for the base class as is done in line 5, then the name of 
  182. the base class is given following the name of the derived class 
  183. separated by a colon as is illustrated in line 7.  Ignore the 
  184. keyword public immediately following the colon in this line.  We 
  185. will study it in detail in the next chapter.  All objects 
  186. declared as being of class car therefore are composed of the two 
  187. variables from the class vehicle because they inherit those 
  188. variables, and the single variable declared in the class car 
  189. named passenger_load.
  190.  
  191. An object of this class will have three of the four methods of 
  192. vehicle and the two new ones declared here.  The method named 
  193. initialize() which is part of the vehicle class will not be 
  194. available here because it is hidden by the local version of 
  195. initialize() which is a part of the car class.  The local method 
  196. will be used if the name is repeated allowing you to customize 
  197. your new class.  Figure 7-2 is a graphical representation of an 
  198. object of this class.
  199.  
  200. Note once again that the implementation for the base class only 
  201. needs to be supplied in its compiled form.  The source code for 
  202. the implementation can be hidden for economic reasons to aid 
  203. software developers.  Hiding the source code also allows the 
  204. practice of information hiding.  The header for the base class 
  205. must be available as a text file since the class definitions are 
  206. required in order to use the class.
  207.  
  208.  
  209. THE CAR CLASS IMPLEMENTATION
  210. -----------------------------------------------------------------
  211. Examine the file named CAR.CPP which is the   ===================
  212. implementation file for the car class.  The         CAR.CPP
  213. first thing you should notice is that this    ===================
  214. file has no indication of the fact that it 
  215. is a derived class of any other file, that can only be determined 
  216. by inspecting the header file for the class.  Since we can't tell 
  217. if it is a derived class or not, it is written in exactly the 
  218. same way as any other class implementation file.
  219.  
  220. The implementations for the two new methods are written in 
  221. exactly the same way as methods are written for any other class.  
  222. If you think you understand this file, you should compile it for 
  223. later use.
  224.  
  225. ANOTHER DERIVED CLASS
  226. -----------------------------------------------------------------
  227. Examine the file named TRUCK.H for an example   =================
  228. of another class that uses the vehicle class         TRUCK.H
  229. and adds to it.  Of course, it adds different   =================
  230.  
  231.                                                          Page 7-4
  232.  
  233.                                           Chapter 7 - Inheritance
  234.  
  235. things to it, because it will specialize in 
  236. those things that pertain to trucks.  In fact, it adds two more 
  237. variables and three more methods.  Once again, ignore the keyword 
  238. public following the colon in line 7 for a few minutes and we 
  239. will cover it in detail in the next chapter of this tutorial.  
  240. See figure 7-3 for a graphical representation of the truck class.
  241.  
  242. A very important point that must be made is that the car class 
  243. and the truck class have absolutely nothing to do with each 
  244. other, they only happen to be derived classes of the same base 
  245. class or parent class as it is sometimes called.Note that both 
  246. the car and the truck classes have methods named passengers() but 
  247. this causes no problems and is perfectly acceptable.  If classes 
  248. are related in some way, and they certainly are if they are both 
  249. derived classes of a common base class, you would expect them to 
  250. be doing somewhat similar things.  In this situation there is a 
  251. good possibility that a method name would be repeated in both 
  252. child classes.
  253.  
  254.  
  255. THE TRUCK IMPLEMENTATION
  256. -----------------------------------------------------------------
  257. Examine the file named TRUCK.CPP for the      ===================
  258. implementation of the truck class.  It has         TRUCK.CPP
  259. nothing unusual included in it.               ===================
  260.  
  261. You should have no problem understanding this implementation.  
  262. Your assignment at this point is to compile it in preparation for 
  263. our example program that uses all three of the classes defined in 
  264. this chapter.  Figure 7-4 is the class diagram for these three 
  265. classes illustrating the inheritance.  This form of class design 
  266. notation is generally accepted in the software development 
  267. community, although some authors use "clouds" rather than boxes 
  268. to indicate a class.  The double line with an arrow pointing from 
  269. the derived to the base class is in general use.  Many designers 
  270. draw the diagram with the base class at the top and the derived 
  271. classes below it, but that is really a matter of personal taste.
  272.  
  273.  
  274. USING ALL THREE CLASSES
  275. -----------------------------------------------------------------
  276. Examine the program named ALLVEHIC.CPP for an  ==================
  277. example that uses all three of the classes we     ALLVEHIC.CPP
  278. have been discussing in this chapter.  It      ==================
  279. uses the parent class vehicle to declare 
  280. objects and also uses the two child classes to declare objects.  
  281. This was done to illustrate that all three classes can be used in 
  282. a single program.
  283.  
  284. All three of the header files for the classes are included in 
  285. lines 3 through 5 so the program can use the components of the 
  286. classes.  Notice that the implementations of the three classes 
  287. are not in view here and do not need to be in view.  This allows 
  288.  
  289.                                                          Page 7-5
  290.  
  291.                                           Chapter 7 - Inheritance
  292.  
  293. the code to be used without access to the source code for the 
  294. actual implementation of the class.  However, it should be clear 
  295. that the header file definition must be available.
  296.  
  297. In this example program, only one object of each class is 
  298. declared and used but as many as desired could be declared and 
  299. used in order to accomplish the programming task at hand.  You 
  300. will notice how clean and uncluttered the source code is for this 
  301. program.  The classes were developed, debugged, and stored away 
  302. previously, and the interfaces were kept very simple.  There is 
  303. nothing new here so you should have no trouble understanding the 
  304. operation of this program.
  305.  
  306. Compiling and executing this program will take a bit of effort 
  307. but the process is not complicated.  The three classes and the 
  308. main program can be compiled in any order desired.  All four must 
  309. be compiled prior to linking the four resulting object (or 
  310. binary) files together.  Finally, you can execute the complete 
  311. program.  Be sure you do the required steps to compile and 
  312. execute this program because the effective use of C++ will 
  313. require you to compile many separate files and link them 
  314. together.  This is because of the nature of the C++ language, but 
  315. it should not be a burden if a good "make" capability exists with 
  316. your compiler.  If you are using an implementation of C++ that 
  317. has a project capability, it will make this a snap.
  318.  
  319.  
  320. WHY THE #ifndef VEHICLE_H ?
  321. -----------------------------------------------------------------
  322. We promised to return to the strange looking preprocessor 
  323. directive in lines 4, 5 and 18 in the VEHICLE.H file, and this is 
  324. the time for it.  When we define the derived class car, we are 
  325. required to supply it with the full definition of the interface 
  326. to the vehicle class since car is a derived class of vehicle and 
  327. must know all about its parent.  We do that by including the 
  328. vehicle class into the car class, and the car class can be 
  329. compiled.  The vehicle class must also be included in the header 
  330. file of the truck class for the same reason.
  331.  
  332. When we get to the main program, we must inform it of the details 
  333. of all three classes, so all three header files must be included 
  334. as is done in lines 3 through 5 of ALLVEHIC.CPP, but this leads 
  335. to a problem.  When the preprocessor gets to the car class, it 
  336. includes the vehicle class because it is listed in the car class 
  337. header file, but since the vehicle class was already included in 
  338. line 3 of ALLVEHIC.CPP, it is included twice and we attempt to 
  339. redefine the class vehicle.  Of course it is the same definition, 
  340. but the system doesn't care, it simply doesn't allow redefinition 
  341. of a class.  We allow the double inclusion of the file and at the 
  342. same time prevent the double inclusion of the class by building a 
  343. bridge around it using the word VEHICLE_H.  If the word is 
  344. already defined, the definition is skipped, but if the word is 
  345. not defined, the definition is included and the word is defined 
  346.  
  347.                                                          Page 7-6
  348.  
  349.                                           Chapter 7 - Inheritance
  350.  
  351. at that time.  The end result is the actual inclusion of the 
  352. class only once, even though the file is included more than once.  
  353. You should have no trouble understanding the logic of the 
  354. includes if you spend a little time studying this program 
  355. sequence.
  356.  
  357. Even though ANSI-C allows multiple definitions of entities, 
  358. provided the definitions are identical, C++ does not permit this.  
  359. The primary reason is because the compiler would have great 
  360. difficulty in knowing if it has already made a constructor call 
  361. for the redefined entity, if there is one.  A multiple 
  362. constructor call for a single object could cause great havoc, so 
  363. C++ was defined to prevent any multiple constructor calls by 
  364. making it illegal to redefine any entity.  This is not a problem 
  365. in any practical program.
  366.  
  367. The name VEHICLE_H was chosen as the word because it is the name 
  368. of the file, with the period replaced by the underline.  If the 
  369. name of the file is used systematically in all of your class 
  370. definitions, you cannot have a name clash because the filename of 
  371. every class must be unique provided you keep all files in the 
  372. same directory.  It would be good for you to get into the 
  373. practice of building the optional skip around all of your class 
  374. headers.  All class definition files in the remainder of this 
  375. tutorial will include this skip around to prevent multiple 
  376. inclusions and to be an example for you.  You should get into 
  377. the practice of adding the skip around to all of your class 
  378. headers no matter how trivial they may seem to be.
  379.  
  380.  
  381. OUR FIRST PRACTICAL INHERITANCE
  382. -----------------------------------------------------------------
  383. Continuing where we started in chapter 5, we    =================
  384. will inherit the date class into the file           NEWDATE.H
  385. named NEWDATE.H and add a member variable and   =================
  386. a new method to the class.  Actually, this is 
  387. not a good way to add the day_of_year to the date class since it 
  388. is available in the structure returned from the system call in 
  389. the date class.  However, we are more interested in illustrating 
  390. inheritance in a practical example than we are in developing a 
  391. perfect class, so we will live with this inefficiency.  You will 
  392. note that we add one variable and one method to create our new 
  393. class.
  394.  
  395. The program named NEWDATE.CPP contains the    ===================
  396. implementation for the added method and           NEWDATE.CPP
  397. should be simple for the student to           ===================
  398. understand.  This class implementation uses 
  399. the array days[] from the date class implementation since it was 
  400. defined as a global variable there.  The method named 
  401. get_time_of_day() involves very simple logic but still adjusts 
  402. for leap years.  
  403.  
  404.  
  405.                                                          Page 7-7
  406.  
  407.                                           Chapter 7 - Inheritance
  408.  
  409. Finally, the example program named             ==================
  410. TRYNDATE.CPP will use the new class in a          TRYNDATE.CPP
  411. very simple way to illustrate that the         ==================
  412. derived class is as easy to use as the 
  413. base class and in fact the main program has no way of knowing 
  414. that it is using a derived class.
  415.  
  416. You should compile and link this program to gain the experience 
  417. of doing so.  Remember that it will be necessary to link in the 
  418. object code for the original date class as well as the object 
  419. code from the newdate class and the main program.
  420.  
  421.  
  422. PROGRAMMING EXERCISES
  423. -----------------------------------------------------------------
  424. 1.  Add another object of the vehicle class to ALLVEHIC.CPP named 
  425.     bicycle, and do some of the same operations as were done to 
  426.     the unicycle.  You will only need to recompile the main 
  427.     program and link all four files together to get an executable 
  428.     file, the three classes will not require recompilation.
  429.     
  430. 2.  Add a new method to the truck class to return the total 
  431.     weight of the truck plus its payload and add code to 
  432.     ALLVEHIC.CPP to read the value out and display it on the 
  433.     monitor.  This will require an addition to TRUCK.H, another 
  434.     addition to TRUCK.CPP, and of course the changes to the main 
  435.     program named ALLVEHIC.CPP.  The answer is given as three 
  436.     files named CH07_3A.H (TRUCK.H), CH07_3B.CPP (TRUCK.CPP) 
  437.     and the changed main program is found in CH07_3C.CPP in the 
  438.     answer directory on the distribution disk for this tutorial.
  439.  
  440. 3.  Add a variable named sex of type char to the name class you 
  441.     developed in chapter 5 as well as methods to set and retrieve 
  442.     the value of this variable.  The only legal inputs are 'M' or 
  443.     'F'.  These additions should be done by inheriting the name 
  444.     class into the new class.
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.                                                          Page 7-8
  464.