320 likes | 1.08k Views
Dynamic Binding. Binding Binding time Motivation Dynamic Binding High Level Methods. Binding Time. Inclusion Polymorphism + Overriding = Binding Question. Binding : linking between messages and methods
E N D
Dynamic Binding • Binding • Binding time • Motivation • Dynamic Binding • High Level Methods oop
Binding Time Inclusion Polymorphism + Overriding = Binding Question • Binding: linking between messages and methods • 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
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
Employee raise_salary print+ Manager print++ Static vs. Dynamic Types • Consider the call: Manager M; M.raise_salary(10); • What is the type of thisin the called method? • Static Type: Employee * • What can be determined in compile time • Dynamic Type: Manager * • 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? • Based on the static type? or, • Based on the dynamic type? oop
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
Employee print+ Manager Engineer SalesPerson print++ print++ print++ Motivation I: Containers • #define SIZEOF(a) (sizeof(a)/sizeof(*a)) • ... • Manager Alice, Bob; • Engineer Chuck, Dan, Eve; • SalesPerson Faith, Gil, Hugh; • Employee Ira, Jim, Kelly; • .... • Employee *delegation[] = { &Bob, &Dan, &Faith, &Kelly}; • ... • for (int i = 0; i < SIZEOF(delegation); i++) • delegation[i]->print(cout); Which printshould be called here? oop
Another Container Example • A display list in a graphic application. • List elements: • Objects of subclasses of classShape: • 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
Shape location draw* hide* move+(delta) Some Shape draw+ hide+ Motivation II: High Level Methods Motivation II: High Level Methods • High Level Methods: methods which are coded using only the publicinterface of a class. • Facilitate code reuse in inheritance. class Shape { Point location;public:... void move(Point delta) { hide(); location += delta; draw(); } ... }; class Rectangle: public Shape { public: void hide(void) const { ... } void draw(void) const { ... } }; Which hideshould be called here? Which drawshould be called here? oop
Shape clone+, draw+ Star clone++, draw++ Motivation III: External Functions void duplicate(const Shape *base) { enum {Dx = 12, Dy = 30}; Shape *clone = base->clone(); clone->move(Dx,Dy); clone->draw(); } Which version of draw() and clone() should be called here? oop
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
Dynamic Binding in C? void rotate(Shape *p) {switch (p->type) {case rectangle: ... case circle: ... case line: ... ... }} 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;}; pointers to functions can be used instead. void draw(Shape *p) {switch (p->type) { case rectangle: ... case circle: ... case line: ... ... }} oop
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 • Function rotate • Function draw • All other functions Some OO programming languages do not include a switch like statement, just because of the above bad usage of switch! oop
The Shapes Example in C++ class Shape {public:virtualvoid draw(void);virtualvoid hide(void);virtualvoid rotate(int deg); ... protected:int x, y; ... /* Other common fields */}; The specialized code is associated with the type, not with each function. OOP promotes the shift of focus from operations to operands class Circle: public Shape {public:virtualvoid draw(void) { ... }virtualvoid hide(void) { ... } //...}; The type tag is hidden, and maintained by the compiler class Line: public Shape {public:virtualvoid draw(void) { ... }virtualvoid hide(void) { ... } //...}; class Rectangle: public Shape {public:virtualvoid draw(void) { ... }virtualvoid hide(void) { ... } //...}; oop
Downcasting vs. Dynamic Binding void draw(Shape *p){ if (Circle *q = dynamic_cast<Circle *>p) { // Draw circle ... } elseif (Line *q = dynamic_cast<Line *>p) { // Draw line ... } elseif (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
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
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
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
C++ Example struct Base {virtualvoid f(void) { ... } void g(void) { ...} }; struct Derived: public Base {virtualvoid f(void) { ...} // Override f() of Base void g(void) { ...} // Override g() of Base void h(void) { ...} } y; Base *px = &y; px->f(); // The right methodpx->g(); // The wrong methodpx->h(); // Compile time error! No guarantee that the method exists oop
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