La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

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.

Presentaciones similares


Presentación del tema: "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."— Transcripción de la presentación:

1 Sesión 12: Herencia (2) – herencia múltiple 1

2 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia C ONTENIDO Herencia Multiple 1 Ambigüedades Herencia Múltiple 2 Herencia Virtual 3

3 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informá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últiple

4 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informá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últiple

5 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informá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 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últiple

6 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia Herencia Múltiple class 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 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; }

7 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia C ONTENIDO Herencia Multiple 1 Ambigüedades Herencia Múltiple 2 Herencia Virtual 3

8 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia Ambigü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

9 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informá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üedades

10 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informá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üedades

11 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia A MBIGÜEDADES : SOLUCIÓN 1 class 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 using namespace std; class ClaseC : public ClaseA, public ClaseB {}; int main() { ClaseC CC; cout << CC.LeerValor() << endl; return 0; } #include 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??

12 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia Ambigüedades: solución 2 class 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 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; }

13 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia Ambigü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??  Ejemplo class D:tipoDeAcceso B1,tipoDeAcceso B1,…  Aunque …  Este fenómeno se puede presentar de manera indirecta.

14 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia Ambigüedades class ClaseA {... }; class ClaseB : public ClaseA {... }; class ClaseC : public ClaseA {... }; class ClaseD : public ClaseB, public ClaseC {... }; class ClaseA {... }; class ClaseB : public ClaseA {... }; class ClaseC : public ClaseA {... }; class ClaseD : public ClaseB, public ClaseC {... }; ClaseD ClaseA ClaseC ClaseB ClaseA Duplicación indirecta de la ClaseA

15 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia Problemas de acceso class B { public: int b; int b0; }; 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 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; };

16 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia C ONTENIDO Herencia Multiple 1 Ambigüedades Herencia Múltiple 2 Herencia Virtual 3

17 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informá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 Virtual

18 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informá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 B 1,... Herencia Virtual

19 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia class B { public: int b; int b0; }; 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 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 acceso

20 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia Problemas de acceso class ClaseA {... }; class ClaseB : virtual public ClaseA {... }; class ClaseC : virtual public ClaseA {... }; class ClaseD : public ClaseB, public ClaseC {... }; class ClaseA {... }; class ClaseB : virtual public ClaseA {... }; class ClaseC : virtual public ClaseA {... }; class ClaseD : public ClaseB, public ClaseC {... }; ClaseD ClaseC ClaseB ClaseA Herencia múltiple NO ambigua

21 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia E JEMPLO using 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) = 0 Valores finales: z1.var (de X) = 1 z1.var (de Y) = 2

22 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia E JEMPLO using 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) = 0 Valores finales: z1.var (de X) = 20 z1.var (de Y) = 20

23 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia Herencia 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 ClaseC ClaseB ClaseA

24 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia #include 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)

25 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informá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 Estudiante::LeeNombre() << "," LeeSalario() << "," LeeNota() << endl; return 0; } Otro Ejemplo: Ojo a la virtualidad(1)

26 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia #include 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)

27 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informá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 LeeNombre() << "," LeeSalario() << "," LeeNota() << endl; return 0; } Otro Ejemplo: Ojo a la virtualidad(2)

28 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática II Universidad de Antioquia Bibliografí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


Descargar ppt "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."

Presentaciones similares


Anuncios Google