You are on page 1of 19

Lecturer 10

Computer Programming II

Static Polymorphism
Overview
What is Polymorphism?
Method Overriding
Function Call Binding
Static Binding
Static Polymorphism
Static Polymorphism: Problem

What is Polymorphism?
-Polymorphism is allowing objects of different types
to respond differently to the same method call.
-You have seen some obvious polymorphism in
method/function overriding.
- Method overriding is the idea that the definition
for a method declared in a superclass is
overridden in a subclass.
-In order to override a superclass method, the
method in the subclass must have the same method
name, same parameter list, same return type, and
same const-ness (const or not const).
3

Different objects invoke different version of methods


with the same name (speak())
class Animal {
public:
void speak() {
cout << "I'm an animal\n";
}
};
class Bird : public Animal {
public:
void speak() { // overriding
cout << "I'm a bird\n";
}
};
int main() {
Animal a;
a.speak(); // call Animal::speak()
Bird b;
b.speak(); // call Bird::speak()
return 0;
};

How does C++ knows


which method to call?
Through function call
binding

Output:
I'm an animal
I'm a bird

Function Call Binding


Connecting a function call to a function body is called binding
Function call binding is the process of determining what block
of function code is executed when a function call is made.
class Animal {
public:
void speak() { ... }
};
class Bird : public Animal {
public:
void speak() { ... }
};
int main() {
Animal a;
a.speak();
Bird b;
b.speak();
return 0;
};

Memory
0x7723

0x77b4

Function Call Binding


There are 2 types of function call binding:
Early/Static/Compile-time binding: Binding is
performed during compile-time, and is decided by
the compiler and linker (focus of this lecture)
Late/Dynamic/Runtime binding: Binding
occurs at runtime, based on the type of the object
calling the method. (Next lecture)

Static Polymorphism
It is the polymorphism that is implemented using
static binding
The compiler determines beforehand what
method definition will be executed for a
particular method call, by looking at the
type of the variable invoking the method

Static Polymorphism
Consider the following Animal hierarchy, subclass
Bird does not override superclass Animal
move() method
class Animal {
public:
void move() {
cout << "Moving";
}
};
class Bird : public Animal {
};

Animal
+ move()

Bird

Static Polymorphism
Call the move() method from an Animal object or a pointer to
an Animal object
int main() {
Animal a;
a.move(); // cout "Moving"
...
}

Animal::move() is called.
No problem

int main() {
Animal* a = new Animal;
a->move(); // cout "Moving"
...
}
9

Static Polymorphism
Call the move() method from a Bird object or a pointer to an
Bird object
int main() {
Bird b;
b.move(); // cout "Moving"
...
}

Animal::move() is called.
No problem

int main() {
Bird* b = new Bird;
b->move(); // cout "Moving"
...
}
10

Static Polymorphism
Call the move() method for a Bird object using a
pointer to an Animal
int main() {
Bird* b = new Bird;
Animal* a = b; // Upcasting
a->move(); // cout "Moving"
...
}

Animal::move() is called.
No problem

int main() {
Bird b;
Animal* a = &b; // Upcasting
a->move(); // cout "Moving"
...
}

11

Static Polymorphism
Static binding always occurs when subclass does not
override superclass method. It generally does not introduce
problem.
In all previous examples, output is always "Moving"
which is fine since subclass Bird does not provide a
different meaning/semantic for the move() method.
When subclass does override superclass method, static
binding is still used by default, but it may introduce
semantic/logical/precision problem when upcasting.
Consider if subclass Bird does provide a different
meaning/semantic for the move() method, static binding
will fail to adhere to the new meaning when upcasting.
12

Static Polymorphism
Now consider the following Animal hierarchy,
subclass Bird does override superclass Animal
move() method
class Animal {
public:
void move() { cout << "Moving"; }
};
class Bird : public Animal {
public:
void move() { cout << "Flying"; }
};

Animal
+ move()

Bird
+ move()
13

Static Polymorphism
Call the move() method from an Animal object or a pointer to
an Animal object
int main() {
Animal a;
a.move(); // cout "Moving"
...
}

Animal::move() is called.
No problem

int main() {
Animal* a = new Animal;
a->move(); // cout "Moving"
...
}
14

Static Polymorphism
Call the move() method from a Bird object or a
pointer to a Bird object
int main() {
Bird b
b.move(); // cout "Flying"
...
}

Bird::move() is called. No
problem
int main() {
Bird* b = new Bird;
b->move(); // cout "Flying"
...
}
15

Static Polymorphism: Problem


Call the move() method for a Bird object using a pointer
to an Animal object (upcasting)
int main() {
Bird* b = new Bird;
Animal* a = b; // Upcasting
a->move(); // cout "Moving"
...
Animal::move()
}

is still called but


Bird::move() is more
appropriate/precise/accurate in
the context. This happens when
upcasting

int main() {
Bird b;
Animal* a = &b; // Upcasting
a->move(); // cout "Moving"
...
}

16

Static Polymorphism: Problem


Call the move() method for a Bird object using a
reference to an Animal object (upcasting)
Animal::move() is still called but
Bird::move() is more
appropriate/precise/accurate in
the context. This happens when
upcasting
int main() {
Bird b;
Animal& a = b; // Upcasting via reference
a.move(); // cout "Moving"
...
}

17

Static Polymorphism: Problem


The solution to the upcasting problem we just
discussed is to use dynamic binding.
We'll discuss dynamic binding in the next lecture.

18

Static Polymorphism
To recap, static binding/polymorphism is fine when:
1.Calling methods defined in a particular class from an instance of
that class (both directly and via a pointer/reference to that class)
2.Calling methods defined in a superclass and publicly inherited
(but not overridden) in a subclass from an instance of the subclass
(both directly and via a pointer/reference to the subclass)
3.Calling methods defined in a superclass and publicly inherited
(but not overridden) in a subclass from an instance of the subclass,
via an upcasted pointer/reference to the superclass
4.Calling methods defined in a superclass and publicly inherited
and overridden in a subclass from an instance of the subclass
(either directly or via a pointer/reference to the subclass)
Static binding/polymorphism is not fine when:
1.Calling methods defined in a superclass and publicly inherited
and overridden in a subclass from an instance of the subclass, via
an upcasted pointer/reference to the superclass
19

You might also like