Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Polymorphism in C++


Russell Feldhausen
russfeldh@gmail.com

Previously...

class Person{
  private:
    int age;
  public:
    Person(int);
    int happyBirthday();
};

Person::Person(int anAge){
  age = anAge;
}

int Person::happyBirthday(){
  age = age + 1;
  return age;
}

Think-Pair-Share
What other examples can you come up with?

Polymorphism

noun: The ability to assume different forms or shapes


In programming, polymorphism allows an object to assume different forms and perform different operations based on its type.
An object can assume multiple types based on its class hierarchy (or inheritance).

void Person::happyBirthday() {
  age = age + 1;
}
void Student::changeMajor() {
  major = major + 1;
}
void Teacher::promotion() {
  title = title + 1;
}
void Administrator::promotion() {
  title = title + 1;
  salary = salary + 1;
}
class Person{
  public:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void changeMajor();
};
class Teacher: public Person{
  public:
    int title;
    void promotion();
};
class Administrator: public Teacher{
  public:
    int salary;
    void promotion();
};
int main(){
  Person person;
  person.age = 32
  person.happyBirthday();
  cout << person.age << endl;
  return 0;
}
class Person{
  public:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void changeMajor();
};
class Teacher: public Person{
  public:
    int title;
    void promotion();
};
class Administrator: public Teacher{
  public:
    int salary;
    void promotion();
};
void Person::happyBirthday() {
  age = age + 1;
}
void Student::changeMajor() {
  major = major + 1;
}
void Teacher::promotion() {
  title = title + 1;
}
void Administrator::promotion() {
  title = title + 1;
  salary = salary + 1;
}
int main(){
  Person person;
  person.age = 32
  person.happyBirthday();
  cout << person.age << endl; // 33
  return 0;
}
class Person{
  public:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void changeMajor();
};
class Teacher: public Person{
  public:
    int title;
    void promotion();
};
class Administrator: public Teacher{
  public:
    int salary;
    void promotion();
};
void Person::happyBirthday() {
  age = age + 1;
}
void Student::changeMajor() {
  major = major + 1;
}
void Teacher::promotion() {
  title = title + 1;
}
void Administrator::promotion() {
  title = title + 1;
  salary = salary + 1;
}
int main(){
  Student student;
  Person* person = &student;
  student.age = 42;
  student.major = 2;
  student.happyBirthday();
  student.changeMajor();
  cout << student.age << endl;
  cout << person->age << endl;
  cout << student.major << endl;
  return 0;
}
class Person{
  public:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void changeMajor();
};
class Teacher: public Person{
  public:
    int title;
    void promotion();
};
class Administrator: public Teacher{
  public:
    int salary;
    void promotion();
};
void Person::happyBirthday() {
  age = age + 1;
}
void Student::changeMajor() {
  major = major + 1;
}
void Teacher::promotion() {
  title = title + 1;
}
void Administrator::promotion() {
  title = title + 1;
  salary = salary + 1;
}
int main(){
  Student student;
  Person* person = &student;
  student.age = 42;
  student.major = 2;
  student.happyBirthday();
  student.changeMajor();
  cout << student.age << endl; // 43
  cout << person->age << endl; // 43
  cout << student.major << endl; // 3
  return 0;
}
class Person{
  public:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void changeMajor();
};
class Teacher: public Person{
  public:
    int title;
    void promotion();
};
class Administrator: public Teacher{
  public:
    int salary;
    void promotion();
};
void Person::happyBirthday() {
  age = age + 1;
}
void Student::changeMajor() {
  major = major + 1;
}
void Teacher::promotion() {
  title = title + 1;
}
void Administrator::promotion() {
  title = title + 1;
  salary = salary + 1;
}
int main(){
  Administrator admin;
  Teacher* teacher = &admin;
  Person* person = &admin;
  admin.age = 25;
  admin.title = 5;
  admin.salary = 12;
  teacher->happyBirthday();
  admin.promotion();
  cout << person->age << endl;
  cout << teacher->title << endl;
  cout << admin.salary << endl;
  return 0;
}
class Person{
  public:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void changeMajor();
};
class Teacher: public Person{
  public:
    int title;
    void promotion();
};
class Administrator: public Teacher{
  public:
    int salary;
    void promotion();
};
void Person::happyBirthday() {
  age = age + 1;
}
void Student::changeMajor() {
  major = major + 1;
}
void Teacher::promotion() {
  title = title + 1;
}
void Administrator::promotion() {
  title = title + 1;
  salary = salary + 1;
}
int main(){
  Administrator admin;
  Teacher* teacher = &admin;
  Person* person = &admin;
  admin.age = 25;
  admin.title = 5;
  admin.salary = 12;
  teacher->happyBirthday();
  admin.promotion();
  cout << person->age << endl; // 26
  cout << teacher->title << endl; // 6
  cout << admin.salary << endl; // 13
  return 0;
}
class Person{
  public:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void changeMajor();
};
class Teacher: public Person{
  public:
    int title;
    void promotion();
};
class Administrator: public Teacher{
  public:
    int salary;
    void promotion();
};
void Person::happyBirthday() {
  age = age + 1;
}
void Student::changeMajor() {
  major = major + 1;
}
void Teacher::promotion() {
  title = title + 1;
}
void Administrator::promotion() {
  title = title + 1;
  salary = salary + 1;
}

