sesión 12: herencia (2) – herencia múltiple 1. 2009/1 circuitos digitales iii 2010/1 circuitos...

28
Informática II Sesión 12: Herencia (2) – herencia múltiple 1

Upload: gustavo-reyes-san-segundo

Post on 24-Jan-2016

225 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

1

Informática IISesión 12: Herencia (2) – herencia múltiple

Page 2: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

CONTENIDOCONTENIDO

Herencia Multiple1

Ambigüedades Herencia Múltiple2

Herencia Virtual3

Page 3: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

C++ permite crear clases derivadas que heredan los miembros de una o más clases antecesoras. Esta es una característica en la que C++ difiere de

otros lenguajes. Esta característica tiene pros y contras.

La herencia múltiple: Consiste en el ensamblando una nueva clase con los

elementos de varias clases-base.

Herencia MúltipleHerencia Múltiple

Page 4: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

Cuando se desea declarar una clase derivada de varias clases base se utiliza una lista de las bases directas separadas por comas:

class ClaseDerivada : tipoAcceso ClaseB1, tipoAcceso ClaseB2,… {

//La clase derivada posee información de las clases bases (atributos y métodos). Además, puedo agregar y modificar información.

};

Clase_Derivada hereda todos los miembros de las clases antecesoras ClaseBase1, ClaseBase2, … Usando herencia pública sólo puede utilizar los miembros que

derivan de recursos públicos y protegidos en las clases base.

Herencia MúltipleHerencia Múltiple

Page 5: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

class ClaseA { protected: int valorA;

public: ClaseA() : valorA(10) {} int getValor() const { return valorA; }};

class ClaseB { private: int valorB;

public: ClaseB() : valorB(20) {} int LeerValor() const { return valorB; }};

#include<iostream>using namespace std;

class ClaseC : public ClaseA, public ClaseB {public: ClaseC() {

valorA++;valorB++;

} };

int main() { ClaseC CC;

// Que valores se imprimen? cout << CC.LeerValor() << endl; cout << CC.getValor() << endl; cout << CC.valorA << endl; cout << CC.valorB << endl;

return 0;}

Herencia MúltipleHerencia Múltiple

Page 6: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

Herencia MúltipleHerencia Múltipleclass ClaseA { protected: int valorA;

public: ClaseA() : valorA(10) {} ClaseA(int va) : valorA(va) {} int getValor() const { return valorA; }};

class ClaseB { protected: int valorB;

public: ClaseB() : valorB(20) {} ClaseB(int vb) : valorB(vb) {} int LeerValor() const { return valorB; }};

#include<iostream>using namespace std;

class ClaseC : public ClaseA, public ClaseB { ClaseC(int va, int vb): ClaseA(va), ClaseB(vb) { }};

int main() { ClaseC CC(13,26);

cout << CC.LeerValor() << endl; cout << CC.getValor() << endl; cout << CC.valorA << endl; cout << CC.valorB << endl;

return 0;}

Page 7: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

CONTENIDOCONTENIDO

Herencia Multiple1

Ambigüedades Herencia Múltiple2

Herencia Virtual3

Page 8: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

AmbigüedadesAmbigüedades

“La herencia múltiple es uno de los puntos peliagudos del lenguaje C++.

Hasta el extremo que algunos teóricos consideran que esta característica debe evitarse, ya que además de los problemas teóricos, presenta también una gran dificultad técnica para su implementación en los compiladores.

Por ejemplo, surge la cuestión:• Si dos clases A y B son clases base de una

subclase D y ambas tienen propiedades con el mismo nombre

Page 9: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

¿Que debe resultar en la subclase D? ¿Miembros Duplicados?, o ¿un miembro que sean la agregación de las propiedades de A y B?.

Los creadores del C++ optaron por un diseño que despeja cualquier posible ambigüedad, aunque ciertamente deriva en una serie de reglas y condiciones bastante intrincadas”

AmbigüedadesAmbigüedades

Page 10: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

La herencia múltiple puede originar situaciones de ambigüedad Cuando una clase derivada contiene versiones

duplicadas de clases base Cuando clases bases contienen miembros con el

mismo nombre.

El problema de la ambigüedad puede ser resuelto si: Se especifica a cual de las clases bases pertenece la

propiedad heredada. Se re-define el miembro en la clase derivada

AmbigüedadesAmbigüedades

Page 11: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

AMBIGÜEDADES: SOLUCIÓN 1

AMBIGÜEDADES: SOLUCIÓN 1class ClaseA {

public: ClaseA() : valorA(10) {} int LeerValor() const { return valorA; } protected: int valorA;};

class ClaseB { public: ClaseB() : valorB(20) {} int LeerValor() const { return valorB; } protected: int valorB;};

