Continuando con la programación orientada a objetos en C++ hoy vamos a ver cómo funciona la herencia de clases, con algunos ejemplos.
Recordemos que, en C++, cuando una clase extiende de otra, la misma hereda sus métodos y propiedades, exceptuando el constructor.
También vamos a ver cómo sobrescribir métodos de la clase padre.
Nota: antes de que leas sobre la herencia, mira los principios de la programación orientada a objetos en C++.
Extender de otra clase en C++
Para definir que una clase extiende de otra, se usan los dos puntos:
class NombreDeClase: NombreDeLaClasePadre{};
Se puede extender de varias clases:
class NombreDeClase: NombreDeUnaClase, NombreDeOtraClase{};
Llamar a métodos de la clase padre
Si los métodos de la clase son marcados como públicos o protegidos, se puede acceder a ellos a través de this
.
Sobrescribir métodos
Para sobrescribir métodos dentro de una clase padre, los mismos deben ser declarados como virtuales con la palabra virtual. Por ejemplo:
virtual void nombreDelMetodo(){};
De esta manera, en la clase hija se sobrescribe con la palabra override:
void nombreDelMetodo override(){}
Obviamente el método debe tener el mismo nombre, número de argumentos y valor de retorno.
Llamar al constructor padre
Se puede llamar al constructor padre, para ello primero se debe definir un constructor en la clase hija.
Por ejemplo:
ConstructorDeLaClaseHija(int argumento1) : ConstructorDeLaClasePadre(argumento1){};
Fíjate que el constructor de la clase padre no indica el tipo de dato, solo el nombre de la variable.
Vas a entender mejor con el código.
Hablar es de mal gusto, muéstrame el código
Ahora veamos el código de todo lo que hemos explicado sobre la herencia de clases en C++
Dentro del código se refleja el acceso a las propiedades y métodos definidas en la clase padre, así como un ejemplo para sobrescribir métodos.
#include <iostream>
class Persona {
private:
std::string nombre;
int edad;
void metodoPrivado() {
std::cout << "Solo puedo ser llamado desde dentro de la clase";
}
public:
// Constructor sin argumentos
Persona() {
std::cout << "Se llama al constructor";
this->metodoPrivado();
}
// Constructor con nombre y edad
Persona(std::string nombre, int edad) {
this->edad = edad;
this->nombre = nombre;
}
int getEdad() { return this->edad; }
void setEdad(int edad) { this->edad = edad; }
std::string getNombre() { return this->nombre; }
void setNombre(std::string nombre) { this->nombre = nombre; }
void saludar() {
std::cout << "Hola, me llamo " << this->nombre << " y mi edad es "
<< this->edad << "\n";
}
// Definido virtual para que se pueda sobrescribir ;)
virtual void saludarAmigo(std::string nombre) {
std::cout << "Hola " << nombre << ", me llamo " << this->nombre
<< " y mi edad es " << this->edad << "\n";
}
};
class Estudiante : public Persona {
public:
// Constructor vacío
Estudiante(std::string nombre, int edad, std::string escuela)
: Persona(nombre, edad) {}
// Definir propios métodos
void estudiar() { std::cout << "*estudia*\n"; }
// Sobrescribir otros
void saludarAmigo(std::string nombre) override {
// Usamos getEdad y getNombre porque es una subclase
// y las variables son privadas
std::cout << "Qué onda " << nombre << ", me llamo " << this->getNombre()
<< " y mi edad es " << this->getEdad() << "\n";
}
};
int main() {
Persona p1("Luis", 21);
p1.saludar();
Persona p2;
p2.setEdad(1);
p2.setNombre("John Galt");
p2.saludar();
Estudiante e1("Luis", 3, "Ninguna");
e1.saludar();
e1.saludarAmigo("Pedro");
e1.estudiar();
}
La definición y llamada del constructor es un poco compleja, pero se ejemplifica claramente. Por cierto, el constructor de la clase hija podría tener más argumentos y pasarle únicamente algunos a la del padre.
Como siempre, recuerda que la clase puede definir sus propios métodos y propiedades, así como extender de varias clases.