La herencia Como bien se sabe la herencia no se reparte: se descuartiza. Bromas aparte, la herencia constituye una de las herramientas mas poderosas del culto OO. Si una clase hereda de la otra, lo que hereda son todos sus atributos y metodos. Ademas de heredarlos puede sobreescribirlos, tanto los constructores-destructores como los metodos convencionales. Veremos un ejemplo claro que resume lo que se puede hacer y los efectos de la herencia Por un lado vemos la clase generica vehiculo y su descendiente: el coche. La clase Vehiculo
| /**
* Vehiculo.hpp
* Clase que define el objeto vehiculo
*
* Pello Xabier Altadill Izura
*
*/
using namespace std;
#include <iostream>
enum tipo_combustible { QUEROSENO, CANNABIS, GIRASOL, GASOIL, AGUA, PLUTONIO };
class Vehiculo {
protected:
	int cilindrada;
	
	tipo_combustible combustible;
	char *marca;
public:
	Vehiculo();
	Vehiculo(char *marca);
	
	Vehiculo(int cilindrada, tipo_combustible combustible, char *marca);
	
	~Vehiculo();
	Vehiculo(const Vehiculo &);
	void arrancar();
	
	void mover(int metros);
	// metodo tipo virtual, util cuando definamos PUNTEROS Y REFERENCIAS a vehiculo
	virtual void claxon() const {
		cout << "<clase vehiculo> Mec-meeec!! Que? meeec! Que de que? meec!" << endl;
	}
	char *getMarca() const {return this->marca;}
	tipo_combustible getCombustible() const {return this->combustible;}
	
	int getCilindrada() const {return this->cilindrada;}
	
}; | 
| /**
* Vehiculo.cpp
* Fichero que implementa la clase vehiculo
*
* Pello Xabier Altadill Izura
*
* Compilacion: g++ -c Vehiculo.cpp
*/
#include "Vehiculo.hpp"
// Constructor
Vehiculo::Vehiculo() {
	cout << "<clase vehiculo> Vehiculo creado" << endl;
}
// Constructor
Vehiculo::Vehiculo(char *marca) {
	
	this->marca = marca;
	cout << "<clase vehiculo> Vehiculo creado con parametro marca: " << marca << endl;
	
}
// Constructor con valores iniciados
Vehiculo::Vehiculo(int cilindrada, tipo_combustible combustible, char *marca) :
	cilindrada(cilindrada),
	combustible(combustible),
	marca(marca)
{
	cout << "<clase vehiculo> Vehiculo creado con valores: " << endl;
	cout << "<clase vehiculo> cilindrada: " << cilindrada << endl;
	cout << "<clase vehiculo> combustible: " << combustible << endl;
	cout << "<clase vehiculo> marca: " << marca << endl;
}
// Destructor 
Vehiculo::~Vehiculo() {
	
	cout << "<clase vehiculo> Vehiculo destruido" << endl;
}
// Constructor copia de vehiculo
Vehiculo::Vehiculo(const Vehiculo & vehiculoOrigen) {}
// Arrancamos el vehiculo
void Vehiculo::arrancar() {
	
	cout << "<clase vehiculo> arrancando vehiculo. Brruum!!" << endl;
	
}
// Movemos el vehiculo unos metros
void Vehiculo::mover(int metros) {
	
	cout << "<clase vehiculo> moviendo vehiculo " << metros << " metros" << endl;
} | 
| /**
* Coche.hpp
* Clase que define el objeto Coche, hijo de vehiculo, señor del capitalismo
*
* Pello Xabier Altadill Izura
*
*/
#include "Vehiculo.hpp"
class Coche : public Vehiculo {
protected:
	int caballos;
	char *motor;
public:
	// Atencion: constructor pasando parametros por defecto estilo guru
	// pero invocando a su clase padre
	Coche():Vehiculo("Audi") {
	
		cout << "<clase coche> Coche destruido invocando al constructor vehiculo" << endl;
	}
	// Constructor que sobreescribe al de vehiculo!
	Coche(char *marca);
	// Constructor
	Coche(int cilindrada, tipo_combustible combustible, char *marca);
	
	
	// Constructor
	Coche(int caballos, char *motor) {
		this->caballos = caballos;
		this->motor = motor;
		cout << "<clase coche> Coche construido con caballos y motor" << endl;
		
	}
	// Destructor
	~Coche();
	
