Inheritance y Polymorphism
Una class puede heredar de otra con : public Base. Marcar un method de la base class como virtual, y la versión de la derived class como override, le dice al compilador que despache dinámicamente: cuando llamas al method a través de un pointer o reference a la base class, se ejecuta la versión del tipo real en tiempo de ejecución — no necesariamente la que sugeriría el tipo estático.
#include <iostream>
#include <string>
using namespace std;
class Animal {
public:
virtual string speak() const {
return "...";
}
};
class Dog : public Animal {
public:
string speak() const override {
return "Woof!";
}
};
class Cat : public Animal {
public:
string speak() const override {
return "Meow!";
}
};
int main() {
Dog dog;
Cat cat;
Animal* animals[2] = { &dog, &cat };
for (int i = 0; i < 2; i++) {
cout << animals[i]->speak() << endl;
}
return 0;
}Woof! Meow!
animals es un array de Animal* — un pointer a la base class de tipado estático — pero cada elemento igual llama al speak() correcto de su derived class. Sin virtual, ambas llamadas imprimirían '...' en su lugar, ya que el compilador resolvería la llamada estáticamente contra el tipo Animal declarado en vez de despachar en tiempo de ejecución.
Siguiente: operator overloading — darle a tus propios types la misma sintaxis +, -, == que ya tienen los types integrados.
Practice exercise
Define una class Shape con un virtual method name() que devuelva "Shape". Define una class Circle que herede de Shape y haga override de name() para devolver "Circle". Crea un Circle a través de un Shape* pointer e imprime su name().