c++ herencia

Upload: enrique-gamez-cardenas

Post on 17-Oct-2015

10 views

Category:

Documents


0 download

DESCRIPTION

C++ Herencia pdf

TRANSCRIPT

  • 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.