poo herencia

21
Estructuras de Datos Avanzadas Estructuras de Datos Avanzadas Programación Orientada a Objetos Profesores: Belén Melián Batista ([email protected]) José A. Moreno Pérez ([email protected]) Cl Clases Sobrecarga de operadores Herencia Herencia Jerarquía de clases Polimorfismo Plantillas Manejo de excepciones

Upload: sergio

Post on 01-Oct-2015

28 views

Category:

Documents


1 download

DESCRIPTION

Conceptos de herencia en POO

TRANSCRIPT

  • Estructuras de Datos Avanzadas Estructuras de Datos Avanzadas Programacin Orientada a Objetos

    Profesores: Beln Melin Batista ([email protected])Jos A. Moreno Prez ([email protected])

    Cl Clases Sobrecarga de operadores Herencia Herencia Jerarqua de clases Polimorfismo Plantillas Manejo de excepciones

  • HERENCIA: definicin La herencia en POO permite definir una clasep fmodificando una o ms clases ya existentes.

    Estas modificaciones consisten habitualmente en aadirnuevos miembros (variables o funciones), a la clase que seest definiendo, aunque tambin se puede redefinirvariables o funciones miembro ya existentes.

    La clase de la que se parte en este proceso recibe el nombre declase base, y la nueva clase que se obtiene se denominal d i d d l b

    y qclase derivada. sta a su vez puede ser clase base en unnuevo proceso de derivacin, iniciando de esta manera unajerarqua de clases.

    Las clases base suelen ser ms generales que las clasesderivadas, dado que a las clases derivadas se les suelen ir

    di d i bl f i dif iaadiendo variables y funciones que diferencian, concretan yparticularizan.

  • HERENCIA: clases base abstractas Clases base abstractas (ABC, Abstract Base Class): clases

    i ilid d l b lcuya nica utilidad es ser clase base para otras clases que sederiven de ella. De ellas no se declara ningn objeto, y su funcin esla de agrupar miembros comunes de otras clases que se derivarn deellas Por ejemplo se puede definir la clase vehiculo para despusellas. Por ejemplo, se puede definir la clase vehiculo para despusderivar de ella coche, bicicleta, patinete, etc., pero todos losobjetos que se declaren pertenecern a alguna de estas ltimasclases; no habr vehculos que sean slo vehculos.

    Las caractersticas comunes de estas clases pertenecern a la clasebase y las que sean particulares de alguna de ellas pertenecernslo a la clase derivadaslo a la clase derivada.

    Este mecanismo de herencia presenta mltiples ventajas evidentesa primera vista como la posibilidad de reutilizar cdigo sina primera vista, como la posibilidad de reutilizar cdigo sintener que escribirlo de nuevo. Esto es posible porque todas lasclases derivadas pueden utilizar el cdigo de la clase base sintener que volver a definirlo en cada una de ellas.

  • HERENCIA: variables y funciones miembro PROTECTED Uno de los problemas que aparece con la herencia es el del control

    d l l ddel acceso a los datos.

    Una funcin de una clase derivada no puede acceder a los datospri ados de otra pero podra ser mu con eniente que una claseprivados de otra, pero podra ser muy conveniente que una clasederivada accediera a todos los datos de su clase base.

    Para hacer posible esto existe el tipo de dato protected que es Para hacer posible esto, existe el tipo de dato protected, que esprivado para todas aquellas clases que no son derivadas, peropblico para una clase derivada de la clase en la que se hadefinido la variable como protected.p

  • HERENCIA: clase base public o private

    El proceso de herencia puede efectuarse de dos formas distintas:

    public: En el caso de que la clase base sea public para la clasep q p pderivada, sta hereda los miembros public y protected de laclase base como miembros public y protected,respectivamente.

    Private: Si la clase base es private para la clase derivada, stahereda todos los datos de la clase base como private. Lasiguiente tabla puede resumir lo explicado en los dos ltimossiguiente tabla puede resumir lo explicado en los dos ltimosprrafos.

  • HERENCIA: clase base public o privateTipo de dato de Clase derivada de una Clase derivada de una Otras clases sin pla clase base clase base public clase base private relacin de

    herencia con la clase base

    Private No accesible directamente No accesible directamente No accesible directamente

    Protected Protected Private No accesible directamente

    Public Public Private Accesible medianteoperador (.) o (->)

    Herencia pblica o privada

  • HERENCIA: clase base public o private

    Como ejemplo, se puede pensar en dos tipos de cuentas bancariasComo ejemplo, se puede pensar en dos tipos de cuentas bancariasque comparten algunas caractersticas y que tambin tienen algunasdiferencias. Ambas cuentas tienen un saldo, un inters y elnombre del titular de la cuenta.L t j ti d t i l d d d l La cuenta joven es un tipo de cuenta que requiere la edad delpropietario, mientras que la cuenta empresarial necesita elnombre de la empresa.

    El problema podra resolverse estableciendo una clase base llamada El problema podra resolverse estableciendo una clase base llamadaC_Cuenta y creando dos tipos de cuenta derivados de dicha clasebase.

    Para indicar que una clase deriva de otra es necesario indicarloqen la definicin de la clase derivada, especificando el modo -public o private- en que deriva de su clase base:

    l Cl i d bli i Clclass Clase_Derivada : public o private Clase_Base

  • #include l C C t {class C_Cuenta {

    // Variables miembroprivate:

    char *Nombre; // Nombre de la personadouble Saldo; // Saldo Actual de la cuentadouble Interes; // Inters aplicado// p

    public:// ConstructorC Cuenta(const char *unNombre, double unSaldo=0.0, double C_Cuenta(const char unNombre, double unSaldo 0.0, double unInteres=0.0){

    Nombre = new char[strlen(unNombre)+1];Nombre = new char[strlen(unNombre)+1];strcpy(Nombre, unNombre);SetSaldo(unSaldo);SetInteres(unInteres);SetInteres(unInteres);

    }// Destructor

    C ()~Cuenta(){ delete [] Nombre; }

  • // Mtodos// Mtodosinline char *GetNombre()

    { return Nombre; }inline double GetSaldo()inline double GetSaldo()

    { return Saldo; }inline double GetInteres()

    { return Interes; }{ return Interes; }inline void SetSaldo(double unSaldo)

    { Saldo = unSaldo; }i li id S I (d bl I )inline void SetInteres(double unInteres)

    { Interes = unInteres; }inline void Ingreso(double unaCantidad)

    { SetSaldo( GetSaldo() + unaCantidad ); }friend ostream& operator

  • class C_CuentaJoven : public C_Cuenta {private:

    int Edad;int Edad;public:C_CuentaJoven( // argumentos del constructor

    const char * nNombreconst char *unNombre,int laEdad,double unSaldo=0.0,d bl )double unInteres=0.0): C_Cuenta(unNombre, unSaldo, unInteres)

    // se llama al constructor de la clase base en la lnea previa.{

    Edad = laEdad;}}

    };

  • class C_CuentaEmpresarial : public C_Cuenta {private:

    char *NomEmpresa;public:p

    C_CuentaEmpresarial( // argumentos del constructorconst char *unNombre,const char *laEmpresa,const char laEmpresa,double unSaldo=0.0,double unInteres=0.0): C Cuenta(unNombre unSaldo unInteres): C_Cuenta(unNombre, unSaldo, unInteres)

    // se llama al constructor de la clase base en la lnea previa.{

    N E h [ t l (l E ) ]NomEmpresa = new char[strlen(laEmpresa)+1];strcpy(NomEmpresa, laEmpresa);

    }// Cuando una variable de este tipo se destruye se llamar// primero el destructor de CuentaEmpresarial y posteriormente se// llama automticamente el destructor de la clase base.//~C_CuentaEmpresarial()

    { delete [] NomEmpresa; }};

  • void main(){{

    C_CuentaJoven c1("Igor", 18, 10000.0, 1.0);C_CuentaEmpresarial c2("Juan", "MicroComputers Corp." ,10000000.0);// Ambas cuentas pueden llamar mtodos definidos previamente// Ambas cuentas pueden llamar mtodos definidos previamentecout

  • HERENCIAHay algunos elementos de la clase base que no pueden serheredados:

    HERENCIA

    heredados:

    1. Constructores2 D t t2. Destructores3. Funciones friend4. Funciones y datos estticos de la clase5. Operador de asignacin (=) sobrecargado

  • HERENCIA t t d l l d i d

    Un objeto de la clase derivada contiene todos los miembros de la

    HERENCIA: constructores de las clases derivadas, inicializador base

    Un objeto de la clase derivada contiene todos los miembros de laclase base y todos esos miembros deben ser inicializados. Por tanto,el constructor de la clase derivada debe llamar al constructord l l b Al d fi i l t t d l l d i dde la clase base. Al definir el constructor de la clase derivadase debe especificar un inicializador base.

    Las clases derivadas no heredan los constructores de sus clasesbase. El inicializador base es la forma de llamar a losconstructores de las clases base y poder as inicializar lasy pvariables miembro heredadas.

    El inicializador base puede ser omitido en el caso de que la claseEl inicializador base puede ser omitido en el caso de que la clasebase tenga un constructor por defecto.

    C CuentaJoven (const char *unNombre int laEdad doubleC_CuentaJoven (const char unNombre, int laEdad, doubleunSaldo=0.0, double unInteres=0.0) : C_Cuenta(unNombre,unSaldo, unInteres)

  • HERENCIA h i i l lti lHERENCIA: herencia simple y mltiple

    CLASE 1

    CLASE 2 CLASE 3 HERENCIA SIMPLE

    CLASE 4 CLASE 5 CLASE 6

    CLASE 1 CLASE 2CLASE 1 CLASE 2

    HERENCIA MLTIPLECLASE 3 CLASE 4

    CLASE 4

  • HERENCIA j lComo ejemplo se puede presentar el caso de que se tenga una clase parael manejo de los datos de la empresa Se podra definir la clase

    HERENCIA: ejemplo

    el manejo de los datos de la empresa. Se podra definir la claseC_CuentaEmpresarial como la herencia mltiple de dos clases base:la ya bien conocida clase C_Cuenta y nueva clase llamadaC E t ti iC_Empresa, que se muestra a continuacin:

    class C_Empresa {private:

    char *NomEmpresa;public:

    C_Empresa(const char*laEmpresa){

    NomEmpresa = new char[strlen(laEmpresa)+1];strcpy(NomEmpresa, laEmpresa);

    }}~C_Empresa()

    { delete [] NomEmpresa; }// Otros mtodos // Otros mtodos ...

    };

  • HERENCIA j lHERENCIA: ejemplo

    class C_CuentaEmpresarial : public C_Cuenta, public C_Empresa {public:

    C_CuentaEmpresarial(const char *unNombre,const char *laEmpresa,double unSaldo=0.0,double unInteres=0.0) : C_Cuenta(unNombre, unSaldo, unInteres), C_Empresa(laEmpresa)

    // se llama a los constructores de las clases base en la lnea previa{{

    // Constructor}// Otros mtodos// Otros mtodos

    };

  • HERENCIA l i t lAl utilizar la herencia mltiple puede suceder que, indirectamente, unaclase herede varias veces los miembros de otra clase tal como se ve

    HERENCIA: clases virtuales

    clase herede varias veces los miembros de otra clase, tal como se veen la figura siguiente.

    Clase Abuela

    Clase_Madre_1 Clase_Madre_2

    Clase Hija

    Para evitar este problema las clases Madre_1 y Madre_2 debenderivar de la clase Abuela declarndola clase base virtual. Esto haceque los miembros de una clase de ese tipo se hereden tan slo una vezque los miembros de una clase de ese tipo se hereden tan slo una vez.Un ejemplo de declaracin de una clase base virtual es el que sepresenta a continuacin:class Madre 1 : virtual public Abuela {class Madre_1 : virtual public Abuela {...}

  • HERENCIA C i t bj t d l b

    Es posible realizar conversiones o asignaciones de un objeto de una

    HERENCIA: Conversiones entre objetos de clases base y clases derivadas

    Es posible realizar conversiones o asignaciones de un objeto de unaclase derivada a un objeto de la clase base. Es decir se puede ir de loms particular a lo ms general, aunque en esa operacin se pierdainformacin pues haya variables que no tengan a qu asignarseinformacin, pues haya variables que no tengan a qu asignarse

    Por el contrario las conversiones o asignaciones en el otro sentido,d i d l l l i l ibles decir de lo ms general a lo ms particular, no son posibles, porque

    puede suceder que no se disponga de valores para todas las variablesmiembro de la clase derivada.

    As pues, la siguiente asignacin sera correcta:Objeto clase base = Objeto clase derivada // Asignacin vlidaObjeto_clase_base Objeto_clase_derivada // Asignacin vlida

    mientras que esta otra sera incorrecta:Objeto clase derivada = Objeto clase base // Asignacin Objeto_clase_derivada = Objeto_clase_base // Asignacin

    incorrecta

  • HERENCIA j l d i t bj tHERENCIA: ejemplo de conversiones entre objetos

    id i ()void main(){

    // VlidoC_CuentaEmpresarial *c1 = new C_CuentaEmpresarial("Juan","Jugos SA", 100000.0, 10.0);// Vlido. Se utilizan los valores por defecto// pC_Cuenta *c2 = new C_CuentaEmpresarial("Igor", "Patata CORP");// NO VLIDOC CuentaEmpresarial *c3 = new C Cuenta("Igor", 100.0, 1.0);C_CuentaEmpresarial c3 new C_Cuenta( Igor , 100.0, 1.0);// ...

    }

  • HERENCIA

    De forma anloga, se puede guardar la direccin almacenada en un

    HERENCIA

    De forma anloga, se puede guardar la direccin almacenada en unpuntero a una clase derivada en un puntero a la clase base. Estoquiere decir que se puede hacer referencia a un objeto de la clasederivada con su direccin contenida en un puntero a la clase basederivada con su direccin contenida en un puntero a la clase base.

    Al igual que sucede con los nombres de los objetos, en principio cuando sehace referencia a un objeto por medio de un puntero el tipo de dichohace referencia a un objeto por medio de un puntero, el tipo de dichopuntero determina la funcin miembro que se aplica, en el casode que esa funcin se encuentre definida tanto en la clase base como en lad i d E d fi i i l l b d lderivada. En definitiva, un puntero a la clase base puede almacenarla direccin de un objeto perteneciente a una clase derivada. Sinembargo, se aplicarn los mtodos de la clase a la que pertenezca elpuntero, no los de la clase a la que pertenece el objeto.