#include<iostream>using namespace std;

class ClaseC : public ClaseA, public ClaseB {};int main() { ClaseC CC;

cout << CC.LeerValor() << endl; return 0;}#include<iostream>using namespace std;

class ClaseC : public ClaseA, public ClaseB {};int main() { ClaseC CC;

// Manera correcta de hacerlo cout << CC.ClaseA::LeerValor() << endl; cout << CC.ClaseB::LeerValor() << endl; return 0;}

// Produce error de compilación por ambigüedad

Método Derivado de

ClaseA??

Método derivado de ClaseB??

Page 12: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

Ambigüedades: solución 2Ambigüedades: solución 2class ClaseA { public: ClaseA() : valorA(10) {} int LeerValor() const { return valorA; } protected: int valorA;}; class ClaseB { public: ClaseB() : valorB(20) {} int LeerValor() const { return valorB; } protected: int valorB;};

#include<iostream>using namespace std;

class ClaseC : public ClaseA, public ClaseB{ int LeerValor() const { return valorA + valorB; } };int main() { ClaseC CC;

cout << CC.LeerValor() << endl; return 0;}

Page 13: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

AmbigüedadesAmbigüedades

Una clase puede: Ser heredada por muchas clases.

Pero no puede: Ser heredada más de una vez por una misma clase. Razón??

Ejemploclass D:tipoDeAcceso B1,tipoDeAcceso B1,…

Aunque … Este fenómeno se puede presentar de manera indirecta.

Page 14: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

AmbigüedadesAmbigüedades

class ClaseA { ... };class ClaseB : public ClaseA { ... };class ClaseC : public ClaseA { ... };class ClaseD : public ClaseB, public ClaseC { ... };

ClaseD

ClaseA

ClaseCClaseB

ClaseA

Duplicación indirecta de

la ClaseA

Page 15: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

Problemas de accesoProblemas de acceso

class B {  public:  int b;  int b0;};

class D:public C1,public C2{  public:  D(){ c = 10;    C1::c = 110; C2::c = 120; b = 12;     C1::b = 11; C2::b = 12; B::b = 10; C1::B::b = 10; b0 = 0; C1::b0 = 1; C2::b0 = 2; }};

class C1 :public B {  public:  int b;  int c;};

class C2 :public B {  public:  int b;  int c;};

Page 16: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

CONTENIDOCONTENIDO

Herencia Multiple1

Ambigüedades Herencia Múltiple2

Herencia Virtual3

Page 17: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

Si las clases base contienen elementos comunes Estos se ven duplicados en los objetos de la subclase

(clase-derivada).

Para evitar estos problemas, existe una variante de la herencia: La herencia virtual: cada objeto de la clase derivada

no contiene todos los recursos (atributos y métodos) de las clases-base si estos están duplicados.

Se busca evitar los problemas asociados a la ambigüedad.

Herencia VirtualHerencia Virtual

Page 18: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

Como hacer herencia virtual? Se antepone la palabra ‘virtual’ al nombre de una clase-

base al momento de definir la herencia. Así se declara una clase-base virtual, que da lugar a un

mecanismo con el mismo nombre.

Sintaxis:class ClaseD : virtual public B1, ...

Herencia VirtualHerencia Virtual

Page 19: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

class B {  public:  int b;  int b0;};

class D:public C1,public C2{  public:  D(){ c = 10;    C1::c = 110; C2::c = 120; b = 12;     C1::b = 11; C2::b = 12; B::b = 10; C1::B::b = 10; b0 = 0; C1::b0 = 1; C2::b0 = 2; }};

class C1 : virtual public B {  public:  int b;  int c;};

class C2 : virtual public B {  public:  int b;  int c;};

Problemas de accesoProblemas de acceso

Page 20: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

Problemas de accesoProblemas de acceso

class ClaseA { ... };class ClaseB : virtual public ClaseA { ... };class ClaseC : virtual public ClaseA { ... };class ClaseD : public ClaseB, public ClaseC { ... };

ClaseD

ClaseCClaseB

ClaseA

Herencia múltiple NO

ambigua

Page 21: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

EJEMPLOEJEMPLOusing namespace std; class B {                   public: int var;  B() { var = 0; }       };class X : public B {}; class Y : public B {};   class Z : public X, public Y {};

int main () {      Z z1;            cout << "Valores iniciales:" << endl;    cout << " z1.var (de X) = " << z1.X::var << endl;    cout << " z1.var (de Y) = " << z1.Y::var << endl;

  z1.X::var = 1;     z1.Y::var = 2;       cout << "Valores finales:" << endl;    cout << " z1.var (de X) = " << z1.X::var << endl;    cout << " z1.var (de Y) = " << z1.Y::var << endl;}

Valores iniciales: z1.var (de X) = 0 z1.var (de Y) = 0Valores finales: z1.var (de X) = 1 z1.var (de Y) = 2

Page 22: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

EJEMPLOEJEMPLOusing namespace std; class B {                   public: int var;  B() { var = 0; }       };class X : virtual public B {}; class Y : virtual public B {};   class Z : public X, public Y {};

int main () {      Z z1;            cout << "Valores iniciales:" << endl;    cout << " z1.var (de X) = " << z1.X::var << endl;    cout << " z1.var (de Y) = " << z1.Y::var << endl;

  z1.X::var = 8;     z1.Y::var = 20;       cout << "Valores finales:" << endl;    cout << " z1.var (de X) = " << z1.X::var << endl;    cout << " z1.var (de Y) = " << z1.Y::var << endl;}

Valores iniciales: z1.var (de X) = 0 z1.var (de Y) = 0Valores finales: z1.var (de X) = 20 z1.var (de Y) = 20

Page 23: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

Herencia VirtualHerencia Virtual Cuando se crea una estructura que posea herencia

virtual, deberemos tener cuidado con los constructores.

El constructor de la ClaseA deberá ser invocado desde el constructor de la ClaseD, ya que ni la ClaseB ni la ClaseC lo harán automáticamente.

ClaseD

ClaseCClaseB

ClaseA

Page 24: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

#include <iostream>#include <cstring>

class Persona { public: Persona(char *n) { strcpy(nombre, n); } const char * LeeNombre() const { return nombre; } protected: char nombre[30];};class Empleado : public Persona { public: Empleado(char *n, int s) : Persona(n), salario(s) {} int LeeSalario() const { return salario; } void ModificaSalario(int s) { salario = s; } protected: int salario;};

Otro Ejemplo: Ojo a la virtualidad(1)Otro Ejemplo: Ojo a la virtualidad(1)

Page 25: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

class Estudiante : public Persona { public: Estudiante(char *n, float no) : Persona(n), nota(no) {} float LeeNota() const { return nota; } void ModificaNota(float _nota) { nota = _nota; } protected: float nota;};

class Becario : public Empleado, public Estudiante { public: Becario(char *n, int s, float _nota) : Empleado(n, s), Estudiante(n, _nota) {}};

int main() { Becario * Fulanito; Fulanito = new Becario("Tarcisio", 1000, 7); cout << Fulanito->Estudiante::LeeNombre() << "," << Fulanito->LeeSalario() << "," << Fulanito->LeeNota() << endl; return 0;}

Otro Ejemplo: Ojo a la virtualidad(1)Otro Ejemplo: Ojo a la virtualidad(1)

Page 26: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

#include <iostream>#include <cstring>

class Persona { public: Persona(char *n) { strcpy(nombre, n); } const char *LeeNombre() const { return nombre; } protected: char nombre[30];};

class Empleado : virtual public Persona { public: Empleado(char *n, int s) : Persona(n), salario(s) {} int LeeSalario() const { return salario; } void ModificaSalario(int s) { salario = s; } protected: int salario;};

Otro Ejemplo: Ojo a la virtualidad(2)Otro Ejemplo: Ojo a la virtualidad(2)

Page 27: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

class Estudiante : virtual public Persona { public: Estudiante(char *n, float no) : Persona(n), nota(no) {} float LeeNota() const { return nota; } void ModificaNota(float no) { nota = no; } protected: float nota;};

class Becario : public Empleado, public Estudiante { public: Becario(char *n, int s, float no) : Empleado(n, s), Estudiante(n, no), Persona(n) {}};

int main() { Becario * Fulanito; Fulanito = new Becario(“Tarcisio", 1000, 7); cout << Fulanito->LeeNombre() << "," << Fulanito->LeeSalario() << "," << Fulanito->LeeNota() << endl; return 0;}

Otro Ejemplo: Ojo a la virtualidad(2)Otro Ejemplo: Ojo a la virtualidad(2)

Page 28: Sesión 12: Herencia (2) – herencia múltiple 1. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática

2009/1Circuitos Digitales III 2010/1Circuitos Digitales III 2010/1Circuitos Digitales IIICircuitos Digitales III 2010/1Informática II Universidad de Antioquia

BibliografíaBibliografía

man, ¡no dude en utilizarlo!! Como Programar en C++ - Deithel & Deithel Ed.

PRENTICE HALL Sams Teach Yourself C++ in One Hour a Day, J.

Liberty,S. Rao, B. Jones

http://newdata.box.sk/bx/c/

Informática II