Dynamic-Binding

advertisement
1
ָ
Dynamic Binding





oop
Binding
Binding time
Motivation
Dynamic Binding
High Level Methods
‫נ ן‬
2
ָ
Binding Time
 Binding: linking between messages and methods
Inclusion Polymorphism + Overriding = Binding Question
 The same entity may refer to objects of different classes,
each of which has a different implementation of the same
method
More generally, binding time is the time when an attribute of some
portion of a program, or the meaning of a particular construct is
determined
 Compile Time
 Link Time
 Execution Time:
• Program Init
• Procedure/function begin
• Statement Execution
 Static Binding (AKA Early Binding): the compiler uses
the type of variables to do the binding at a compile (link)
time
 Dynamic Binding (AKA Late Binding): the decision is
made at run time based on the type of the actual values
oop
‫נ ן‬
ָ
3
Main Binding Techniques
Early (static) binding, is the binding of functions in
a program at compile time.
The programmer knows the type of data for each
function called. For example:
AddRealNums(x, y)
x, y - of type real.
Late (dynamic) binding of the message selector to
the appropriate method at run time.
The programmer doesn't know the specific method that
will be used. For example:
AddNumbers(x, y)
x, y - are number objects.
oop
‫נ ן‬
ָ
4
Static vs. Dynamic Types
 Consider the call:
Manager
M;
M.raise_salary(10);
Employee
raise_salary
print+
 What is the type of this in the called method?
 Static Type:
Employee *
 What can be determined in compile time
 Dynamic Type:
Manager *
Manager
print++
 Actual type, as determined in run time
 No simple way for the programmer to examine the
dynamic type
 Suppose that raise_salary calls print, then,
which version of print will be called?
oop
 Based on the static type? or,
 Based on the dynamic type?
‫נ ן‬
ָ
5
Static vs. Dynamic Binding
 Static Binding: binding based on static type.
 More efficient
 Less flexible
 Static type checking leads to safer programs
 Dynamic Binding: binding based on dynamic type.
 Less efficient
 More flexible
 May need dynamic type checking!
 As it turns out, dynamic binding is the only
reasonable choice:
 Why?
 If static typing is so good, why “spoil” it with dynamic
binding?
oop
‫נ ן‬
ָ
Motivation I: Containers
6
Employee
print+
Manager
Engineer
print++
print++
SalesPerson
print++
#define SIZEOF(a) (sizeof(a)/sizeof(*a))
...
Manager Alice, Bob;
Engineer Chuck, Dan, Eve;
SalesPerson Faith, Gil, Hugh;
Which print should
Employee Ira, Jim, Kelly;
....
be called here?
Employee *delegation[] =
{ &Bob, &Dan, &Faith, &Kelly};
...
for (int i = 0; i < SIZEOF(delegation); i++)
delegation[i]->print(cout);
oop
‫נ ן‬
ָ
7
Another Container Example
 A display list in a graphic application.
 List elements:
 Objects of subclasses of class Shape:
 Points, lines, triangles, rectangles, circles, etc.
 We want the list to contain elements of type Shape,
but each should be capable of preserving its own
special properties.
 If we loop over the list and send each element in it
a draw message, the element should respond
according to its “dynamic type”.
oop
‫נ ן‬
ָ
8
Motivation II: High Level Methods
 High Level Methods: methods which are coded
using only the public interface of a class.
Shape
 Facilitate code reuse in inheritance.
location
class Shape {
Point location;
public:
Which hide should be
...
void move(Point delta) called here?
{
hide();
location += delta; Which draw should be
called here?
draw();
}
...
};
class Rectangle: public Shape {
public:
void hide(void) const { ... }
void draw(void) const { ... }
};
oop
draw*
hide*
move+(delta)
Some Shape
draw+
hide+
‫נ ן‬
9
ָ
Motivation III: External Functions
Shape
void duplicate(const Shape *base)
{
enum {Dx = 12, Dy = 30};
Shape *clone = base->clone();
clone->move(Dx,Dy);
clone->draw();
}
clone+, draw+
Star
clone++, draw++
Which version of
draw() and clone()
should be called here?
oop
‫נ ן‬
ָ
10
Dynamic Binding is the Answer!
 The rule: A called method should be selected based on the
actual type of the object it is sent to.
 Meaningful only for reference semantics.
 Value semantics: dynamic type == static type.
 This is why this is a pointer to the object, rather than the object
itself.
 In a “better C++” this would be a reference to an object.
• Archaic C++ code used the idiom this = 0.
 All methods in Smalltalk, Eiffel and all other “decent”
