c++ herencia
DESCRIPTION
C++ Herencia pdfTRANSCRIPT
-
1Herencia Junto con el polimorfismo, es la caracterstica ms importante de la
POO.
Permite reutilizar cdigo, definiendo nuevas clases a partir de otras ya existentes.
Si una clase A hereda de otra clase B, a B la llamaremos clase base, mientras que A ser una subclase de B.
Si una clase hereda de otra, en particular hereda todos sus mtodos y atributos, pudiendo adems declarar y definir ms atributos y mtodos, y redefinir algunos de los mtodos heredados.
2
Herencia: Sintaxis Sintaxis:
class B : Identificador A {....};
indica que la clase B hereda de la clase A. El Identificadorespecifica el tipo de herencia, que en C++ puede ser: pblica, protegida y privada.
No vamos a utilizar ni la herencia protegida ni la privada. Slo usaremos la pblica:
class B : public A {....};
3
Herencia: Sintaxis
OJO:
Si no se pone ningn identificador se asume que la herencia es privada.
4
Herencia: Niveles de proteccin
En la implementacin de la clase B podemos utilizar todos los atributos pblicos y protegidos (protected) de la clase A, pero nunca los privados.
El nuevo identificador protected para mtodos y atributos indica que estos pueden ser utilizados dentro de la implementacin de una clase que herede de ella. En cualquier otra situacin se comportan como atributos privados.
-
5Herencia: Niveles de proteccinIdentificador Accesible desde Accesible desde Accesiblede mtodo o atributo la propia clase? subclases? para los dems?
public
private
protected
SI
SI
SI
SI
SI
NO
SI
NO
NO
6
Herencia: Un ejemplo
class Base {private: // no accesible desde las subclasesint x,y;
protected: // accesible desde las subclasesint nx,ny;
public: // accesible para todosBase():x(0),y(0),nx(0),ny(0){};Base(int a,int b):x(a),y(b),nx(0),ny(0){};
Lista de inicializaciones
7
Herencia: Un ejemplo
void set(int a,int b,int c,int d){x=a;y=b;nx=c;ny=d;}
int getX(){return x;}int getY(){return y;} mtodos inlineint getNX(){return nx;}int getNY(){return ny;}
};
8
Herencia: Un ejemploclass Hija:public Base{private:int p1,p2;
public:void actualizaNXNY(){
p1=nx; // CORRECTOp2=y+ny; // INCORRECTOset(2,3,p1,p2); // CORRECTO
};void actualizaXY(){
p1=getX(); p2=getY();}; // CORRECTOint getP1(){return p1;}int getP2(){return p2;};
-
9Herencia: Constructoras Supongamos que declaramos la variable:
Hija h;
Qu constructora se ejecuta?
La constructora por defecto de la clase Hija, ya que, como la clase Hija no tiene definida ninguna constructora, tiene una por defecto, que lo nico que hace es invocar a la constructora por defecto de la clase Base.
10
Herencia: Constructoras Si aadimos a la clase Hija:
Hija(){set(1,1,1,1);p1=5;p2=7;}
se ejecutarn:
La constructora sin argumentos de la clase Base. La constructora sin argumentos de la clase Hija.
11
Herencia: Constructoras
Cuando se crea un objeto de una subclase, siempre se invoca en primer lugar (implcita o explcitamente) a una constructora de la clase base.
Explcitamente: mediante la lista de inicializaciones en las constructoras de la subclase.
Implcitamente: Si no se especifica una, se ejecuta la constructora por defecto de la clase base.
12
Herencia: Constructoras
Hija(int a,int b):Base(a,b),p1(a+2),p2(b+2){};
Llamada explcita a la constructora con dos argumentos de la clase Base.
Hija(int a,int b):p1(a+2),p2(b+2){};
Como no aparece llamada explcita, se llama a la constructora por defecto de la clase Base.
-
13
Herencia: Destructoras
Para el caso de las destructoras, cuando se destruye un objeto de una subclase, se invoca primero a la destructora de la subclase y al final se invoca a la destructora de la clase base.
14
Herencia: Redefinicin de mtodos
Una subclase puede redefinir mtodos de la clase base:
clase Base {.....int suma(){
ShowMessage(Clase Base);return nx+ny+x+y;}
}clase Hija: public Base {......int suma(){ShowMessage(Clase Hija);return px+py;}
}
15
Herencia: Redefinicin de mtodos
Cmo funciona? Enlace esttico, el de la clase declarada para la variable (se decide en tiempo de compilacin).
Hija h(2,3);ShowMessage(h.suma());
Base b(2,3);ShowMessage(b.suma());
Clase Hija
Clase Base
16
Herencia: Casting
Qu hacer si queremos que h ejecute el mtodo suma de la clase Base?
// casting hacia arribaShowMessage(((Base) h).suma());
Es correcto: ?
b=h; // POLIMORFISMOb.suma();
Qu pasa con los atributos p1 y p2 que no tiene b?Qu mtodo se ejecuta? El de la clase Base
-
17
Herencia: Enlace esttico Enlace esttico (i.e. en tiempo de compilacin). Se ejecutan los
mtodos de la clase a la que pertenece la variable declarada y no del posible objeto que contiene.
Es correcto? ShowMessage((Hija b).suma())h=b;h.suma();
NO: Error de compilacin. b no tiene los atributos p1 y p2 de la clase Hija !!!
18
Herencia: Enlace dinmico Para conseguir que se ejecutara el mtodo suma de la clase Hija
(objeto contenido en la variable b) necesitaramos mtodos virtuales con enlace dinmico (i.e. en tiempo de ejecucin), que slo tienen sentido en presencia de punteros y referencias).
clase Base {.......virtual int suma(){....}
};Hija h(2,3);Base* b = &h;ShowMessage(b->suma()); // enlace dinmico
19
Herencia: Enlace dinmicoConclusin: Utilizaremos el polimorfismo con PUNTEROS.
Observacin: Si en la clase Hija quisiramos utilizar el mtodo suma de la clase Base, debemos utilizar la notacin:
Base::suma()
class Hija:public Base{.........virtual int suma(){
ShowMessage("Clase hija");return Base::suma()+p1+p2;}
};20
Polimorfismo Permite disear e implementar sistemas que sean extensibles con
gran facilidad.
Los programas se escriben para que procesen objetos en forma genrica: objetos de todas las clases existentes en una jerarqua.
A
B C D
-
21
Polimorfismo Una variable de tipo A puede contener a cualquier objeto de sus
subclases (no al contrario).
A=animales; B=perros; C=gatos; D=leones;
Tiene sentido:
Un perro es un animal? SIA* a = new B(); // CORRECTO
Todos los animales son perros? NOB* b = new A(); // INCORRECTO
22
Polimorfismo ymtodos virtuales
Supongamos que la clase A contiene un mtodo esttico p, y que las subclases de A redefinen dicho mtodo:
C* objC = new C();B* objB = new B();A* objA = objB; objA->p(); // (1)objA = objC;objA->p(); // (2)
23
Polimorfismo ymtodos virtuales
Tanto en (1) como en (2) se ejecuta el mtodo p de la clase A. La razn es que objA es de tipo A, y como el mtodo es de enlace esttico, siempre se ejecuta el mtodo de la clase a la que pertenece la variable y no el de la clase del objeto contenido en la variable (enlace dinmico-tiempo de ejecucin).
qu podramos hacer para que se ejecute el mtodo del tipo del objeto contenido en la variable?
mtodos virtuales
Se determina el mtodo a ejecutar en tiempo de ejecucinENLACE DINMICO
(SLO POSIBLE CON PUNTEROS Y REFERENCIAS)24
Polimorfismo ymtodos virtuales
Sintaxis:
virtual tipo nombreMetodo(argumentos);
Convenio:
Poner virtual, adems de en la clase base, en todas las subclases directas o indirectas que redefinan el mtodo.
-
25
Polimorfismo ymtodos virtuales: Un ejemplo
class Base {public:virtual void p(){ShowMessage(Clase base");}};class Hija:public Base {public:virtual void p(){ShowMessage(Clase hija");}};class Nieta:public Hija {public:virtual void p(){ShowMessage(Clase nieta");}};
Base
Hija
Nieta
26
Polimorfismo ymtodos virtuales: Un ejemplo
Base* b=new Hija();b->p(); // p de la clase HijaHija* h = new Nieta();h->p(); // p de la clase Nieta
Aunque en las subclases el mtodo p no apareciera como virtual lo sera igualmente.
27
Polimorfismo ymtodos nuevos
Cuando una subclase aade nuevos mtodos, si hacemos uso del polimorfismo, no podemos invocarlos directamente: hay que hacer casting.class Base {public:virtual void p(){ShowMessage(Clase base");}};
class Hija:public Base {public:virtual void p(){ShowMessage(Clase hija");}void p1(){ShowMessage(Soy nuevo);}};
Base * b = new Hija(); b->p1(); // error de compilacin(Hija* b)->p1(); // se ejecuta el mtodo p1 de la clase Hija
28
Polimorfismo: Destructoras
class Base{private:
T* t; // objeto dinmico de la clase Tpublic:
Base(){t=new T(...);....}.....~Base(){delete t; t=NULL;}
-
29
Polimorfismo: Destructoras
class Hija:public Base {private:M* m; // objeto dinmico de la clase Mpublic:Hija():Base(){m=new M(...);...}.....~Hija(){delete m; m=NULL;}
};
30
Polimorfismo: DestructorasBase* b = new Hija();delete b;
Se invoca a la destructora de la clase Base !!! Nos dejamos sin borrar m !!!
SOLUCIN: La destructora de la clase Base debe ser virtual. En tal caso, primero se ejecutar la destructora de la clase Hija, y despus la de la clase Base.
31
Polimorfismo: Clases abstractas Una clase abstracta es una clase de la que no podemos tener
instancias (i.e. objetos).
Se usan como clases tipo de las cuales heredan otras clases.
Para indicar que una clase es abstracta basta introducir un mtodo virtual puro (o abstracto).
virtual tipo nombreMetodo(argumentos)=0;
32
Polimorfismo: Clases abstractasPor ejemplo:
class Base {public:virtual void show()=0;
};
Una clase que herede de la clase Base debe implementar el mtodo show. En otro caso la subclase tambin se considerar abstracta.
-
33
Informacin de tipo en ejecucin
La funcin typeid devuelve una referencia a un objeto de la clase type_info. Los objetos de esta clase representan un tipo.
Sintaxis:typeid(expresin) == typeid(tipo)
34
Informacin de tipo en ejecucin Ejemplos:
Grafico* graf = new Rectangulo(......);if typeid(*graf)==typeid(Rectangulo)
ShowMessage(cierto);else ShowMessage(falso);
Si la clase Grafico contiene al menos un mtodo virtual (clase polimrfica), se mostrar cierto, en otro caso se mostrarfalso.
Con clases polimrficas, typeid(*graf) devuelve el tipo del objeto apuntado por graf en tiempo de ejecucin. En otro caso devuelve el tipo en tiempo de compilacin.
35
Informacin de tipo en ejecucin
La clase type_info tiene definidos los operadores == y !=
Para utilizar typeid es necesario incluir el mdulo typeinfo:
#include
typeid(*a) con a == NULL genera una excepcin.