Title: Object Oriented Programming and Object Oriented Design
1Object Oriented ProgrammingandObject Oriented
Design
- Programming Languages
- Robert Dewar
2Object Oriented Programming
- OOP provides three fundamental functionalities
- Type extension
- Inheritance
- Dynamic Polymorphism
3Type Extension
- The problem, given an existing type, add
additional capabilities retaining the original - Make the extended type look as much like the
original as possible - Typical implementation, add fields or components
to an existing record type.
4Faking Type Extension
- Could make a new record
- With new components
- And retaining the old type as one component
- type Ext is record Parent Old Newf
Integerend record - But that would not look much like original
- If Newobj is of type Ext
- Cannot say Ext.Value
- Must say Ext.Parent.Value
5Inheritance
- Goes along with type extension
- When a type is extended
- New type has all the operations of the old type,
with the same meaning. - Of course they do not know about the new fields,
and do not reference them - But most code that worked for the base type works
for the extended type without change
6More on Inheritance
- Cannot always use operations of base type
- May need to mess with new fields
- In particular constructors must do so
- May have different semantics from new field
- Should be able to override inherited operations
when type is extended - Must override constructors
- Can also add new operations for new extended type
7Faking Inheritance
- If you fake type extension
- You could add definitions for every operation.
Most would look like - procedure Operate (X Ext) isbegin Operate
(X.Parent)end Operate - Thats rather annoying
- And generates a lot of junk
8Ad Hoc Polymorphism
- More familiar term is overloading
- Applies in this situation as follows
- If we have several types derived from a common
parent with an operation Op - Suppose Op is overridden for some types
- If a variable has a particular type, then the
compiler can figure out what Op you mean from the
type of the variable
9Dynamic Polymorphism
- Also called dynamic dispatching
- Addresses problems where you have data structures
that are heterogenous and can contain different
kinds of data. - The data items are similar (e.g. obtained by type
extension from a common base). - And therefore have a similar set of operations.
10More on Dynamic Dispatching
- Now suppose we apply Op to a variable which at
run time can have more than one possible type. - What we want is that at runtime, the proper Op is
picked, based on the current type of the object
in the variable - This is called dynamic dispatching
11Faking Dynamic Dispatching
- We could have record fields that contained
pointers to the function to be called. - Actually thats how dynamic dispatching is
usually implemented - Record contains a pointer to a table
- Table has (at fixed offsets for any given
operation), address of function to be called. - Different types have different tables
12An Approach to Compare
- The issue is that we want a variable that can
have several different forms at runtime. - And we have some code that depends on which
particular form it has. - And some code that is the same for all types.
13Using Variant Records
- Instead of N types extended from a given base
type, use a variant record with N different
possibilities. - Fields of parent correspond to common fields in
the variant record - Code that does not depend on type just accesses
these common fields
14Using Variant Records (cont)
- Code that is not common has a case statement
- case Object.DiscrimValue is when val1 gt when
val2 gt end case
15Comparing the Approaches
- Consider that you have N operations and T types,
then potentially you have NT different
functions, but in practice many of the functions
are the same for many types. - Case statement means you have one unit per
operation, using case to select - Dynamic dispatching means you have one unit per
type, with overridden operations.
16Comparing the Approaches (cont.)
- If you often add operations, the case statement
approach is easier, add one new unit for new
operation providing base code with case
statements as required - If you often add types, the dynamic dispatching
approach is easier, add one new unit for new type
overriding any operations where base code is
wrong.
17OOP and Reuse
- By making your types extendible
- You increase reuse capabilities
- Instead of editing your code in places where it
does not apply - A client extends your types, and overrides your
code where it does not apply
18Object Oriented Design
- Has nothing to do with OOP per se
- Relates not to language features but to the
design approach - It may be that OOP features are useful for object
oriented design (OOD).
19OOD The Basic Idea
- The problem is modeled as a set of objects,
preferably related to the structure of the
problem, that represent real objects in the
world. These objects have state. - Computation proceeds by passing messages
(requests, signals, commands, reports) between
objects.
20How does OOD relate to OOP
- In the real world, objects are built by
specializing more general notions - A Toyota Previa is an instance of Car with extra
info, which is an instance of Vehicle with extra
information, etc. - Type extension
- All cars work mostly the same
- Inheritance
- But for some features, cars differ
- Dynamic dispatching
21OOP Features in Ada 83
- Ada 83 provides features for
- Inheritance
- But does not provide
- Type extension
- Dynamic dispatching
- Inheritance is provided via derived types
- Other OOP features deliberately omitted
- Designers were very familiar with Simula-67
- But felt that genericity was a better approach
22Derived Types
- Declare a type and some operations on it
- type Base is .procedure Print (Arg
Base)function New_Base return Base - Now derive a new type
- type Mybase is new Base
- All operations are available on Mybase Including
for example Print and New_Base - But you can redefine (override) any inherited
operations.
23OOP In Ada 95
- Genericity is not enough
- Market demands OOP features
- So in Ada 95 features are added for
- Type Extension
- Dynamic Dispatching
- But multiple inheritance is deliberately omitted
24Tagged Types in Ada 95
- A tagged type has a dynamic tag showing what type
the object is. Otherwise it looks like a record - type Base is tagged record X Integer Y
Floatend record - Can also have tagged private types
- type Base is tagged private
- Completion must be tagged record
25Type Extension
- A tagged type can be extended
- Using an extension of derived type idea
- type Mybase is new Base with record B
Boolean D Durationend record - All operations are inherited
- Except for constructors (functions returning
values of type Base) - Constructors must be overridden
- Since they need to know about the new fields
26How type Extension Works
- New fields are added at the end of the record,
with original fields at the start. - A subprogram that is only referencing the
original fields can do this on the base type or
any type derived from it. - Because the original fields are always at the
same offset from the start of the record. - This model does not extend well to the case of
multiple inheritance.
27Type extension and overloading
- Suppose a client has
- B Base
- M Mybase
- And there is an operation D that was not
overridden - D (B) D (M)
- Correct proc called, but in fact does same thing
- And there was an overridden operation O
- O (B) O (M)
- Correct proc called (static overloading)
28Converting Among Types
- Suppose we have an operation Q that is defined
for Base and was not inherited - Because it was not defined in original package
- And now we have a Mybase
- M Mybase
- And we want to call Q on M
- Q (M) -- no good, wrong type
- Q (Base (M)) -- thats ok, a view conversion
29Using conversion when Overriding
- Suppose we have a procedure Dump defined on Base
- For Mybase we want to dump the new fields and
then call the original dump - procedure Dump (X Mybase) isbegin dump
new fields Dump (Base (X)) -- calls
original Dumpend Dump
30Converting the Other Way NOT
- Suppose we have an operation M that is defined
for Mybase, and we have an object of type Base - B Base
- And we want to apply M to B
- You are out of luck, cant do it
- After all M might refer to extended fields!
31Class Variables
- Suppose you want a data structure that holds a
mixture of objects of type Base and Mybase. - The type BaseClass is a type that includes
values of tagged type Base and all types derived
from Base. - type Bptr is access BaseClass
- BC_Ptr Bptr new Base(.)BC_Ptr new
Mybase(.)
32Dynamic Dispatching
- If a subprogram, say Draw is defined as a
primitive operation of type Base (defined along
with type Base) - Then not only is it inherited by any type derived
from Base - But it is also defined on BaseClass
33Special Treatment of BaseClass
- The subprogram
- procedure Draw (Arg BaseClass)
- That is derived automatically
- Has special semantics
- It is called with an object of the appropriate
type (e.g. BC_Ptr.all) - The result is to call the version of Draw that is
appropriate to the actual run-time type of the
argument (looks at the tag)
34How Dynamic Dispatching Works
- Tag is actually a pointer to a table
- One table for each type
- In our example, two tables
- One table for Base
- Different table for Mybase
- Table contains pointers to subprograms
- Put new ones at end
- First entries in Mybase table are a copy of the
entries in the Base table unless overridden.
35Object-Oriented programming in C
- Classes as units of encapsulation
- Information Hiding
- Inheritance
- polymorphism and dynamic dispatching
- Storage management
- multiple inheritance
36Classes
- Encapsulation of type and related operations
- class point
- double x,y //
private data members - public
- point (int x0, int y0) //
public methods - point () x 0 y 0 // a
constructor - void move (int dx, int dy)
- void rotate (double alpha)
- int distance (point p)
37A class is a type objects are instances
- point p1 (10, 20) // call constructor
with given arguments - point p2 // call default
constructor - Methods are functions with an implicit argument
- p1.move (1, -1) // special syntax to
indicate object - // in other languages might write move
(p1, 1, -1) - // special syntax inspired by
message-passing metaphor - // objects are autonomous entities that
exchange messages.
38Implementing methods
- No equivalent of a body each method can be
defined separately - void pointrotate (double alpha)
- x x cos (alpha) - y sin
(alpha) - y y cos (alpha) x cos (alpha)
-
- // x and y are the data members of the
object on which the - // method is being called.
- // if method is defined in class
declaration, it is inlined.
39Constructors
- One of the best innovations of C
- special method (s) invoked automatically when an
object of the class is declared - point (int x1, int x2)
- point ()
- point (double alpha double r)
- point p1 (10,10), p2 p3 (pi / 4,
2.5) - Name of method is name of class
- Declaration has no return type.
40The target of an operation
- The implicit parameter in a method call can be
retrieved through this - class Collection
- Collection insert (thing x)
// return reference - modify data structure
- return this
// to modified object -
-
- my_collection.insert (x1).insert
(x2)
41Static members
- Need to have computable attributes for class
itself, independent of specific object e.g.
number of objects created. - Static qualifier indicates that entity is unique
for the class - static int num_objects 0
- point () num_objects //
ditto for other constructors - Can access static data using class name or object
name - if (point.num_objects ! p1.num_objects)
error ()
42Classes and private types
- If all data members are private, class is
identical to a private type visible methods,
including assignment. - A struct is a class with all public members
- How much to reveal is up to programmer
- define functions to retrieve (not modify) private
data - int xcoord () return x
- int ycoord () return y
- p2.x 15 //
error, data member x is private
43Destructors
- If constructor allocates dynamic storage, need to
reclaim it - class stack
- int contents int sz
- public
- stack (int size) contents new
int sz size - void push ()
- int pop ()
- int size () return sz
- stack my_stack (100) // allocate
storage dynamically - // when is my_stack.contents
released?
44If constructor uses resources, class needs a
destructor
- User cannot deallocate data because data member
is private system must do it - stack ( ) delete contents
- inventive syntax negation of constructor
- Called automatically when object goes out of
scope - Almost never called explicitly
45Copy and assignment
- point p3 (10,20)
- point p5 p3 //
componentwise copy - This can lead to unwanted sharing
- stack stack1 (200)
- stack stack2 stack1 //
stack1.contents shared - stack2.push (15) // stack1
is modified - Need to redefine assignment and copy
46Copy constructor
-
- stack (const stack s) // reference
to existing object - contents new int sz s.size()
- for (int I 0 I ltsz I) contents
I s.contents I -
- stack s1 (100)
-
- stack s2 s1 // invokes
copy constructor
47Redefining assignment
- Assignment can also be redefined to avoid
unwanted sharing - Operator returns a reference, so it can be used
efficiently in chained assignments one
two three - stack operator (const stack s)
- if (this ! s) //
beware of self-assignment - delete contents
// discard old value - contents new int sz s.size
() - for (int I 0 I ltsz I)
contents I s.contents I -
- return this
- stack s1 (100), s2 (200) s1
s2 // transfer contents
48Differences Between Ada and C
- C model much more specialized to the notion of
OOD - Distinguished first parameter is object involved
- No easy way of defining binary operators
- Prefix notation nice for objects but awkward for
values - C allows multiple inheritance
49Doing Multiple Inheritance in Ada
- We can have one field that we add be an instance
of some other base type. - We can use generics to parametrize this
additional type - Worked out examples in Ada 95 Rationale
- Which you can find at www.adapower.com
50OOP in Java