CS320 Lecture: Fundamental Concepts 7/24/96 - revised 8/18/98
Materials: Transparencies: Booch fig. 2-3, 2-4 (pp 30-31)
Booch p. 77
Class Description form for BankAccount class
Bank account class hierarchy
Terminology handout
I. Introduction
- ------------
A. In our last lecture, we saw that object orientation represents a new
software development PARADIGM - i.e. a new way of looking at and solving
problems - that is, a new way of thinking.
B. To explain how the OO paradigm differs from the procedural paradigm, we
might consider the following comparisons. (Perhaps these are a bit
overstated - but the essential contrast is certainly there.)
1. When analyzing about a problem procedurally, one thinks about the VERBS
in the problem description; when thinking about a problem the OO way,
one thinks about the NOUNS.
Example: Consider the design of the software for an automated teller
machine (ATM).
a. Approaching this from a procedural standpoint, one might end up
with a structure like this:
main
read_card
read_PIN
repeat
read_request
process_request
print_receipt
until finished
Notice that the name of each procedure consists of a verb followed
by a direct object (noun) that specifies the data the action of the
verb is performed upon. (This actually is a classical guideline for
naming procedures in structured design methodologies)
b. Approaching this from an OO standpoint, one would begin by listing
the relevant objects - e.g.
customer
transaction
account
receipt
etc.
Then one would identify the operations these objects can perform -
e.g. a customer can insert his/her card, enter a PIN and
request transactions; a transaction can do itself (we will soon see
that we will want to have different kinds of transactions that know
how to do themselves in appropriate ways); an account can deposit
money to itself, withdraw money from itself, etc. and a receipt can
print various sorts of information on itself.
2. When designing a problem solution procedurally, one designs PROCEDURES
that DO THINGS TO DATA; when thinking OO, one designs OBJECTS that
DO THINGS TO THEMSELVES FOR OTHER OBJECTS. (Data is passive; objects
are active).
Example: Note this in the above.
TRANSPARENCY: BOOCH FIGURES 2-3, 2-4
3. When programming procedurally, one focusses on producing HIERARCHIES
OF PROCEDURES. When programming OO, one focusses on producing
HIERARCHIES OF OBJECTS AND CLASSES.
Example:
a. In the procedural design above, we would end up with a procedural
hierarchy like this. (Note that one to the second level procedures
has been further refined into third level procedures)
main
|
_________________________________________________________
/ / | \ \
read_card read_PIN read_request process_request print_receipt
|
___________________________
/ / \ \
do_deposit do_withdrawl do_transfer do_inquiry
b. In the OO design, we would end up with a hierarchy of classes
representing various kinds of transactions, each of which embodies
the knowledge of how it is to be performed
Transaction
DepositTransaction
WithdrawlTransaction
TransferTransaction
InquiryTransaction
etc.
II. Basic Vocabulary
-- ----- ----------
A. In order to understand object-oriented methods, it is necessary to
clearly understand some fundamental terms. Unfortunately, in the world
of OO some terms are fairly universal while in other cases different
programming language communities use different terms for the same
thing (e.g. Smalltalk users might use one name for a concept that C++
users might call something else.) The following are the terms (or
sets of alternative terms) we want to learn now:
1. Object
2. Class
3. Encapsulation
4. Operation/Message/Method/Member Function
5. Polymorphism
6. Class Hierarchy
7. Inheritance
8. Attribute/Instance Variable/Data Member
9. Class Variable/Static Data Member
B. Obviously, the first term we have to consider is "OBJECT". Rather than
giving a formal definition, we will consider some characteristics of an
object.
1. An object is a something we create to model a portion of the "world"
a given software system must deal with.
a. An object may model a concrete entity in this world - e.g. in a
banking system, a customer may be modelled as an object, as would
a teller, an ATM, etc.
b. An object may also model an abstract entity - e.g. in a banking
system, individual accounts would also be objects - even though
their only physical, tangible existence may be as magnetic spots on
a disk somewhere.
c. An object may model an event - e.g. a bank deposit or withdrawl
d. An object may model an interaction between entities - e.g. in a
banking system an "ATM session" object may be used to model
the act of a customer object interacting with an ATM
e. As we shall see, the other kinds of objects may become necessary
as part of the implementation of a system, even though they don't
correspond directly to anything in the world the system models.
In object-oriented software design, a system consists of a collection
of objects that interact with one another in appropriate ways. Some
are relatively permanent (e.g., in a bank customers and accounts);
some are ephemeral (e.g. an ATM session).
2. "An object is characterized by a number of operations and a state
which remembers the effect of those operations" [Ivar Jacobson, 1992].
Example: In a bank system, an "account" object has operations like
deposit money, withdraw money, credit interest, print
statement etc. The effect of these operations is reflected
in the state of the account - specifically its balance.
3. The author of our text says an object has three properties:
ASK CLASS
a. State
b. Operations (or behaviors)
c. Identity
TRANSPARENCY - BOOCH P. 77
Two of these are the same as those cited by Jacobson. The third is
added to the list to point out that two or more distinct objects may
have the same state and operations, but still have distinct identies.
Example: Two bank accounts may happen to have the same balance (and
thus the same state) and both certainly would support the
same operations - yet they still have distinct identities.
C. Each object in a system belongs to some "CLASS". That is, a class is a
set of similar objects (called its INSTANCES). The class to which it
belongs determines its properties - e.g. what operations it can perform
(behaviors it can exhibit) and what information is remembered as part of
its state.
1. Often, many individual objects will be instances of the same
class. For example, in a bank system there would likely be a customer
class of which many individual customer objects are instances,
and an account class of which individual account objects are instances,
etc. However, it is also possible to have a unique object which is the
only one of its class in the system.
2. You may be thinking "the relationship between an individual object
and its class is like the relationship between a variable and its
type." This is true as far as it goes:
a. In a language like C++, individual objects are represented by
variables (named or anonymous). A variable's class is, in fact,
its data type as far as the syntax of the language is concerned,
and determines what operations are possible on it.
b. But there is more to the notion of class than this, as we shall
see.
3. Typically, a class is specified in terms of an INTERFACE (what clients
of objects that belong to the class are allowed to know and rely upon)
and an IMPLEMENTATION (which provides the services specified in the
interface in a way that a client of the class need not know.)
Example: To continue or bank account example, we might create a
BankAccount class whose instances are individual accounts.
a. The interface for this class would specify the operations possible
for an account - which might include:
i. A CONSTRUCTOR that sets up an account. The constructor might
require a single parameter - the initial balance for the account
- or it might simply create an account with initial balance
zero - or there might be two different constructors, one set up
each way.
ii. One or more MUTATORs that can alter the account
- We might have a mutator that deposits money in the account,
requiring a single parameter - the amount being deposited.
- We might have another mutator to withdraw money - also taking
a single parameter. This mutator might also enforce the rule
that we cannot withdraw more than the current balance of the
account, and would signal some kind of error if this were
attempted, or perhaps would activate some overdraft mechanism
that transfers money from another account or sets up an
automatic loan.
iii. An ACCESSOR that returns the current balance.
iv. A DESTRUCTOR that destroys an account when it is closed,
perhaps enforcing the rule that an account cannot be closed
unless its balance is zero.
b. The interface description implies that the state of an account
includes information as to the current balance in the account. The
implementation of this class would deal with issues like how
this balance is represented (as an integer number of cents? as a
real number? as a character string?) But since this is not part of
the interface, the users of the class need not worry about this.
c. Later in the course, we will be learning a more formal technique
for describing classes. The following is an illustration of how
this information might be recorded in the form we will learn then:
TRANSPARENCY: CLASS DESCRIPTION FORM FILLED OUT FOR ABOVE
D. A class serves to "ENCAPSULATE" the properties of an object. Typically,
the state of a particular object is not directly accessible - it cannot
be examined or altered by just anyone. Rather, the state is only
accessible through the operations which the class provides for that
purpose. This serves two purposes:
1. It allows the class designer to build appropriate constraints into the
operations - e.g. in a bank system, an account class may provide a
"withdraw" operation that enforces appropriate rules like "the
withdrawl amount cannot exceed the balance".
2. It allows the implementation of a class to be changed at a later date
without impacting the clients who use objects of the class.
Example: The account class we discussed above might originally be
implemented with the balance represented using an integer
that represents cents - e.g. a $500 balance would be
represented by 50000. If 32 bit unsigned integers are used,
this limits the balance to about $40 million. It the bank
(and its customers) prosper, a new implementation may need
to be developed!
These implementation changes may be necessitated by:
a. Changing requirements (as above) (Adaptive maintenance)
b. Fixing an error (Corrective maintenance)
c. Adding a new feature (Perfective maintenance)
d. Improving performance (Perfective maintenance)
etc.
E. Operation/Message/Method/Member Function
1. In our discussion of the interface to a class, we spoke of it as
listing operations that objects of the class can perform. (Note that
the object is the doer of the action - e.g. we think of a a bank
account object as depositing money to itself.)
2. In the OO world, the terms MESSAGE and METHOD are often used when
describing operations performed by an object. (These terms come out
of the Smalltalk world).
a. In an object-oriented system, objects interact with one another by
means of MESSAGES. For example, when a customer deposits money at
an ATM, the ATM object involved may create a deposit transaction
object which (after verifying that the deposit has actually been
put in the machine) may send a message to the appropriate account
object telling it to add the amount to its balance.
b. Each class defines METHODS for dealing with various messages.
Thus, the bank account object will have a deposit method that deals
with the deposit message. (Note that the name of the message and
the method are the same).
c. The reason for the distinction is that different objects may have
different methods for handling a given message, and thus may
respond to the same message in different ways. Thus, for example,
the withdraw method for a simple bank account object might signal
an error if the account receives a withdraw message whose amount
might overdraw the account. But a bank account that has overdraft
protection might use a different method to respond to the same
message - one that automatically transfers money from somewhere
else to cover the overdraft.
d. Note, then, that one object requests another object to do something
by sending it a MESSAGE. The message consists of a message
name and (possibly) a list of arguments. The object responds to the
message by using its own METHOD for doing so, and may return a
result back to the sender of the original message.
3. In C++, methods are called MEMBER FUNCTIONS. They are called
functions because they perform an operation; members, because they
belong to the particular object whose operation is being invoked.
F. The example we discussed about how different account objects might
respond differently to an overdraft introduces us to a very important and
fundamental concept of OO systems: POLYMORPHISM.
1. We will discuss polymorphism in more detail later. For now, it
suffices to say that the essence of polymorphism is that OO systems
provide mechanisms that allow different objects to do the same
thing in different ways - and the knowledge of how to handle this
resides with the object.
2. One place where polymorphism proves particularly useful is in
graphics systems.
a. Consider a drawing package of the sort that might be either a
stand alone application or integrated into an application such
as a word processor.
b. Such a package typically allows the user to create and manipulate
various sorts of shapes - lines, ovals, rectangles, polygons, etc.
At any given time, a drawing consists of a collection of such
shapes - each of which is represented by an object whose state
records the object's position, size, etc. (Indeed, such packages
are often called "object-oriented drawing packages" to contrast
them with bitmapped painting packages.)
c. There are times when the application has to redraw part or all of
the drawing - e.g. when the user opens a saved drawing or scrolls
the window to a previously hidden portion, or an obscuring window
is closed or moved, or when the drawing is to be printed
(in which case it is "drawn" on the printer).
i. To accomplish this, the drawing package causes the "Draw"
message to be sent to each object.
ii. When each object receives the message sent to it, it responds
in its own way. Circles do something quite different to draw
themselves than rectangles do, etc.
3. What makes polymorphism unique is that the knowledge about the
special properties of an object resides with the object - and thus
new kinds of objects can be added with minimal changes to other
components of the system.
4. Example: Consider adding a new kind of shape to a drawing package -
say a star.
a. If this package were implemented procedurally, there would
probably be a procedure Draw that looks something like this:
for each component of the drawing do
case shape of the component of
rectangle: DrawRectangle ...
oval: DrawOval ...
end
To add a new star shape, we would need to write a DrawStar
procedure, and we would need to modify the above case statement
to recognize the new shape and call the correct procedure.
b. If an OO approach were used, the corresponding code would be
for each component of the drawing do
send Draw message to this component
Notice that this does NOT have to change if we add a new shape!
G. One interesting question we will deal with in OO design is the matter
of thinking about how the various classes comprising a system are
related to one another. As we shall see, many kinds of relationships
are possible - but one of the most important is the relationships
that give rise to a CLASS HIERARCHY.
1. Consider our bank example we discussed earlier. A little bit of
thought should tell us that there are actually several kinds of
accounts we might have to deal with - e.g. checking accounts,
passbook savings accounts, time deposit savings accounts etc.
2. Each of these kinds of accounts has certain unique features - e.g.
a. Savings accounts earn interest - checking accounts often don't.
(In the rest of our discussion, we will assume that checking
accounts are of the "standard" non-interest-bearing variety).
b. Premature withdrawl from a time deposit results in a penalty.
etc.
3. This suggests that a bank account may need to be represented not by
a single class, but by a hierarchy of classes:
TRANSPARENCY - BANK ACCOUNT HIERARCHY
a. Note that we include here three concrete classes that represent
the unique kinds of accounts, plus one abstract base class that
represents the things they all have in common.
b. The concrete classes are connected to the base class by an "is-a"
relationship - e.g. a checking account "is-a" bank account.
4. In an object-oriented system, a class can be declared to be a
descendant (subclass) of another class. The parent class is called
the BASE CLASS or SUPERCLASS, and the new class is called the
DERIVED CLASS or SUBCLASS.
5. Every instance of a derived class is also an instance of the base class
- e.g. every checking account is also a bank account. Thus, the set
of instances of the subclass forms a subset of the instances of
the base class. (The set of all checking accounts is a subset of
the set of all bank accounts).
H. A notion closely related to the notion of class hierarchy is that of
INHERITANCE.
1. As part of the process of building a class hierarchy, we can identify
properties that instances of all the classes in the hierarchy have in
common, and properties that are unique to a particular subclass or
subclasses.
Example: What properties and operations do all bank accounts have
in common? ASK
- They have an owner and a balance
- They can respond to deposit, withdrawl, and balance inquiry
requests
What properties and operations do savings accounts have that
other accounts (e.g. standard checking accounts) do not?
- They have an interest rate
- They can credit interest, report total interest paid year
to date
What properties and operations do checking accounts have that
other accounts (e.g. savings accounts) do not?
- They maintain a record of what check numbers have cleared
- They can respond to an inquiry as to whether a particular
check number has cleared, and if so when and for what
amount.
2. One advantage of a class hierarchy is that it lets us implement the
properties and operations that all subclasses share once, in the
base class.
a. The descendant classes automatically INHERIT features from the
base class.
i. All of the base class's state information.
ii. All of the base class's operations.
b. In addition, the descendant class can have
i. Data members of its own
ii. Operations of its own
c. Further, it can have methods that OVERRIDE methods of the same
name that would otherwise be inherited from the base class - i.e.
the subclass performs all the operations that the base class
performs, but may perform some of them in a different way. (This
is how polymorphism is actually accomplished.)
3. One thing that can get confusing:
a. A derived class is called a SUBCLASS of its base class because
every instance of the derived class is also an instance of the
base class - but not necessarily vice versa. Thus, the objects
belonging to the derived class are a subset of the objects
belonging to the base class.
b. However, in general the state and operations of a derived class
form a SUPERSET of those of the base class - e.g. an instance of
the derived class can do everything an instance of the base class
can do, plus typically some additional things.
Example: CS students form a subset of the the class of college
students, but the tasks they can do constitute a superset
of the tasks all college students can do. (All college
students can presumably write a research paper, but only
CS students - and some others - can write programs!)
4. The example we have considered has involved a simple case, where we
have one base class and two subclasses derived from it. In complicated
systems, we can get hierarchies in the form of multi-level tree
structures.
Example - people at Gordon College
person
student employee
regular special faculty staff
fr. so. jr. sr. tenured non-tenured
I. Attribute/Instance Variable/Data Member
1. In our discussion of objects and classes, we have stated that each
object encapsulates certain state information (e.g. the account
balance). This information is stored in the class object in an
appropriate way - e.g. in C++ an object resembles a record structure
that has various fields to hold state information.
2. The data held within an object goes by various names - depending on
the programming language in use - e.g.
a. Attributes (generic term)
b. Instance variables (Smalltalk)
c. Data members (C++)
3. The particular attributes present in each object are specified as part
of the class definition - e.g. the class definition for a bank account
would specify that each bank account object has a balance attribute.
a. For practical reasons, the details of how the attribute is stored
may also need to appear in the class definition. (e.g. whether the
balance is stored as an integer, real number, string etc.)
b. However, good practice dictates that these details should not be
relied upon by the clients of the class, because they might change.
(This is a key component of encapsulation). Most OO programming
languages provide some mechanism for enforcing this, though some
do not.
TRANSPARENCY - BANK ACCOUNT CLASS DESCRIPTION (again)
J. Class Variables/Static Data Members
1. We have seen that each object typically records certain information
about its state in its instance variables. The kind of information is
spelled out in the class definition, but its value is distinct for
each object that is an instance of the class.
Example: The definition for the BankAccount class specifies that
each bank account has a balance - but the value of the
balance is (probably) different for each account object
2. There are times when it is useful to also have certain state
information that is shared by ALL instances of a class - e.g. they
all reference the same value, rather than each having their own.
Example: In most banks, all savings accounts (of the same general
kind) have the same interest rate, which may change from
time to time. If each savings account object holds its
own interest rate value, then all the objects need to be
updated when the rate changes; if they all share a single
value, then only one update is needed.
3. Most OO languages allow a class definition to specify that a certain
attribute is to exist in one copy that is shared by all instances of
the class.
a. In Smalltalk, this is called a CLASS VARIABLE (in contrast to an
instance variable).
b. In C++, this is called a STATIC data member.
K. To wrap this all up, some writers refer to the distinctive features
of OO systems by the acronym "PIE" - which stands for Polymorphism,
Inheritance, Encapsulation.
1. Encapsulation is something that is not unique to OO systems, of
course. For example, the notion of Abstract Data Types (ADT's) in
procedural systems is a form of encapsulation. However, in OO
systems encapsulation is carried further: an object encapsulates
not only data, but also operations on its data.
2. Polymorphism is a key distinctive of OO systems - perhaps the key
distinctive. In an OO system, different objects may handle the
same basic operation in different ways.
3. Inheritance is also a key distinctive of OO systems. New classes of
objects can be created by extending existing classes, rather than
from scratch.
a. It should be noted that there are some systems that use objects
(and support polymorphism) but lack inheritance. Such systems
are properly called OBJECT-BASED rather than OBJECT-ORIENTED.
b. Example:
i. The original version of Ada (Ada83) supports objects and
polymorphism, but not inheritance. Ada83 is an object based
language.
ii. The latest version of Ada (Ada95) adds inheritance (and many
other capabilities). Ada95 is a true OO language.
Copyright ©1998 - Russell C. Bjork