home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Chapter 15
- ENCAPSULATION & INHERITANCE
-
-
- Encapsulation is the cornerstone upon which object oriented
- programming is built, and without which it would not exist.
- We will cover the topic of encapsulation in this chapter in
- enough depth to illustrate its use and what it can do for you
- in software development. Because there are many new terms in
- this chapter, you could very easily become intimidated, and
- wish to simply give up on this new topic. You can be assured
- that the time spent studying encapsulation will be greatly
- rewarded as you apply this new technique in your software
- development efforts.
-
- Object oriented programming is not a panacea to solve all of
- your software problems, but it is a new and improved way of
- programming. In fact it is really more of a software
- packaging technology than a new method of programming. You
- will find that your software will be easier to write and debug
- as you gain experience using this new packaging method. Like
- any new endeavor however, it will require some effort on your
- part to master these concepts.
-
-
- OUR FIRST ENCAPSULATION
- ____________________________________________________________
-
- The example program named ENCAP1.PAS contains ==============
- our first example of encapsulation. In order ENCAP1.PAS
- to keep it easy to understand, it was kept ==============
- very short. This results in a program that
- does not illustrate the advantage of using
- object oriented programming, but it does give us a start in
- the right direction. With this in mind, load ENCAP1.PAS and
- we will study the code contained in it.
-
- Line 5 has our first new reserved word, object. This is used
- in much the same way that the reserved word record is used,
- but it has a much different meaning. An object is permitted
- to have not only data embedded within it, but also procedures,
- functions, and constructors. Constructors will be described
- in detail later. Since data plus procedures and functions can
- be grouped together in this fashion, the object is said to be
- encapsulated. An object is therefore a group of related data
- and the subprograms that operate on that data, all entities
- being very closely coupled together.
-
-
- WHAT IS A METHOD?
- ____________________________________________________________
-
- A method is a term used with object oriented programming, and
- for the time being we will simply say that a method is either
-
- Page 15-1
-
- Encapsulation and Inheritance
-
- a function or a procedure (including a constructor). A method
- is therefore a method for doing an operation on some data.
- Lines 8 through 10 are method headers and give the pattern for
- all calls to these methods which can be used by the compiler
- to check for the correct number and types of parameters.
-
- Once again, we promise to discuss the constructor soon. For
- the time being, simply think of it as another procedure.
-
- The entire object type definition is given in lines 5 through
- 11. This object contains two variables named length and
- width, each of type integer, and three methods which can be
- used to operate on the two variables. In the same manner that
- the definition of a type in Pascal does not actually give you
- a variable to use, only a pattern, the definition of an object
- type does not give you an object. We will declare the objects
- when we get to line 30 of this program.
-
- You will note that we are already using new terminology, but
- this is necessary. The field of object oriented programming
- has its own vocabulary and in order for you to understand
- technical articles in this field, you must begin now to learn
- the new terminology. It won't be too long until you feel
- somewhat comfortable with it.
-
-
-
- THE METHOD IMPLEMENTATION
- ____________________________________________________________
-
- The object type definition describes in detail what we can do
- with the object but we must now describe what actions will
- take place when each of the methods is called. The
- implementation for each method will define the operations for
- that method and are defined in lines 13 through 28 of this
- example program. The only thing that is really different
- about these methods is the way their headers are defined,
- namely the inclusion, in the header, of the object type name
- Box dotted to the method name. This is required, but we will
- wait until the next example program to define why it is
- needed.
-
- The observant student will also notice that we are referring
- to the object variables within the methods of that object
- without the object name dotted to the variable name. This is
- because the implied object name is automatically "with"ed to
- the variable names within the method implementations, allowing
- the variables to be directly referred to within the objects
- because of the definition of object oriented programming. It
- should be obvious that any mathematics or logical operations
- can be done within the implementations of the methods. In
- fact, you can perform any legal Pascal operations within the
- methods, just like you can in any Pascal function or
- procedure. Very short operations were selected here because
-
- Page 15-2
-
- Encapsulation and Inheritance
-
- we wish to illustrate the interfaces to the methods at this
- point in the tutorial.
-
-
- AN INSTANCE OF AN OBJECT
- ____________________________________________________________
-
- We need another new term at this point. When we use the
- object type to declare variables of that type as we do in line
- 30, we are creating instances of that object type. An
- instance is like a variable in conventional Pascal (non object
- oriented), except that it can do more and has some very
- interesting properties that a simple variable does not have.
- In line 30 we have created three instances of the object type
- named Box and each has two simple variables associated with
- it. Three methods are available which can be called to
- operate on these variables. We therefore have three objects
- named Small, Medium, and Large. In order to initialize the
- values stored within the objects we call the three objects in
- lines 34 through 36 to store values in their internal
- variables by dotting the name of the object to the name of the
- method we wish to call. You will note that this looks like
- the same technique we use to refer to the fields of a record.
-
- We display the area of the three boxes in lines 38 through 40
- using the same technique used to initialize the values stored,
- and the program is complete.
-
- We seem to have accomplished very little with this program
- that we could not have more easily accomplished with an even
- shorter standard Pascal program, and that is true. This
- program is only meant to introduce some of the mechanics of
- object oriented programming and additional programs will be
- used to illustrate some of the uses of this new technique.
-
-
-
- NEW TERMINOLOGY
- ____________________________________________________________
-
- You may note that we switched terminology halfway through the
- above paragraphs. We began by referring to the object types
- as object types and calling the variables declared in line 30
- instances. Later we began calling the instances objects. In
- this tutorial we will refer to the types as object types and
- the variables either as objects or instances. This
- terminology is consistent with current practice and should
- help you learn the new terminology.
-
- Another very important point is the fact that we pass a
- message to a method rather than call a subprogram as in
- conventional Pascal. The difference is rather subtle, but
- there really is a difference as we will see a little later in
- this tutorial.
-
- Page 15-3
-
- Encapsulation and Inheritance
-
-
- WHAT DID WE ACCOMPLISH?
- ____________________________________________________________
-
- In this program we defined an object type, then declared
- several instances of that type, one of which was named Small.
- The object named Small has two internal variables that should
- only be accessed via its methods, so we will refer to them as
- private data points. (Actually, they should be unavailable
- to any user outside of the method implementations but Borland
- chose not to make them private. It is therefore up to you to
- discipline yourself to not refer to them directly.) The
- proper way to use the object is to send a message to the
- object telling it to do something to itself. In the case of
- the Init method, we are telling it to store the two values in
- its private variables named length and width, and in the case
- of the Get_Area method, we are telling it to give us the
- product of its own internally stored width and length which
- we can then print out.
-
- Remember that in the beginning of this chapter we said that
- object oriented programming is a code packaging technique.
- That should help to explain some of the strange things we did
- in this program. As we continue through the example programs,
- we will see that everything here was done for a reason and you
- will eventually learn to use and prefer object oriented
- programming methods over the old familiar procedural
- programming method you have been using.
-
- Be sure to compile and execute this program to see if it does
- what the comments say it will do.
-
-
-
- DATA & CODE PROTECTION
- ____________________________________________________________
-
- The data and methods are protected from outside influence
- because they are packaged together with an object. Of even
- more importance is the fact that because they were to be
- packaged together, they were probably carefully thought out
- together during the design stage. This would probably result
- in a much more understandable program. The object keeps the
- data and methods together and keeps them working in close
- synchronization.
-
- An object type is sometimes referred to as an abstract data
- type in the technical literature discussing object oriented
- programming.
-
-
-
-
-
-
- Page 15-4
-
- Encapsulation and Inheritance
-
- MORE ENCAPSULATION
- ____________________________________________________________
-
- The example program named ENCAP2.PAS uses ================
- most of the same techniques as the last ENCAP2.PAS
- program but this is much more meaningful ================
- since it illustrates one of the simplest
- advantages of using object oriented
- programming.
-
- In this program, we define two object types in lines 5 through
- 19, Box and Pole. Each has its own unique kinds of variables
- associated with it, and each has three methods that can be
- used with these kinds of data. The method definitions in
- lines 33 and 44 clearly illustrate why the object name must
- be associated with the method name in the method
- implementation. This allows you to use the same method name
- in more than one object definition. In addition to the two
- method definitions named Set_Data given here, we could also
- define and use another procedure with the name Set_Data that
- was a normal Pascal procedure just like any others we have
- used in prior chapters of this tutorial. Using the same
- method name in several places is often referred to as name
- overloading in object oriented programming terminology.
-
- You will note that in lines 5 through 19 we define the object
- types which define what the object will do. In lines 21
- through 53 we define the method implementations which define
- how we do it. It is assumed that you know enough Pascal at
- this point to understand what each method does, so nothing
- more will be said about the details of this program.
-
- In lines 55 and 56, we declare several objects of the defined
- object types and use some of them in the main program. We can
- finally illustrate one of the biggest advantages of object
- oriented programming.
-
- We should all agree that it would be silly and meaningless to
- multiply the height of one of the poles by the width of a box.
- If we were using standard procedural programming with all
- variables defined globally, it would be a simple matter to
- accidentally write height*width and print out the result
- thinking we had a meaningful answer. By encapsulating the
- data within the objects, we would have to really work at it
- to get that meaningless answer because the system itself would
- prevent us from accidentally using the wrong data. This is
- true only if we have agreed not to use any of the data
- directly but to do all data access through the available
- methods.
-
- Encapsulation is a form of information hiding, but it is a
- rather weak form of it in TURBO Pascal because, as mentioned
- earlier, Borland chose not to make the variables within the
- object private. If the variables were defined as private
-
- Page 15-5
-
- Encapsulation and Inheritance
-
- variables, they would be unaccessible outside of the
- implementation for the object and the client would be forced
- to use only the methods provided by the author of the object
- to access the contained data. This would be true information
- hiding and would add some degree of protection to the internal
- data. It is up to you to never refer to the data within the
- object directly as stated by Borland in the OOP GUIDE included
- with the compiler.
-
- The careful student will notice that since all data is
- carefully tied up within the objects, inadvertent mixing of
- the wrong data is impossible provided a few simple rules are
- followed as discussed above. Once again, this is such a small
- program that it is difficult to see the advantage of going to
- all of this trouble. In a larger program, once the objects
- are completed, it is a simple matter to use them knowing that
- they are debugged and working.
-
- After the data are all printed out, some of the variables are
- changed in lines 78 through 80, and the same output statements
- are used to reprint the same data so you can observe the
- changes.
-
-
-
- A FEW RULES ARE NEEDED
- ____________________________________________________________
-
- As with any new topic, there are a few rules we must follow
- to use this new technique. The variables must all be declared
- first in the object followed by the method definitions. The
- names of all variables within an object must be unique and
- may not be repeated as the names of any of the formal
- variables in any of the methods. Thus length, width, len, and
- wid must be unique as used in lines 6, 7, and 8. The names
- of formal variables may be reused in other methods however,
- as illustrated in lines 8 and 9, and all names may be reused
- in another object. It should be obvious that all object type
- names must be unique within a given file and all objects must
- have unique names.
-
- All of the above rules are obvious if you spend a little time
- thinking about them. They should therefore not be a stumbling
- block to anyone with some procedural programming experience.
-
-
-
- WHAT IS A CONSTRUCTOR?
- ____________________________________________________________
-
- It is time to keep our promise and define just what a
- constructor is. In this present context, that of simple
- objects, the constructor does very little for us, but we will
- include one for nearly every object to illustrate its use.
-
- Page 15-6
-
- Encapsulation and Inheritance
-
- The constructor can be named anything desired but it would be
- best to stick with the convention and name every constructor
- Init as suggested by Borland. The constructor is used to
- initialize all values within an object and do any other setup
- that must be done to use an object. The constructor should
- be called once for every declared object. When we get to the
- topic of virtual functions, constructors will be absolutely
- required for every object, but for the simple objects we are
- using here, they are optional.
-
- It would be best to include a constructor in every object
- type, use the constructor to initialize all variables within
- the object, and call the constructor once for each instance
- of the object type. Until we get to virtual methods, none of
- this is required, but it would be good practice to get in the
- habit of doing it.
-
-
-
- WHAT IS A DESTRUCTOR?
- ____________________________________________________________
-
- A destructor is another method that can be used for cleanup
- when you are finished with an object. It is usually used in
- conjunction with dynamic allocation to assure that all
- dynamically allocated fields associated with the object are
- deallocated prior to leaving the scope of the object. A
- destructor is not illustrated in this tutorial but it should
- be easy for you to define and use one when you have a need for
- one.
-
-
-
- OUR FIRST INHERITANCE
- ____________________________________________________________
-
- Load the example program named INHERIT1.PAS ================
- for our first example of a program with INHERIT1.PAS
- inheritance. As always, our first encounter ================
- with this new topic will be very simple.
-
- In lines 7 through 14 we define a simple object type defining
- a vehicle and a few characteristics about the vehicle. We
- have the ability to store a few values and read them out in
- several ways. Of course, most of the interest is in the
- interfaces, so the implementations are purposely kept very
- small.
-
- In lines 17 through 35, we declare two additional object types
- that use the Vehicle type as a base for the new types as
- indicated by the previously defined name Vehicle in
- parentheses in the object definitions in lines 17 and 26. The
- Vehicle object is said to be the ancestor type and the two new
- object types are called descendant types. The descendant
-
- Page 15-7
-
- Encapsulation and Inheritance
-
- types inherit some information from the ancestor types
- according to well defined rules. The variables in the
- ancestor type are all included within the descendant types and
- are available in objects of the descendant types just as if
- they had been defined within the descendant types. For that
- reason, all variable names must be unique within the ancestor
- type and within each of the descendant types. A name can be
- reused in one or more descendants however, as is illustrated
- in lines 18 and 27 where the variable name Passenger_Load is
- used in both object types.
-
- The method names from the ancestor object types can be
- repeated in the descendant object types but this has the
- effect of overriding the method of the same name in the
- ancestor making the ancestor method unavailable for use in
- objects of the descendant types. Objects instantiated of the
- type Car therefore, have the three methods available in lines
- 11 through 13 of the ancestor type, the constructor in line
- 19 which overrides the constructor in line 10 of the ancestor
- type, and the function given in line 22. This object
- therefore has five different methods to perform its required
- operations.
-
- Objects of type Truck have five methods available also, the
- two in lines 11 and 12 and the one in line 33. The two in
- lines 29 and 34 of the descendant overrides the two in lines
- 10 and 13 of the ancestor object type.
-
- You should note that even though some of the methods were
- overridden in the descendant object type, they do not affect
- the ancestor, and instances of the Vehicle type have two
- variables and four methods available.
-
- In effect we have an object hierarchy which can be extended
- to as many levels as necessary to complete the task at hand.
- The most important part of object oriented programming is the
- definition of the objects in a meaningful manner, but it is
- not something you will learn to do overnight. It will take
- a great deal of practice until you can see the objects in any
- given project in such a way that a clear solution can be
- found. I was somewhat intimidated by the clever examples
- found in a classic text on object oriented programming until
- I talked to a man that had shared an office with the author
- at the time he was writing that particular book. I learned
- that what was finally put in the book was at least the fourth
- iteration of each problem and in some cases the seventh before
- he finally arrived at a good solution. We will have more to
- say about this as we progress through this tutorial.
-
-
-
-
-
-
-
- Page 15-8
-
- Encapsulation and Inheritance
-
- HOW DO WE USE THE OBJECTS?
- ____________________________________________________________
-
- The implementations of the methods are given in lines 39
- through 92 and should be self explanatory, except for a few
- notable exceptions. You will note that in line 81 we send a
- message to the Vehicle.Init method to initialize some data.
- A change to the Vehicle type will be reflected in the Truck
- type also because of this call. In lines 64 and 65 we are
- using some inherited variables just as if they had been
- defined as part of the descendant object types.
-
- In lines 96 through 98 we instantiate one of each and send a
- message to their constructors in lines 102 through 104 then
- print out a few of the stored values.
-
- Lines 113 through 116 are repeated in lines 120 through 123
- where they are placed within a with section to illustrate that
- the with can be used for the calls to the methods in the same
- manner that it is used for accessing the fields of a record.
- Any other details of this program can be gleaned by the
- diligent student. Be sure to compile and execute this program
- so you can verify the given result.
-
-
-
- AN OBJECT IN A UNIT
- ____________________________________________________________
-
- Load the example program named VEHICLES.PAS ================
- for an example of the proper way to package VEHICLES.PAS
- the object so it can be conveniently reused ================
- for another project.
-
- The object type definition is given in the public part of the
- unit so it is available to any Pascal program which needs to
- use it. The implementation of the methods are hidden in the
- implementation part of the unit where they are not directly
- available to any calling program. Note that it is also
- possible to define a few local methods within the
- implementation for use only within the implementation but none
- are illustrated here. There is no body to this unit, only the
- end statement in line 39 so there is no initialization code
- to be executed during loading. It would be perfectly legal
- to include an initialization body, but if you do, be sure to
- include a constructor to be called once for each object. This
- is to prepare you for the use of virtual functions which we
- will study in the next chapter.
-
- It will be necessary for you to compile this unit to disk so
- it can be used with the last example program in this chapter.
-
-
-
-
- Page 15-9
-
- Encapsulation and Inheritance
-
- ANOTHER OBJECT IN A UNIT
- ____________________________________________________________
-
- The example program named CARTRUCK.PAS ================
- continues the new packaging scheme by CARTRUCK.PAS
- including the two descendant object types in ================
- its interface after telling the system that
- it uses the Vehicles unit.
-
- The remainder of this unit is constructed just like the last
- one so nothing more needs to be said about it. Be sure to
- compile this unit to disk so it will be available for use with
- the next example program.
-
- Note that this unit could have been further divided into two
- separate units, one for each object type, but it was felt that
- it was important to illustrate that several can be combined
- in this manner if desired. In like manner, the last unit
- could have been combined with this unit, but once again, it
- was desired to illustrate the generality of program
- decomposition and packaging.
-
-
- USING THE OBJECTS DEFINED IN UNITS
- ____________________________________________________________
-
- Load the program named INHERIT2.PAS for an ================
- example that uses the units of the last two INHERIT2.PAS
- example programs and is identical to the ================
- program named INHERIT1.PAS.
-
- The only difference in these two programs is in the way the
- code was packaged. The second way is much more general and
- more conducive to good software engineering practices because
- it allows separate development of each of the three program
- units. Each can be refined independently of the other two and
- the overall package can be simpler to debug and maintain. It
- should be clear that any changes to the Car object, for
- example, will be localized to that single unit and not
- scattered all over the software terrain.
-
-
- AN ARRAY AND A POINTER
- ____________________________________________________________
-
- Examine the example program named ================
- INHERIT3.PAS for an example of the use of a INHERIT3.PAS
- pointer to an object and the use of an array ================
- of objects.
-
- This program is nearly identical to INHERIT2.PAS except for
- the addition of an array of Car type objects named Sedan[1]
- to Sedan [3], and the definition of a pointer to the Truck
- type object named Semi_Point. Lines 16 and 17 illustrate the
-
- Page 15-10
-
- Encapsulation and Inheritance
-
- initialization of the array of Sedan, and lines 23 through 26
- illustrates its use when the data is printed out. An object
- is dynamically allocated in line 18 and it is then initialized
- in the next line. Its use is illustrated in lines 28 through
- 40 and it is deallocated in line 41.
-
- TURBO Pascal 5.5 has an extension to the New procedure
- allowing the dynamic allocation and the initialization to take
- place in the same procedure call. The line
-
- New(Semi_Point, Init(1, 25000.0, 18, 5000.0));
-
- can be used to replace lines 18 and 19 in this program if you
- desire to do so.
-
- This program should illustrate that objects can be used with
- arrays and pointers just like a record. Be sure to compile
- and execute this program.
-
-
-
- WHAT IS MULTIPLE INHERITANCE?
- ____________________________________________________________
-
- Multiple inheritance allows the programmer to inherit data and
- methods from two or more ancestor objects. When this is done
- however, there is a real problem if there are two variables
- or methods of the same name and it is up to the programmer to
- somehow define which will be used by the descendent. Some
- object oriented programming languages allow multiple
- inheritance, but most do not. TURBO Pascal (version 5.5) has
- no provision for multiple inheritance, and Borland has made
- no indication at this time whether future versions will allow
- it.
-
-
-
- WHAT SHOULD YOU DO NOW?
- ____________________________________________________________
-
- You have reached a major point in your excursion of object
- oriented programming, because you now have most of the
- knowledge you need to do some serious object oriented
- programming. The best thing for you to do at this point is
- stop studying and get busy programming and using some of these
- techniques for your projects. The only topic left is the use
- of virtual methods and you can easily defer its use for a long
- time.
-
- One point should be made before you begin a serious
- programming project. Your first program could have too many
- objects and be nearly unreadable unless you strive to use only
- a few objects until you gain experience. Define only a few
- objects and write the majority of the program in standard
-
- Page 15-11
-
- Encapsulation and Inheritance
-
- procedural programming methods. Add a few more objects to
- your next project and as you gain experience, you will feel
- very comfortable with the use of objects and your programming
- methods will be very clear.
-
- Now is the time to begin using this new knowledge but enter
- the water slowly the first time.
-
-
- PROGRAMMING EXERCISES
- ____________________________________________________________
-
- 1. Modify ENCAP2.PAS in such a way to multiply the height
- of the short pole times the length of the medium box and
- print the result out. Even though this is possible to
- do, it requires you to expend a bit of effort to
- accomplish. Remember that you should not use the
- components of an object directly, only through use of the
- available methods.
-
- 2. Add an object named Pick_Up to INHERIT2.PAS of type Truck
- and initialize it to some reasonable values. Print out
- its loading and efficiency in a manner similar to the
- Semi.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 15-12