home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Chapter 15
- VIRTUAL METHODS
-
-
-
- Since we covered encapsulation and inheritance in the last chapter,
- we are left with only virtual methods to complete the major topics
- of object oriented programming. Virtual methods, as they are
- called in TURBO Pascal, have several other names in the literature
- to describe the same technique. This technique is sometimes called
- run-time binding or late binding referring to when the decision is
- made as to what method will respond to the message. The use of
- virtual methods moves the responsibility of selection from the
- client (the logic sending the message) to the supplier (the methods
- responding to the message). We will begin with a skeleton of a
- program without a virtual method and add one to show the effect of
- adding a virtual method.
-
-
-
- WITHOUT A VIRTUAL METHOD
- _________________________________________________________________
-
- The example program named VIRTUAL1.PAS will be ==============
- used as the starting point for the study of VIRTUAL1.PAS
- virtual methods. We must state that this program ==============
- does not contain a virtual method, it is only the
- starting point for studying them.
-
- The objects included here are very similar to the objects
- describing vehicles which we were working with in the last chapter.
- You will notice that all three objects contain a method named
- Message in lines 11, 20, and 31. The Message method will be the
- center of our study in the first three example programs. It should
- be pointed out that the constructors for the three objects are
- called in lines 98 through 100 even though a constructor call is
- still not absolutely necessary in this case. We will have more to
- say about the constructor calls during the next example program.
-
- Compile and execute the program and you will find that even though
- it is legal to pass the objects of type Car and Truck to the method
- named Output_A_Message in lines 109 and 110, the method that is
- called from line 86 is the method named Message in the parent type
- Vehicle. This is probably no surprise to you since we defined an
- object of type Vehicle as a formal parameter of the method
- Output_A_Message. We need only one small change and we will have
- a virtual procedure call.
-
- Even though this program seems to do very little, it will be the
- basis of our study of virtual methods so you should study the code
- in detail.
-
-
-
- Page 15-1
-
- Chapter 15 - Virtual Methods
-
- NOW TO MAKE IT A VIRTUAL METHOD
- _________________________________________________________________
-
- Examine the example program named VIRTUAL2.PAS, ================
- and you will find only one small change in the VIRTUAL2.PAS
- code but a world of difference in the way it ================
- executes.
-
- The careful student will notice the addition of the reserved word
- virtual in lines 13, 22, and 33. This makes the method named
- Message a virtual method which operates a little differently from
- the way it did in the last program. Once again, we call the three
- constructors in lines 100 through 102 and this time the constructor
- calls are absolutely essential. We will discuss why in a couple
- of paragraphs.
-
- Once again we send a message to Output_A_Message three times in
- lines 110 through 112 and line 88 is used to send a message to the
- Message method. When we compile and execute this program, we find
- that even though the method Output_A_Message only uses the parent
- type Vehicle, the system calls the correct procedure based on the
- type of the actual object passed to this method. The system sends
- a message to the objects of the correct type instead of to the
- parent type as may be expected. It should be clear to you that the
- object that is to receive the message is not known at compile time
- but must be selected at run time when the object arrives at the
- method Output_A_Message. This is known as late binding since the
- type is not known until run time as opposed to early binding where
- the type is known at compile time. Every subprogram call in this
- entire tutorial, up to this point, has been early binding.
-
- You will note that even though the method Output_A_Message only
- knows about the objects of type Vehicle, it has the ability to pass
- through other types, provided of course that they are descendant
- types of Vehicle. The method Output_A_Message only passes the
- message through, it does not do the selection. The selection is
- done by the objects themselves which answer the messages passed to
- them. This means that the sender does not know where the message
- will be answered from, and it is up to the receiver to find that
- a message is being sent its way and to respond to it. It is often
- said that the supplier (the method doing the work) must make the
- decision to answer the message, rather than the client (the user
- of the work done). The burden is placed on the supplier to do the
- right thing.
-
- If a method is declared virtual, all methods of that name must also
- be virtual including all ancestors and all descendants. It is not
- possible to declare part of the methods of the same name virtual
- and part standard. All parameter lists for all virtual methods of
- the same name must also be identical since they must all be capable
- of being called by the same method call.
-
-
-
-
- Page 15-2
-
- Chapter 15 - Virtual Methods
-
- ASSIGNING DESCENDANTS TO ANCESTORS?
- _________________________________________________________________
-
- It is legal in any object oriented language to assign a descendant
- object to an ancestor variable but the reverse is not true. A
- vehicle, for example, can be used to define a car, a truck, a bus,
- or any number of other kinds of vehicles so it can be assigned any
- of those values. A car on the other hand, is too specific to be
- used for the definition of anything but a car, so it cannot have
- any other value assigned to it. A vehicle is very general and can
- cover a wide range of values, but a car is very specific and can
- therefore only define a car.
-
-
- WHY USE A CONSTRUCTOR?
- _________________________________________________________________
-
- The constructor is absolutely required in this case because of the
- way the authors of TURBO Pascal defined the use of virtual
- functions. The constructor sets up a pointer to a virtual method
- table (VMT) which is used to find the virtual methods. If there
- is no pointer, the system jumps off to some unknown location and
- tries to execute whatever happens to be there and could do almost
- anything at that unknown and undefined point in the code. So it
- is important to call a constructor once for each object as is done
- here so the pointer to the VMT can be initialized to the proper
- value. If you make several objects of one type, it is not enough
- to call a constructor for one object and copy that object into each
- of the other objects. Each object must have its own constructor
- call in order to prevent a system crash.
-
- The strange looking code in line 6 tells the system to check each
- call to a virtual function to see if the constructor has been
- called. This slows the program down slightly but will result in
- an error message if a virtual method is called prior to its VMT
- being properly set up with a constructor call. After a program is
- thoroughly tested, the code can be removed from line 6 to speed up
- the program slightly by eliminating the checks. Be warned however,
- that a call to a virtual method without A VMT will probably result
- in the computer hanging up.
-
-
- VIRTUALS AND POINTERS
- _________________________________________________________________
-
- The example program named VIRTUAL3.PAS is nearly ==============
- identical to the last program except that this VIRTUAL3.PAS
- program uses pointers to objects instead of using ==============
- the objects directly.
-
- You will notice that once again, the methods named Message are all
- defined as virtual and a pointer type is defined for each object
- type. In lines 99 through 101, three pointers are declared and
- memory is dynamically allocated on the heap for the objects
-
- Page 15-3
-
- Chapter 15 - Virtual Methods
- themselves. The objects are all sent a constructor message to
- initialize the stored data within the objects and to set up the VMT
- for each. The rest of the program is nearly identical to the last
- program except that Dispose procedures are called for each of the
- dynamically allocated objects. The code used in line 6 of the last
- program to force a check of each virtual method call has been
- removed to illustrate that it doesn't have to be there if you are
- sure a message is sent to a constructor once for each object with
- a virtual method.
-
- Compiling and executing this program will give the same result as
- the last program indicating that it is perfectly legal to use
- pointers to objects as well as the objects themselves.
-
-
- AN ANCESTOR OBJECT
- _________________________________________________________________
-
- The example program PERSON.PAS is not a complete ==============
- program at all but only an object definition PERSON.PAS
- within a unit. This unit should pose no problem ==============
- for you to understand so we will not say much
- except to point out that the method named Display
- is a virtual method.
-
- This example program, as well as the next two example programs,
- have been carefully selected to illustrate the proper way to
- package objects for use in a clear understandable manner.
-
- Compile this unit to disk in order to make it available for use in
- the remainder of this chapter.
-
-
- SOME DESCENDENT OBJECTS
- _________________________________________________________________
-
- The example program named SUPERVSR.PAS is another ==============
- unit which contains three descendants of the SUPERVSR.PAS
- previously defined object named Person_ID. You ==============
- will notice that each of the objects have a method
- named Display which is virtual just as the same
- method in the ancestor object was.
-
- The interface for each object has been purposely kept very simple
- in order to illustrate the use of objects. The implementation has
- also been kept as simple as possible for the same reason so the
- diligent student should have no trouble in understanding this unit
- completely.
-
- Once again, be sure to compile this unit to disk in order to make
- it available for use in the next few example programs.
-
-
-
-
-
- Page 15-4
-
- Chapter 15 - Virtual Methods
-
- A COMPLETE EMPLOYEE PROGRAM
- _________________________________________________________________
-
- Although the program named EMPLOYEE.PAS is a very ==============
- short program that does very little, it is a EMPLOYEE.PAS
- complete program to handle a very small amount of ==============
- data about your employees.
-
- You will notice that we declare an array of ten pointers to the
- Person_ID object and one pointer to each of the three descendant
- objects. In the main program we send a message to the constructor
- for each of the array elements. Inspection of the Person_ID.Init
- code will reveal that this initialization does nothing. It is used
- to initialize the pointer to the VMT for each object, so the
- message must be sent. We then dynamically allocate six objects of
- assorted descendant objects being careful to send a message to the
- constructor for each object. This is done to generate a VMT for
- each object as it is allocated. Finally, we send a message to the
- first six objects pointed to by the array of pointers instructing
- them to display their values.
-
- When the program is compiled and executed, we find that the virtual
- methods were called as explained in the last example program. Even
- though only one kind of pointer was passed to the Display method,
- three different messages were actually displayed, each message
- being of the proper kind based on the type of pointer used.
-
- You will notice how clean and neat the main program is. It is
- extremely easy to follow because all of the implementation details
- have been moved to the objects themselves. Once the objects are
- carefully defined and debugged, the main program is usually a snap
- to write and debug.
-
- Object oriented programming requires a whole new mindset over the
- procedural methods you have been using but after you catch on to
- the technique, you will find your programs much easier to debug and
- maintain. The one thing you should avoid is the use of too many
- objects in your first program. It is best to define a few simple
- objects for your first attempt at object oriented programming and
- write the rest of the program using standard procedural methods.
- Then as you gain experience, you can begin using more and more
- objects until you finally write a program that is essentially all
- objects. Of course, you will find that you will always write at
- least part of your program in a standard procedural format as was
- done in EMPLOYEE.PAS in this chapter.
-
- PROGRAMMING EXERCISES
- _________________________________________________________________
-
- 1. Add a new object type to SUPERVSR.PAS to define a Consultant
- defining appropriate data fields for him, then add a couple
- of Consultant type objects to EMPLOYEE.PAS to use the new
- object type.
-
-
- Page 15-5