Subclass (Child or Derived Class)


What if I want something accessible by subclasses but NOT everyone?

Subclass (Child or Derived Class)


What if I want something accessible by subclasses but NOT everyone? Use the protected access modifier!

void Person::happyBirthday() {
  age = age + 1;
}
void Student::setAge(int anAge) {
  age = anAge;
}
int Student::getAge() {
  return age;
}
void Student::getOlder() {
  happyBirthday();
}
void Student::changeMajor() {
  major = major + 1;
}
class Person{
  protected:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void setAge(int);
    int getAge();
    void getOlder();
    void changeMajor();
};
int main(){
  Student student;
  student.age = 42;
  student.major = 2;
  student.happyBirthday();
  student.changeMajor();
  cout << student.age << endl;
  cout << student.major << endl;
  return 0;
}
class Person{
  protected:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void setAge(int);
    int getAge();
    void getOlder();
    void changeMajor();
};
void Person::happyBirthday() {
  age = age + 1;
}
void Student::setAge(int anAge) {
  age = anAge;
}
int Student::getAge() {
  return age;
}
void Student::getOlder() {
  happyBirthday();
}
void Student::changeMajor() {
  major = major + 1;
}
int main(){
  Student student;
  student.age = 42; // protected!
  student.major = 2;
  student.happyBirthday(); // protected!
  student.changeMajor();
  cout << student.age << endl; // protected!
  cout << student.major << endl;
  return 0;
}
class Person{
  protected:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void setAge(int);
    int getAge();
    void getOlder();
    void changeMajor();
};
void Person::happyBirthday() {
  age = age + 1;
}
void Student::setAge(int anAge) {
  age = anAge;
}
int Student::getAge() {
  return age;
}
void Student::getOlder() {
  happyBirthday();
}
void Student::changeMajor() {
  major = major + 1;
}
int main(){
  Student student;
  student.setAge(42);
  student.major = 2;
  student.getOlder();
  student.changeMajor();
  cout << student.getAge() << endl;
  cout << student.major << endl;
  return 0;
}
class Person{
  protected:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void setAge(int);
    int getAge();
    void getOlder();
    void changeMajor();
};
void Person::happyBirthday() {
  age = age + 1;
}
void Student::setAge(int anAge) {
  age = anAge;
}
int Student::getAge() {
  return age;
}
void Student::getOlder() {
  happyBirthday();
}
void Student::changeMajor() {
  major = major + 1;
}
int main(){
  Student student;
  student.setAge(42);
  student.major = 2;
  student.getOlder();
  student.changeMajor();
  cout << student.getAge() << endl; // 43
  cout << student.major << endl; // 3
  return 0;
}
class Person{
  protected:
    int age;
    void happyBirthday();
};
class Student : public Person{
  public:
    int major;
    void setAge(int);
    int getAge();
    void getOlder();
    void changeMajor();
};
void Person::happyBirthday() {
  age = age + 1;
}
void Student::setAge(int anAge) {
  age = anAge;
}
int Student::getAge() {
  return age;
}
void Student::getOlder() {
  happyBirthday();
}
void Student::changeMajor() {
  major = major + 1;
}

Subclass (Child or Derived Class)


Can we have the same function in both a subclass and its superclass, but with different code?

Subclass (Child or Derived Class)


Can we have the same function in both a subclass and its superclass, but with different code? Yes!

void Person::whoAmI() {
  cout << "Parent" << endl;
}

void Student::whoAmI() {
  cout << "Student" << endl;
}
class Person{
  protected:
    int age;
  public:
    void whoAmI();
};

class Student : public Person{
  public:
    void whoAmI();
};
int main(){
  Person person;
  Student student;
  person.whoAmI();
  student.whoAmI();
  return 0;
}
class Person{
  protected:
    int age;
  public:
    void whoAmI();
};

class Student : public Person{
  public:
    void whoAmI();
};
void Person::whoAmI() {
  cout << "Parent" << endl;
}

void Student::whoAmI() {
  cout << "Student" << endl;
}
int main(){
  Person person;
  Student student;
  person.whoAmI(); // Parent
  student.whoAmI(); // Student
  return 0;
}
class Person{
  protected:
    int age;
  public:
    void whoAmI();
};

class Student : public Person{
  public:
    void whoAmI();
};
void Person::whoAmI() {
  cout << "Parent" << endl;
}

void Student::whoAmI() {
  cout << "Student" << endl;
}
int main(){
  Student student;
  Person* person = &student;
  student.whoAmI();
  person->whoAmI();
  return 0;
}
class Person{
  protected:
    int age;
  public:
    void whoAmI();
};