	// Constructor copia
	Coche(const Coche &);
	// Metodo sobreescrito
	void arrancar();
	
	// metodo que sobreescribe al virtual
	void claxon() const;
	// getter/setter
	int getCaballos() const {return this->caballos;} // inline
	char *getMotor() const {return this->motor;} // inline 
}; | 
| /**
* Coche.cpp
* Fichero que implementa la clase Coche
*
* Pello Xabier Altadill Izura
*
* Compilacion: g++ -c Vehiculo.cpp
* g++ Coche.cpp Vehiculo.o -o Coche
*/
#include "Coche.hpp"
// Constructor de coche que sobreescribe
Coche::Coche(char *marca) {
	cout << "<clase coche> Coche construido con marca: " << 
	marca << endl;
}
// Constructor de coche
Coche::Coche(int cilindrada, tipo_combustible combustible, char *marca) {
	cout << "<clase coche> Coche construido con parametros" << endl;
}
// Destructor de coche 
Coche::~Coche() {
	
	cout << "<clase coche> Coche destruido" << endl;
}
// Constructor copia de Coche 
Coche::Coche(const Coche & cocheOriginal) {
	
	marca = new char;
	marca = cocheOriginal.getMarca();
	cout << "<clase coche> Copia de coche" << endl;
}
// metodo sobreescrito
void Coche::arrancar () {
	
		cout << "<clase coche> BOOM! pam! pam! pret pret pret... pam! pret pret" << endl;
}
// metodo que sobreescribe al virtual
void Coche::claxon() const {
	cout << "<clase coche> MOOOOOC!! Mecagon tus muelas MOC-MOOOC!!" << endl;
} 
// Funcion principal
int main () {
	
	// Creamos varios coches. Veremos que al ser objetos heredados
	// se invocaran los constructores, copias, y destructores de la clase
	// padre Vehiculo
	Coche mibuga = Coche();
	Coche tucarro = Coche(mibuga);
	// probando constructor sobrescrito: se invocan los dos!
	Coche tequi = Coche("Alfalfa Romero");
	
	// podemos invocar los metodos del padre y usar sus atributos
	cout << "La marca de mi buga es: " << mibuga.getMarca() << endl;
	mibuga.arrancar();
	// Invocando metodo sobreescrito: solo se invoca el del coche.
	tucarro.arrancar();
	
	// Y si queremos invocar el metodo del padre??
	tequi.Vehiculo::arrancar();
	
	// Creamos otro vehiculo con puntero a un COCHE
	Vehiculo *vehiculo = new Coche("LanborJini");
	// Esto invocara el metodo de vehiculo, el de la clase PADRE
	vehiculo->arrancar();
	vehiculo->mover(3);
	
	// Ahora queremos invocar el claxon, pero a cual de los metodos
	// se invocara, al del Coche o al de la clase vehiculo? al haber
	// definido el metodo claxon como virtual, se invocara el metodo correcto
	// que es el del coche (vehiculo es un puntero a coche).
	vehiculo->claxon();
	return 0;
} | 
| <clase vehiculo> Vehiculo creado con parametro marca: Audi <clase coche> Coche destruido invocando al constructor vehiculo <clase vehiculo> Vehiculo creado <clase coche> Copia de coche <clase vehiculo> Vehiculo creado <clase coche> Coche construido con marca: Alfalfa Romero La marca de mi buga es: Audi <clase coche> BOOM! pam! pam! pret pret pret... pam! pret pret <clase coche> BOOM! pam! pam! pret pret pret... pam! pret pret <clase vehiculo> arrancando vehiculo. Brruum!! <clase vehiculo> Vehiculo creado <clase coche> Coche construido con marca: LanborJini <clase vehiculo> arrancando vehiculo. Brruum!! <clase vehiculo> moviendo vehiculo 3 metros <clase coche> MOOOOOC!! Mecagon tus muelas MOC-MOOOC!! |