home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Chapter 7
- INHERITANCE
-
- One reason to use inheritance is that it permits you to reuse
- code from a previous project, but gives you the flexibility to
- slightly modify it if the old code doesn't do exactly what you
- need for the new project. It doesn't make sense to start every
- new project from scratch since some code will certainly be
- repeated in several programs and you should strive to build on
- what you did previously. Moreover, it is easy to make an error
- if you try to modify the original class. You are less likely to
- make an error if you leave the original alone and only add to it.
- Another reason for using inheritance is if the project requires
- the use of several classes which are very similar but slightly
- different.
-
- In this chapter we will concentrate on the mechanism of
- inheritance and how to build it into a program. A better
- illustration of why you would use inheritance will be given in
- later chapters where we will discuss some practical applications
- of object oriented programming. The principle of inheritance is
- available with several modern programming languages and is
- handled slightly differently with each. C++ allows you to
- inherit all or part of the members and methods of a class, modify
- some, and add new ones not available in the parent class. You
- have complete flexibility, and as usual, the method used with C++
- has been selected to result in the most efficient code execution.
-
-
- A SIMPLE CLASS TO START WITH
- -----------------------------------------------------------------
- Examine the file named VEHICLE.H for a simple =================
- class which we will use to begin our study of VEHICLE.H
- inheritance. There is nothing unusual about =================
- this class header, it has been kept very
- simple. It consists of four simple methods which can be used to
- manipulate data pertaining to our vehicle. What each method does
- is not especially important at this time. We will eventually
- refer to this as a base class or parent class, but for the time
- being, we will simply use it like any other class to show that it
- is indeed identical to the classes already studied. Note that we
- will explain the added keyword protected shortly. Figure 7-1 is
- a graphical representation of the vehicle class.
-
- Ignore lines 4, 5, and 18 until the end of this chapter where
- they will be explained in detail. This file cannot be compiled
- or executed because it is only a header file.
-
-
-
-
-
-
- Page 7-1
-
- Chapter 7 - Inheritance
-
- THE IMPLEMENTATION FOR VEHICLE
- -----------------------------------------------------------------
- Examine the file named VEHICLE.CPP and you ===================
- will find that it is the implementation of VEHICLE.CPP
- the vehicle class. The initialize() method ===================
- assigns the values input as parameters to
- the wheels and weight variables. We have methods to return the
- number of wheels and the weight, and finally, we have one that
- does a trivial calculation to return the loading on each wheel.
- We will have a few examples of methods that do some significant
- processing later, but at this point, we are more interested in
- learning how to set up the interface to the classes, so the
- implementations will be kept trivial.
-
- As stated above, this is a very simple class which will be used
- in the next program. Later in this tutorial we will use it as a
- base class. You should compile this class at this time in
- preparation for the next example program, but you cannot execute
- it because there is no entry point.
-
-
- USING THE VEHICLE CLASS
- -----------------------------------------------------------------
- The file named TRANSPRT.CPP uses the vehicle ==================
- class in exactly the same manner as we TRANSPRT.CPP
- illustrated in the last chapter. This should ==================
- be an indication to you that the vehicle
- class is truly nothing more than a normal class as defined in C++.
- We will make it a little special, however, by using it unmodified
- as a base class in the next few example files to illustrate
- inheritance. Inheritance uses an existing class and adds
- functionality to it to accomplish another, possibly more
- complex job.
-
- You should have no problem understanding the operation of this
- program. It declares four objects of the vehicle class,
- initializes them, and prints out a few of the data values to
- illustrate that the vehicle class can be used as a simple class
- because it is a simple class. We are referring to it as a simple
- class as opposed to calling it a base class or derived class as
- we will do shortly.
-
- If you thoroughly understand this program, you should compile and
- execute it, remembering to link the vehicle object file with this
- object file.
-
-
- OUR FIRST DERIVED CLASS
- -----------------------------------------------------------------
- Examine the file named CAR.H for our first =================
- example of the use of a derived class or CAR.H
- child class. The vehicle class is inherited =================
- due to the ": public vehicle" added to line
-
- Page 7-2
-
- Chapter 7 - Inheritance
-
- 7. This derived class named car is composed of all of the
- information included in the base class vehicle, and all of its
- own additional information. Even though we did nothing to the
- class named vehicle, we made it into a base class because of the
- way we are using it here. To go a step further, even though it
- will be used as a base class in an example program later in this
- chapter, there is no reason it cannot continue to be used as a
- simple class in the previous example program. In fact, it can be
- used as a single class and a base class in the same program. The
- question of whether it is a simple class or a base class is
- answered by the way it is used.
-
- A discussion of terminology is needed here. When discussing
- object oriented programming in general, a class that inherits
- another is often called a derived class or a child class, but the
- most proper term as defined for C++, is a derived class. Since
- these terms are very descriptive, and most writers tend to use
- the terms interchangeably, we will also use these terms in this
- tutorial. Likewise the proper C++ terminology for the inherited
- class is to call it a base class, but parent class and super
- class are sometimes used also.
-
- A base class is a rather general class which can cover a wide
- range of objects, whereas a derived class is somewhat more
- restricted but at the same time more useful. For example if we
- had a base class named programming language and a derived class
- named C++, then we could use the base class to define Pascal,
- Ada, C++, or any other programming language, but it would not
- tell us about the use of classes in C++ because it can only give
- a general view of each language. On the other hand, the derived
- class named C++ could define the use of classes, but it could not
- be used to describe the other languages because it is too narrow.
- A base class tends to be more general, and a derived class is
- more specific.
-
- In this case, the vehicle base class can be used to declare
- objects that represent trucks, cars, bicycles, or any number of
- other vehicles you can think up. The class named car however can
- only be used to declare an object that is of type car because we
- have limited the kinds of data that can be intelligently used
- with it. The car class is therefore more restrictive and
- specific than the vehicle class. The vehicle class is more
- general than the car class.
-
- If we wished to get even more specific, we could define a derived
- class using car as the base class, name it sports_car, and
- include such information as red_line_limit for the tachometer
- which would be silly for the family station wagon. The car class
- would therefore be used as a derived class and a base class at
- the same time, so it should be clear that these names refer to
- how a class is used.
-
-
-
- Page 7-3
-
- Chapter 7 - Inheritance
-
- HOW DO WE DECLARE A DERIVED CLASS?
- -----------------------------------------------------------------
- Enough generalities about classes, let's get down to the
- specifics. A derived class is defined by including the header
- file for the base class as is done in line 5, then the name of
- the base class is given following the name of the derived class
- separated by a colon as is illustrated in line 7. Ignore the
- keyword public immediately following the colon in this line. We
- will study it in detail in the next chapter. All objects
- declared as being of class car therefore are composed of the two
- variables from the class vehicle because they inherit those
- variables, and the single variable declared in the class car
- named passenger_load.
-
- An object of this class will have three of the four methods of
- vehicle and the two new ones declared here. The method named
- initialize() which is part of the vehicle class will not be
- available here because it is hidden by the local version of
- initialize() which is a part of the car class. The local method
- will be used if the name is repeated allowing you to customize
- your new class. Figure 7-2 is a graphical representation of an
- object of this class.
-
- Note once again that the implementation for the base class only
- needs to be supplied in its compiled form. The source code for
- the implementation can be hidden for economic reasons to aid
- software developers. Hiding the source code also allows the
- practice of information hiding. The header for the base class
- must be available as a text file since the class definitions are
- required in order to use the class.
-
-
- THE CAR CLASS IMPLEMENTATION
- -----------------------------------------------------------------
- Examine the file named CAR.CPP which is the ===================
- implementation file for the car class. The CAR.CPP
- first thing you should notice is that this ===================
- file has no indication of the fact that it
- is a derived class of any other file, that can only be determined
- by inspecting the header file for the class. Since we can't tell
- if it is a derived class or not, it is written in exactly the
- same way as any other class implementation file.
-
- The implementations for the two new methods are written in
- exactly the same way as methods are written for any other class.
- If you think you understand this file, you should compile it for
- later use.
-
- ANOTHER DERIVED CLASS
- -----------------------------------------------------------------
- Examine the file named TRUCK.H for an example =================
- of another class that uses the vehicle class TRUCK.H
- and adds to it. Of course, it adds different =================
-
- Page 7-4
-
- Chapter 7 - Inheritance
-
- things to it, because it will specialize in
- those things that pertain to trucks. In fact, it adds two more
- variables and three more methods. Once again, ignore the keyword
- public following the colon in line 7 for a few minutes and we
- will cover it in detail in the next chapter of this tutorial.
- See figure 7-3 for a graphical representation of the truck class.
-
- A very important point that must be made is that the car class
- and the truck class have absolutely nothing to do with each
- other, they only happen to be derived classes of the same base
- class or parent class as it is sometimes called.Note that both
- the car and the truck classes have methods named passengers() but
- this causes no problems and is perfectly acceptable. If classes
- are related in some way, and they certainly are if they are both
- derived classes of a common base class, you would expect them to
- be doing somewhat similar things. In this situation there is a
- good possibility that a method name would be repeated in both
- child classes.
-
-
- THE TRUCK IMPLEMENTATION
- -----------------------------------------------------------------
- Examine the file named TRUCK.CPP for the ===================
- implementation of the truck class. It has TRUCK.CPP
- nothing unusual included in it. ===================
-
- You should have no problem understanding this implementation.
- Your assignment at this point is to compile it in preparation for
- our example program that uses all three of the classes defined in
- this chapter. Figure 7-4 is the class diagram for these three
- classes illustrating the inheritance. This form of class design
- notation is generally accepted in the software development
- community, although some authors use "clouds" rather than boxes
- to indicate a class. The double line with an arrow pointing from
- the derived to the base class is in general use. Many designers
- draw the diagram with the base class at the top and the derived
- classes below it, but that is really a matter of personal taste.
-
-
- USING ALL THREE CLASSES
- -----------------------------------------------------------------
- Examine the program named ALLVEHIC.CPP for an ==================
- example that uses all three of the classes we ALLVEHIC.CPP
- have been discussing in this chapter. It ==================
- uses the parent class vehicle to declare
- objects and also uses the two child classes to declare objects.
- This was done to illustrate that all three classes can be used in
- a single program.
-
- All three of the header files for the classes are included in
- lines 3 through 5 so the program can use the components of the
- classes. Notice that the implementations of the three classes
- are not in view here and do not need to be in view. This allows
-
- Page 7-5
-
- Chapter 7 - Inheritance
-
- the code to be used without access to the source code for the
- actual implementation of the class. However, it should be clear
- that the header file definition must be available.
-
- In this example program, only one object of each class is
- declared and used but as many as desired could be declared and
- used in order to accomplish the programming task at hand. You
- will notice how clean and uncluttered the source code is for this
- program. The classes were developed, debugged, and stored away
- previously, and the interfaces were kept very simple. There is
- nothing new here so you should have no trouble understanding the
- operation of this program.
-
- Compiling and executing this program will take a bit of effort
- but the process is not complicated. The three classes and the
- main program can be compiled in any order desired. All four must
- be compiled prior to linking the four resulting object (or
- binary) files together. Finally, you can execute the complete
- program. Be sure you do the required steps to compile and
- execute this program because the effective use of C++ will
- require you to compile many separate files and link them
- together. This is because of the nature of the C++ language, but
- it should not be a burden if a good "make" capability exists with
- your compiler. If you are using an implementation of C++ that
- has a project capability, it will make this a snap.
-
-
- WHY THE #ifndef VEHICLE_H ?
- -----------------------------------------------------------------
- We promised to return to the strange looking preprocessor
- directive in lines 4, 5 and 18 in the VEHICLE.H file, and this is
- the time for it. When we define the derived class car, we are
- required to supply it with the full definition of the interface
- to the vehicle class since car is a derived class of vehicle and
- must know all about its parent. We do that by including the
- vehicle class into the car class, and the car class can be
- compiled. The vehicle class must also be included in the header
- file of the truck class for the same reason.
-
- When we get to the main program, we must inform it of the details
- of all three classes, so all three header files must be included
- as is done in lines 3 through 5 of ALLVEHIC.CPP, but this leads
- to a problem. When the preprocessor gets to the car class, it
- includes the vehicle class because it is listed in the car class
- header file, but since the vehicle class was already included in
- line 3 of ALLVEHIC.CPP, it is included twice and we attempt to
- redefine the class vehicle. Of course it is the same definition,
- but the system doesn't care, it simply doesn't allow redefinition
- of a class. We allow the double inclusion of the file and at the
- same time prevent the double inclusion of the class by building a
- bridge around it using the word VEHICLE_H. If the word is
- already defined, the definition is skipped, but if the word is
- not defined, the definition is included and the word is defined
-
- Page 7-6
-
- Chapter 7 - Inheritance
-
- at that time. The end result is the actual inclusion of the
- class only once, even though the file is included more than once.
- You should have no trouble understanding the logic of the
- includes if you spend a little time studying this program
- sequence.
-
- Even though ANSI-C allows multiple definitions of entities,
- provided the definitions are identical, C++ does not permit this.
- The primary reason is because the compiler would have great
- difficulty in knowing if it has already made a constructor call
- for the redefined entity, if there is one. A multiple
- constructor call for a single object could cause great havoc, so
- C++ was defined to prevent any multiple constructor calls by
- making it illegal to redefine any entity. This is not a problem
- in any practical program.
-
- The name VEHICLE_H was chosen as the word because it is the name
- of the file, with the period replaced by the underline. If the
- name of the file is used systematically in all of your class
- definitions, you cannot have a name clash because the filename of
- every class must be unique provided you keep all files in the
- same directory. It would be good for you to get into the
- practice of building the optional skip around all of your class
- headers. All class definition files in the remainder of this
- tutorial will include this skip around to prevent multiple
- inclusions and to be an example for you. You should get into
- the practice of adding the skip around to all of your class
- headers no matter how trivial they may seem to be.
-
-
- OUR FIRST PRACTICAL INHERITANCE
- -----------------------------------------------------------------
- Continuing where we started in chapter 5, we =================
- will inherit the date class into the file NEWDATE.H
- named NEWDATE.H and add a member variable and =================
- a new method to the class. Actually, this is
- not a good way to add the day_of_year to the date class since it
- is available in the structure returned from the system call in
- the date class. However, we are more interested in illustrating
- inheritance in a practical example than we are in developing a
- perfect class, so we will live with this inefficiency. You will
- note that we add one variable and one method to create our new
- class.
-
- The program named NEWDATE.CPP contains the ===================
- implementation for the added method and NEWDATE.CPP
- should be simple for the student to ===================
- understand. This class implementation uses
- the array days[] from the date class implementation since it was
- defined as a global variable there. The method named
- get_time_of_day() involves very simple logic but still adjusts
- for leap years.
-
-
- Page 7-7
-
- Chapter 7 - Inheritance
-
- Finally, the example program named ==================
- TRYNDATE.CPP will use the new class in a TRYNDATE.CPP
- very simple way to illustrate that the ==================
- derived class is as easy to use as the
- base class and in fact the main program has no way of knowing
- that it is using a derived class.
-
- You should compile and link this program to gain the experience
- of doing so. Remember that it will be necessary to link in the
- object code for the original date class as well as the object
- code from the newdate class and the main program.
-
-
- PROGRAMMING EXERCISES
- -----------------------------------------------------------------
- 1. Add another object of the vehicle class to ALLVEHIC.CPP named
- bicycle, and do some of the same operations as were done to
- the unicycle. You will only need to recompile the main
- program and link all four files together to get an executable
- file, the three classes will not require recompilation.
-
- 2. Add a new method to the truck class to return the total
- weight of the truck plus its payload and add code to
- ALLVEHIC.CPP to read the value out and display it on the
- monitor. This will require an addition to TRUCK.H, another
- addition to TRUCK.CPP, and of course the changes to the main
- program named ALLVEHIC.CPP. The answer is given as three
- files named CH07_3A.H (TRUCK.H), CH07_3B.CPP (TRUCK.CPP)
- and the changed main program is found in CH07_3C.CPP in the
- answer directory on the distribution disk for this tutorial.
-
- 3. Add a variable named sex of type char to the name class you
- developed in chapter 5 as well as methods to set and retrieve
- the value of this variable. The only legal inputs are 'M' or
- 'F'. These additions should be done by inheriting the name
- class into the new class.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 7-8
-