martes, 10 de enero de 2017
Capítulo 14. Herencia multiple
La herencia multiple Una de las oportunidades que nos ofrece el lenguaje c++ es la
posibilidad de que un objeto tenga la herencia de mas de una clase; esta ventaja fue
considerada por los desarrolladores de Java como una pega y la quitaron, e incluso
hay desarrolladores de c++ que prefieren evitar este tipo de herencia ya que puede
complicar mucho la depuracion de programas Para ilustrar un caso de herencia multiple
hemos definido la superclase Habitante; de ella heredan dos clases distintas:
Humano (que hablan) y Animal (que matan). Ahora queremos definir un ente que
tiene propiedades de esas dos clases: Militar, ya que el militar habla y ademas mata.
Como podemos definirlo? con una herencia multiple. Vamos la definicion de la superclase
o clase padre Habitante Notas de la logia POO Conviene definir todos los
metodos de un clase como const siempre que en el metodo no se modifiquen los
atributos. Tu resistencia es inutil. unete a nosotros o muere. Definir metodos como
const le facilitara el trabajo al compilador y al programador. Nota el codigo necesita
revision y testeo
/**
* Habitante.hpp
* Clase que define el objeto habitante
*
* Pello Xabier Altadill Izura
*
*/
using namespace std;
#include
class Habitante {
private:
char *nombre;
int edad;
public:
Habitante();
virtual ~Habitante();
Habitante(const Habitante &);
virtual void dormir();
// setter/getter o accessors
virtual char *getNombre() const { return this->nombre;}
// inline
virtual void setNombre(char *nombre) { this->nombre = nombre; } // inline
virtual int getEdad() const { return this->edad;} // inline
virtual void setEdad(int edad) { this->edad = edad; } // inline
};
Y su implementacion
/**
* Habitante.cpp
69
Capítulo 14. Herencia multiple
* Programa que implementa la clase habitante
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -c Habitante.cpp
*
*/
#include "Habitante.hpp"
// Constructor
Habitante::Habitante() {
cout << "-clase habitante- Habitante construido."<< endl;
}
// Destructor
Habitante::~Habitante() {
cout << "-clase habitante- Habitante "<< this->getNombre() << " destruido."<< endl;
}
// constructor copia
Habitante::Habitante(const Habitante & original) {
nombre = new char;
original.getNombre();
}
// metodo dormir
void Habitante::dormir() {
cout << "-clase habitante- zzzzzZZZZzzzzz zzz" << endl;
}
Humano La clase Humano, que hereda de Habitante
/**
* Humano.hpp
* Clase que define el objeto humano
*
* Pello Xabier Altadill Izura
*
*/
#include "Habitante.hpp"
// hereda atributos y metodos de la superclase Habitante
class Humano : public Habitante {
private:
char *idioma;
public:
Humano();
virtual ~Humano();
70
Capítulo 14. Herencia multiple
Humano(const Humano &);
virtual void hablar(char *bla) const;
// setter/getter o accessors
virtual char *getIdioma() const { return this->idioma;} // inline
virtual void setIdioma(char *idioma) { this->idioma = idioma; } // inline
};
Y su implementacion
/**
* Humano.cpp
* Fichero que implementa el objeto humano
*
* Pello Xabier Altadill Izura
*
*/
#include "Habitante.hpp"
// Constructor
Humano::Humano() {
cout << "-clase Humano- Humano construido."<< endl;
}
// Destructor
Humano::~Humano() {
cout << "-clase Humano- Humano "<< this->getNombre() << " destruido."<< endl;
}
// constructor copia
Humano::Humano(const Humano & original) {
idioma = new char;
idioma = original.getIdioma();
}
// metodo hablar
void Humano::hablar(char *bla) const {
cout << "-clase Humano-" << this->getNombre() << " dice: " << bla << endl;
}
Animal La clase Animal, que hereda de Habitante
/**
* Animal.hpp
* Clase que define el objeto Animal
*
* Pello Xabier Altadill Izura
*
*/
#include "Habitante.hpp"
71
Capítulo 14. Herencia multiple
// hereda atributos y metodos de la superclase Habitante
class Animal : public Habitante {
private:
int patas;
public:
Animal();
virtual ~Animal();
Animal(const Animal &);
virtual void matar() const;
// setter/getter o accessors
virtual int getPatas() const { return this->patas;} // inline
virtual void setPatas(int patas) { this->patas = patas; } // inline
};
Y su implementacion
/**
* Animal.cpp
* Programa que implementa la clase Animal
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -c Animal.cpp
*
*/
#include "Animal.hpp"
// Constructor
Animal::Animal() {
cout << "-clase Animal- Animal construido."<< endl;
}
// Destructor
Animal::~Animal() {
cout << "-clase Animal- Animal "<< this->getNombre() << " destruido."<< endl;
}
// constructor copia
Animal::Animal(const Animal & original) {}
// metodo matar
void Animal::matar() const {
cout << "-clase Animal-" << this->getNombre() << " Matar! Matar! Matar! " << endl;
}
72
Capítulo 14. Herencia multiple
La herencia multiple! Aqui esta la clase Militar, que hereda de Humano y Animal.
/**
* Militar.hpp
* Clase que define el objeto Militar
*
* Pello Xabier Altadill Izura
*
*/
// Herencia multiple de Humano y Animal
class Militar : public Animal { //, public Humano {
private:
char *rango;
73
Capítulo 14. Herencia multiple
public:
Militar();
~Militar();
Militar(const Militar &);
// sobrescribe metodos
void matar() const;
void hablar(char *bla) const;
// un metodo poco probable entre cualquier uniformado...
void razonar() const;
// setter/getter o accessors
char *getRango() const { return this->rango;}
void setRango(char *rango) { this->rango = rango;}
};
Y su implementacion
/**
* Militar.cpp
* Programa que implementa la clase Militar
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -c Habitante.cpp
* g++ -c Humano.cpp
* g++ -c Animal.cpp
* g++ Militar.cpp Habitante.o Humano.o Animal.o -o Militar
*/
#include "Militar.hpp"
// Constructor
Militar::Militar() {
cout << "-clase Militar- Militar construido."<< endl;
}
// Destructor
Militar::~Militar() {
cout << "-clase Militar- Militar "<< this->getNombre() << " destruido."<< endl;
}
// constructor copia
Militar::Militar(const Militar & original) {
cout << "-clase Militar- Militar copia creada."<< endl;
}
// metodo razonar
void Militar::razonar() const {
74
Capítulo 14. Herencia multiple
cout << "-clase Militar-" << this->getNombre() << " Error: OVERFLOW " << endl;
}
// metodo hablar
void Militar::hablar(char *bla) const {
cout << "-clase Militar-" << this->getRango() << " " << this->getNombre() << " dice: ";
cout << bla << endl;
}
// metodo matar
void Militar::matar() const {
cout << "-clase Militar-" << this->getRango() << " Matar! " << endl;
cout << "-clase Militar- Somos... agresores por la paz " << endl;
}
// Aqui haremos multiples pruebas...
int main () {
return 0;
}
75
Capítulo 14. Herencia multiple
76
Capítulo 15. Miembros estaticos
Quereis ver un miembro no estatico? (< !-- nota docbook: quitar chorradas antes
de publicar -->) Variables/Funciones estaticas Dentro de las clases podemos definir
atributos y metodos estaticos. Tienen de particular que son accesibles sin necesidad
de definir una clase y que su valor es EL MISMO en todas los objetos que se vayan
creando de una clase. Es como una variable global de una clase. Con este ejemplo se
ve su uso, y de paso se revisa el tema de punteros a funciones. (si, has leido bien).
/**
* Soldado.hpp
* Clase que define el objeto soldado muestra el uso de variables estaticas
* y metodos estaticos. Todo lo estatico escapa del ambito de la clase y puede
* ser invocado desde el exterior
*
* Pello Xabier Altadill Izura
*
*/
using namespace std;
#include
class Soldado {
public:
// constructores
Soldado();
Soldado(char *nombre, int unidad);
// destructor
~Soldado();
// copia
Soldado(Soldado const &);
// get/set
char *getNombre () const { return this->nombre; }
void setNombre (char *nombre) { this->nombre = nombre; }
int getUnidad () const { return this->unidad; }
void setUnidad (int unidad) { this->unidad = unidad; }
void matar() const;
void darOrden (char *orden) const;
// metodo que toma como parametro una funcion
void ejecutaAccion ( void (*accion) (int,int));
static int TotalSoldados; // variable estatica!
static int TotalBalas; // variable estatica!
// Funciones estaticas
static int getTotalSoldados () { return TotalSoldados; }
static int getTotalBalas () { return TotalBalas; }
77
Capítulo 15. Miembros estaticos
private:
char *nombre;
int unidad;
};
Y su implementacion. Se recomienda probar y ejecutar para comprobar el
funcionamiento de las variables estaticas.
/**
* Soldado.cpp
* Programa que implementa la clase Soldado
*
* Pello Xabier Altadill Izura
* Compilacion: g++ Soldado.cpp -o Soldado
*/
#include "Soldado.hpp"
// Constructor
Soldado::Soldado(): nombre("Ryan"), unidad(101) {
TotalSoldados += 1;
TotalBalas++;
cout << "Soldado " << nombre << " construido. Unidad: " << unidad << endl;
}
// Constructor parametrizado
Soldado::Soldado(char *nombre, int unidad) {
TotalSoldados++;
TotalBalas++;
this->nombre = nombre;
this->unidad = unidad;
cout << "Soldado " << nombre << " :Soldado construido." << endl;
}
// Destructor
Soldado::~Soldado() {
TotalSoldados--;
cout << "Soldado "<< this->getNombre() << " destruido."<< endl;
}
// constructor copia
Soldado::Soldado(const Soldado & original) {
nombre = new char;
nombre = original.getNombre();
cout << "-clase Soldado- Soldado copia creada."<< endl;
}
// metodo matar
void Soldado::matar() const {
78
Capítulo 15. Miembros estaticos
TotalBalas--;
cout << this->getNombre() << " Matar es lo mio " << endl;
cout << "Born to kill. paz. Es por la dualidad de Kant" << endl;
}
// metodo darOrden
void Soldado::darOrden(char *orden) const {
cout << "Recluta patoso!" << endl;
cout << this->getNombre() << " unidad " << this->getUnidad() << " ordena: ";
cout << orden << endl;
}
// metodo ejecutaAccion: ejecuta la funcion que se le pasa como parametro
void Soldado::ejecutaAccion ( void (*accion) (int,int)) {
accion(5,7);
cout << "Recluta patoso!" << endl;
}
// ATENCION IMPORTANTE: HAY QUE DEFINIR E INICIAR LAS VARIABLES ESTATICA SI NO
// el compilador nos puede poner pegas
int Soldado::TotalSoldados = 0;
int Soldado::TotalBalas = 0;
// Definimos una funcion ajena a la clase desde la cual accederemos
// a la variable estatica, con lo que se demuestra que la variable estatica
// esta fuera de la "capsula" de la clase.
void recuentoSoldados(void);
// definimos otra funcion esta para pasarsela como parametro a un metodo de la clase
void carga (int balas, int granadas);
// funcion principal
// Aqui haremos multiples pruebas...
int main () {
int i, resp;
// creamos los soldados
Soldado peloton[10];
Soldado Hanks = Soldado("Hanks",105);
// definicion de puntero de funcion:
void (*funcion) (int, int) = carga;
// Si hay mas de una funcion carga sera la que tenga los mismos parametros
// y el mismo tipo de retorno
// llamamos a la funcion recuento
recuentoSoldados();
peloton[0].darOrden("Todos en formacion.");
peloton[2].darOrden("Canta el colacao!");
// recorremos los 10 soldados y hacemos algo dependiendo de la entrada
// Si matamos unos cuantos modificaremos la variable de TotalSoldados
79
Capítulo 15. Miembros estaticos
for (i = 0; i < 10 ; i++) {
cout << "Elije 0 o cualquier otro numero: " << endl;
cin >> resp;
if (resp == 0) {
// matamos al soldado
peloton[i].~Soldado();
} else {
peloton[i].matar(); // tiramos una bala
}
// Invocamos el metodo estatico?
// es un acceso DIRECTO sin necesitar un objeto definido
resp = Soldado::getTotalSoldados();
cout << "Cuantos quedan? " << resp << endl;
}//for
// accedemos directamente a variable estatica
cout << "Total balas antes de recarga: " <<
Soldado::TotalBalas << endl;
// hacemos una recarga:
Hanks.ejecutaAccion(funcion);
// llamamos a la funcion recuento
recuentoSoldados();
return 0;
}
// implementacion de la funcion recuento
// muestra el numero de soldados. Podemos acceder DIRECTAMENTE a la variable statica
void recuentoSoldados () {
cout << "Cuantos soldados quedan vivos? " << endl;
cout << "En total: " << Soldado::TotalSoldados << " soldados"<< endl;
cout << "Municion? " << endl;
cout << "En total: " << Soldado::getTotalBalas() << " balas" << endl;
}
// funcion que carga municion del peloton
void carga (int balas, int granadas) {
cout << "Cargando balas: " << balas << endl;
Soldado::TotalBalas += balas ;
cout << "Cargando granadas: " << granadas << endl;
}
Bueno, y con esto ya son dos semanas dandole al c++ y aprendiendo su abc...
Suscribirse a:
Enviar comentarios (Atom)
No hay comentarios:
Publicar un comentario