Dynamic Binding in Java

You might also like

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 19

1

Dynamic Binding
Binding Binding time Motivation Dynamic Binding High Level Methods

oop

Binding: linking between messages and methods Inclusion Polymorphism + Overriding = Binding Question

Binding Time

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

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?

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
Employee print+

Manager print++

Engineer 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

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

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+

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!


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.

The rule: A called method should be selected based on the actual type of the object it is sent to.

All methods in Smalltalk, Eiffel and all other decent object-oriented programming languages are dynamically bound.

oop

Dynamic Binding in C?
enum Shape_type { rectangle, circle, line, ... };

11

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

Strong Coupling

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.
Programmers 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++

13

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

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

You might also like