object-oriented programming languages are dynamically
bound.
oop
‫נ ן‬
ָ
11
Dynamic Binding in C?
enum Shape_type {
rectangle,
circle,
line,
...
};
Strong
Coupling
struct Shape {
int x, y;
... /* Other common fields */
Shape_type type;
union {
struct Rectangle {
...
} r;
struct Circle {
...
} c;
struct Line {
...
} l;
...
/* Other shape kinds
*/
} data;
};
oop
void rotate(Shape *p)
{
switch (p->type) {
case rectangle:
...
case circle:
...
case line:
...
...
}
pointers to
}
functions can be
used instead.
void draw(Shape *p)
{
switch (p->type) {
case rectangle:
...
case circle:
...
case line:
...
...
}
}
‫נ ן‬
ָ
12
Disadvantages of the C Solutions
 Implicit assumption: consistency between value of
the type tag and usage of the union field data.
 Programmer’s responsibility: no compiler aid or checking
 Dispersed coding: the code for different operations
on the same shape is spread all over the program.
 Difficult to understand
 Insusceptibility to change: whenever a new kind of
shape is introduced, the following must be changed:





Definition of Shape_type
Definition of Shape
Some OO programming
Function rotate
languages do not include a
Function draw
switch like statement, just
All other functions
because of the above bad usage
of switch!
oop
‫נ ן‬
ָ
The Shapes Example in C++
The specialized code is associated
with the type, not with each
function. OOP promotes the shift
of focus from operations to
operands
class Shape {
public:
virtual void draw(void);
virtual void hide(void);
virtual void rotate(int deg);
...
protected:
int x, y;
... /* Other common fields */
};
class Circle: public Shape {
public:
virtual void draw(void) { ... }
virtual void hide(void) { ... }
//...
The type tag is hidden, and
};
class Line: public Shape {
maintained by the compiler
public:
virtual void draw(void) { ... }
virtual void hide(void) { ... }
//...
};
class Rectangle: public Shape {
public:
virtual void draw(void) { ... }
virtual void hide(void) { ... }
//...
};
oop
13
‫נ ן‬
14
ָ
Downcasting vs. Dynamic Binding
void draw(Shape *p)
{
if (Circle *q = dynamic_cast<Circle *>p) {
// Draw circle
...
} else if (Line *q = dynamic_cast<Line *>p) {
// Draw line
...
} else if (Rectangle *q = dynamic_cast<Rectangle *>p) {
// Draw rectangle
...
}
...
}
RTTI considered harmful:
 Order of classes in the if chains is significant
 Module must change whenever new class is added to the
hierarchy
oop
‫נ ן‬
ָ
15
Dynamic Binding and
the Container Problem
 Given is a set of employees as in
Employee *department[100];
 Then, how can we determine if a department[3] is a
manager or not?
 Dynamic Binding Answer:
 The question is wrong!!!
 There is never a need to determine the dynamic type of an
object.
 Differences between objects:
 Different state
 Differences between classes:
 Different implementation
 Usage of RTTI in all but very special cases indicates a
misunderstanding of the power of dynamic binding.
oop
‫נ ן‬
16
ָ
High Level Methods
Dynamic binding makes methods truly polymorphic. The
same code will do different things for different objects:
void Shape::move(Point delta)
{
hide();
location += delta;
draw();
}
Internal (in-class) dynamic binding
 Low level methods: implemented only using data members
 code not affected by overriding
 High level methods: may use also other methods
 partially polymorphic code
 Outer level methods: methods implemented solely with
(externally accessible) methods
 fully polymorphic code
oop
‫נ ן‬
17
ָ
Dynamic Binding and Static Typing
 Static typing: guarantee that a method exists
 A variable of type T can contain only objects of type T, or of type
T', where T' is derived from T.
 A message to an object is legal only if its static type recognizes it.
 Dynamic binding: make sure that the right method is
selected.
 The method invoked for an object depends on its dynamic type.
 Static typing + Dynamic binding: the right combination of
safety and power
 Examples: Eiffel, C++, Java, Object-Pascal, Turbo-Pascal, etc.
oop
‫נ ן‬
ָ
18
C++ Example
struct Base {
virtual void f(void) { ... }
void g(void) { ...}
};
struct Derived: public Base {
virtual void f(void) { ...} // Override f() of Base
void g(void) { ...} // Override g() of Base
void h(void) { ...}
} y;
Base *px = &y;
px->f(); // The right method
px->g(); // The wrong method
px->h(); // Compile time error! No guarantee that the method exists
oop
‫נ ן‬
ָ
19
Comparison of Binding Techniques
 Dynamic binding is more flexible. Static is more
efficient.
 Static types are more efficient.
 Calling static methods is more efficient.
 Static method binding may give better error
detection, just as static typing gives better error
detection.
 Usage:
 Static binding: homogenous set of objects that are similar to
an existing class; inheritance simply makes the new set of
objects easier to implement.
 Dynamic binding: heterogeneous mix of objects that share
operations that are conceptually the same, but may have
different implementations.
oop
‫נ ן‬
Download