INTRO TO COMPUTER SCIENCE II
POLYMORPHISM
CS162
What’s the best way to print??
Question from the end of class last time
Previous answer: it depends
Better answer: it depends, but with details void print() can’t be chained, because it’s returning void << can be
In-Class Activity: Operator Overloading
Overload the comparison operators for the Animal class. Include the appropriate prototypes and definitions in the correct locations of the
interface and implementation files linked in the Canvas assignment
Things to think about:
What property of the Animal class makes sense to compare using < and > ?
What is the return type of the comparison operators?
What type of overload function am I going to use? Friend, normal, member function?
Polymorphism
(poly = “many”) + (morph = “forms”)
string Animal::get_name() {
return name;
}
void Animal::make_noise(int num) {
for (int i = 0; i < num; i++)
cout << "???" << " ";
cout << endl;
}
string Monkey::get_name() {
string monkey_name = "Honorable "+Animal::get_name();
return monkey_name;
}
void Monkey::make_noise(int num) {
for (int i = 0; i < num; i++)
cout << "yuh-ooh-aah" << " ";
cout << endl;
}
When a call to a member function executes different code depending on the type of object that invokes the function
2 types Compile time
Function overriding
Function/operator overloading Runtime
Function overriding
Vocab Refresh:
Overriding multiple functions with the same signature/prototype
Overloading multiple functions with the same name, but different arguments
Pointers, references, and derived classes
When you create a derived class, it is composed of multiple parts: one part for the inherited class, and a part for itself
Key feature of inheritance: you can assign a pointer or reference of the base class to a derived class
Which version of get_name() will run when we call
aptr2->get_name()?
Animal Class get_name() make_noise()
Monkey Class get_name() make_noise()
//using objects
Animal a1;
a1.get_name();
Monkey m1;
m1.get_name();
//using pointers
Animal *aptr = &a1;
aptr->get_name();
Animal *aptr2 = &m1;
aptr2->get_name();
Pointers, references, and derived classes
By default, since it is an Animal pointer, it can only see the parts of the animal class
So it will call the Animal version of get_name()
Why wouldn’t we just use a Monkey pointer?
Animal Class get_name() make_noise()
Monkey Class get_name() make_noise()
Animal a1;
a1.get_name();
Monkey m1;
m1.get_name();
Animal *aptr = &a1;
aptr->get_name();
Animal *aptr2 = &m1;
aptr2->get_name();
Pointers
Pointers allow us to treat an object as a different type without permanently losing data
Create an array of Base pointers instead of Base objects
Animal* array[2];
Monkey m1;
Lion l1;
array[0] = &m1;
array[1] = &l1;
for (int i=0; i<2; i++;){
array[i]->make_noise();
}
Polymorphism
Virtual functions
Special type of function that resolves to the most derived version of the
function that exists between the base and derived class
Keyword “virtual” indicates the compiler should wait until run-time to determine which version of the function should run
Isn’t explicitly needed for derived functions, but doesn’t hurt Can be overridden if it is re-defined in a child class
//in animal.h
virtual string get_name();
virtual void make_noise(int);
//in monkey.h
string get_name();
void make_noise(int);
Abstract Polymorphism
Abstract function
virtual void example() = 0;
Also known as pure virtual function
A virtual function that has no definition in the base class
Used when you are intending for child classes to implement the function
Abstract class
Any class that has one or more pure virtual functions
An abstract class cannot be instantiated (i.e. you cannot create an object out of an abstract class)
But you can use pointers & references to abstract class types
Polymorphism specifiers
//in derived class
Override specifier
Used when you want to tell the compiler that this function is intended
to override some function in the base class
Not required, but good to use because lowers the chance of bugs
Final specifier (function) virtual void example() final;
Used when you want to tell the compiler that no child class is allowed
to override this function
virtual void example() override;
Final specifier (class)
Used when you want to tell the compiler that no child class can exist for this class
class Bengal_Tiger final : public Animal {}
Let’s look at some code…
Animals and Monkeys again!