class Student : public Person{
  public:
    void whoAmI();
};
void Person::whoAmI() {
  cout << "Parent" << endl;
}

void Student::whoAmI() {
  cout << "Student" << endl;
}
int main(){
  Student student;
  Person* person = &student;
  student.whoAmI(); // Student
  person->whoAmI(); // Parent
  return 0;
}
class Person{
  protected:
    int age;
  public:
    void whoAmI();
};

class Student : public Person{
  public:
    void whoAmI();
};
void Person::whoAmI() {
  cout << "Parent" << endl;
}

void Student::whoAmI() {
  cout << "Student" << endl;
}

Function Overriding

The function in the superclass is
overridden
by the function in the subclass.


Can we have it always use the subclass code, even if the current type is the superclass?

Function Overriding

The function in the superclass is
overridden
by the function in the subclass.


Can we have it always use the subclass code, even if the current type is the superclass? Use the virtual keyword!

void Person::whoAmI() {
  cout << "Parent" << endl;
}

void Student::whoAmI() {
  cout << "Student" << endl;
}
class Person{
  protected:
    int age;
  public:
    virtual void whoAmI();
};

class Student : public Person{
  public:
    void whoAmI();
};
int main(){
  Person person;
  Student student;
  person.whoAmI();
  student.whoAmI();
  return 0;
}
class Person{
  protected:
    int age;
  public:
    virtual void whoAmI();
};

class Student : public Person{
  public:
    void whoAmI();
};

void Person::whoAmI() {
  cout << "Parent" << endl;
}

void Student::whoAmI() {
  cout << "Student" << endl;
}
int main(){
  Person person;
  Student student;
  person.whoAmI(); // Parent
  student.whoAmI(); // Student
  return 0;
}
class Person{
  protected:
    int age;
  public:
    virtual void whoAmI();
};

class Student : public Person{
  public:
    void whoAmI();
};

void Person::whoAmI() {
  cout << "Parent" << endl;
}

void Student::whoAmI() {
  cout << "Student" << endl;
}
int main(){
  Student student;
  Person* person = &student;
  student.whoAmI();
  person->whoAmI();
  return 0;
}
class Person{
  protected:
    int age;
  public:
    virtual void whoAmI();
};

class Student : public Person{
  public:
    void whoAmI();
};

void Person::whoAmI() {
  cout << "Parent" << endl;
}

void Student::whoAmI() {
  cout << "Student" << endl;
}
int main(){
  Student student;
  Person* person = &student;
  student.whoAmI(); // Student
  person->whoAmI(); // Student
  return 0;
}
class Person{
  protected:
    int age;
  public:
    virtual void whoAmI();
};

class Student : public Person{
  public:
    void whoAmI();
};

void Person::whoAmI() {
  cout << "Parent" << endl;
}

void Student::whoAmI() {
  cout << "Student" << endl;
}

Virtual Functions

Virtual functions can be
redefined
within subclasses.


Do we always have to implement the function in the superclass?

Virtual Functions

Virtual functions can be
redefined
within subclasses.


Do we always have to implement the function in the superclass? No! Make the superclass an abstract class with pure virtual functions

void Student::whoAmI() {
  cout << "Student" << endl;
}
class Person{
  protected:
    int age;
  public:
    virtual void whoAmI() = 0;
};

class Student : public Person{
  public:
    void whoAmI();
};
int main(){
  Student student;
  Person person;
  person.whoAmI();
  student.whoAmI();
  return 0;
}
class Person{
  protected:
    int age;
  public:
    virtual void whoAmI()  = 0;
};

class Student : public Person{
  public:
    void whoAmI();
};

void Student::whoAmI() {
  cout << "Student" << endl;
}
int main(){
  Student student;
  Person person; // cannot instantiate
  person.whoAmI();
  student.whoAmI();
  return 0;
}
class Person{
  protected:
    int age;
  public:
    virtual void whoAmI()  = 0;
};

class Student : public Person{
  public:
    void whoAmI();
};

void Student::whoAmI() {
  cout << "Student" << endl;
}
int main(){
  Student student;
  Person* person = &student;
  student.whoAmI();
  person->whoAmI();
  return 0;
}
class Person{
  protected:
    int age;
  public:
    virtual void whoAmI()  = 0;
};

class Student : public Person{
  public:
    void whoAmI();
};

void Student::whoAmI() {
  cout << "Student" << endl;
}
int main(){
  Student student;
  Person* person = &student; // pointer ok
  student.whoAmI(); // Student
  person->whoAmI(); // Student
  return 0;
}
class Person{
  protected:
    int age;
  public:
    virtual void whoAmI()  = 0;
};

class Student : public Person{
  public:
    void whoAmI();
};

void Student::whoAmI() {
  cout << "Student" << endl;
}

Review

Next Steps

Assignment - Vehicles

Methods for vehicle type and tax rate
Practice with virtual functions and protected members