Está en la página 1de 39

Programacin Orientada a Objetos

TEMA 5

Herencia Mltiple
Facultad de Informtica Universidad de Murcia

ndice
1.- Introduccin 2.- Utilidades de la herencia mltiple 3.- Problemas con la herencia mltiple.
Colisin de nombres Herencia repetida Conflicto cuando hay comparticin Conflicto cuando hay replicacin

4.- Herencia mltiple en Java: Interfaces


2

1.- Introduccin
Las clases pueden necesitar mas de una clase padre Ms difcil de usar e implementar que la herencia simple. Algunos consideran que produce ms inconvenientes que ventajas. Segn B. Meyer:
No puedo pensar en una aplicacin seria escrita en Eiffel que no use la herencia mltiple en un modo significativo Para discutir cuestiones conceptuales sobre H.M. es necesario considerar el doble aspecto de la herencia: subtipos y extensin modular
3

Herencia mltiple y Extensin modular


MATH S R STORABLE R

S es una especializacin de R MATH incluye un paquete de rutinas matemticas STORABLE ofrece servicios de persistencia de objetos
4

Herencia Mltiple y Subtipos


Ejemplo1: Implementacin de los mens de una aplicacin i) Los mens son simples MENU ARRAY [OPCION_MENU] ii) Los mens contienen submens 1) MENU TREE [OPCION_MENU] provocara muchos cambios 2) MENU OPCION_MENU{menu, ejecutar}

{num_opciones opciones, display}

SUBMENU {ejecutar+//visualizar las opciones}


5

Ejemplo2:

Profesores ayudantes estn matriculados de


los cursos de doctorado
PERSONAL_UNI ESTUDIANTE

PROFESOR

PROFESOR_AYUDANTE

Ejemplo3: Aadir un nuevo tipo de cuenta que comparte a

la vez propiedades de cuenta de ahorro y cuenta corriente


CUENTA_BANCARIA

CUENTA_AHORRO

CUENTA_CORRIENTE

SOLUCIN:
Con herencia mltiple
CUENTA_ BANCARIA

Sin herencia mltiple


Perdemos: Polimorfismo CUENTA_ BANCARIA Principio de Abierto-Cerrado Beneficios de la reutilizacin de la herencia

CUENTA_ AHORRO

CUENTA_ CORRIENTE

CUENTA_ AHORRO

CUENTA_ CORRIENTE

NUEVA_CUENTA

NUEVA_CUENTA

NUEVA_CUENTA

Debemos aadir a NUEVA_CUENTA las propiedades de CUENTA_CORRIENTE


7

Ejemplo4: Aadir a la jerarqua Smalltalk una clase para

representar nmeros complejos


MAGNITUDE{=, <, >, ..}

{+, -, *, / ..} NUMBER

CHAR

INTEGER

Soluciones:

OPCION A Magnitude

OPCION B Magnitude Number

Char

Number Char Integer Complejo

Integer

Complejo

{=, >, <, ERROR}

2.- Utilidades de la herencia mltiple


A) Combinar abstracciones de tipos (padres simtricos) B)Matrimonio de implementacin) conveniencia (Herencia de

C) Herencia de estructura D) Herencia de facilidades


9

A) Combinacin de interfaces no relacionadas


Ejemplo1:
class WINDOW inherit TREE [WINDOW] RECTANGLE feature .... end class TEXT_WINDOW inherit WINDOW STRING feature .... end

Una ventana es un objeto grfico y un rbol de ventanas

Una ventana de texto es una ventana que manipula texto


10

A) Combinacin de interfaces no relacionadas


Ejemplo2:
class TREE [G] inherit LIST [G] LINKABLE [G] feature .... end

Un rbol es una lista, la lista de sus hijos, pero tambin es un elemento potencial de la lista (un subrbol de otro rbol) Un rbol es una lista que es tambin un elemento de la lista

LIST permite obtener los hijos de un nodo, aadir/eliminar un hijo,... LINKABLE permite obtener el valor de un nodo, su hermanos, su padre, aadir un hermano...

11

TREE[G] grficamente
A B D E C B A 2

ARBOL es_un NODO valor siguiente cabeza numElementos ARBOL es_una LISTA C 0

2 D 0 E 0

12

C) Herencia de Estructura:
Se desea que una clase posea ciertas propiedades adems de la abstraccin que representa.
NUMERIC COMPARABLE DIAGRAMA STORABLE

INTEGER

DIAGRAMA_CLASES

D) Herencia de Facilidades:
Existen clases que existen con el nico propsito de ofrecer unos servicios a sus descendientes
MATH A ASCII A ITERATOR A

13

B) Matrimonio por conveniencia


Proporcionar una implementacin para una abstraccin definida por una clase diferida usando las facilidades que proporciona una clase efectiva
ARRAY [G] PILA [G]* LINKED_LIST [G]

export [NONE] all

export [NONE] all

PILA_FIJA [G]+

PILA_ENLAZADA [G]+

La clase PILA_FIJA [G] slo exporta las caractersticas exportadas por PILA [G] y oculta las propiedades de ARRAY [G]. La clase PILA_ENLAZADA [G] slo exporta las caractersticas exportadas por PILA [G] y oculta las propiedades de LINKED_LIST [G].
14

B) Matrimonio por conveniencia


Proporcionar una implementacin para una abstraccin definida por una clase diferida usando las facilidades que proporciona una clase efectiva
ARRAY [G] PILA [G]* LINKED_LIST [G]

export [NONE] all

export [NONE] all

PILA_FIJA [G]+

PILA_ENLAZADA [G]+

HERENCIA DE IMPLEMENTACIN La clase PILA_FIJA [G] slo exporta las caractersticas exportadas por PILA [G] y oculta las propiedades de ARRAY [G]. La clase PILA_ENLAZADA [G] slo exporta las caractersticas exportadas por PILA [G] y oculta las propiedades de LINKED_LIST [G].
15

class PILA_FIJA [G] inherit PILA [G] ARRAY [G] export {NONE} all rename put as array_put, make as make_array, count as capacity end creation make feature count: INTEGER; --hace efectiva como atributo una --caracterstica diferida make (n: INTEGER) is require tamao_no_negativo: n>=0; do array_make (1,n) ensure capacidad: capacity = n; vacia: count = 0 end
16

Implementacin de Pilas usando arrays 1/2

Implementacin de Pilas usando arrays 2/2

full: BOOLEAN is do --Est llena la representacin de la pila? Result:= (count = capacity) end; put (x: G) is -- Pone x en la cima de la pila require not full do count:= count + 1; array_put (x, count) end; invariant count>=0 ; count <= capacity ... end -- PILA_FIJA [G]

17

Problema en ejecucin
Sea la declaracin p: PILA_FIJA [INTEGER] entonces p.array_put (32,45) provocara error en tiempo de compilacin.

Provocara error el siguiente cdigo?


p: PILA_FIJA [INTEGER]; a: ARRAY [INTEGER] ... a:= p a.put (32,45)
{se ejecuta la rutina put de array}
18

Herencia de implementacin
ARRAY [G] PILA [G]*

PILA_FIJA [G]+
full: BOOLEAN is do Result:= (count = capacity) end; put (x: G) is do count:= count + 1; array_put (x, count) end;

19

Cmo se hara sin herencia de implementacin?


PILA [G]*

ARRAY [G]

imp

PILA_FIJA [G]+
full: BOOLEAN is do full: BOOLEAN is do Result:= (count = capacity) Result:= (count = imp.capacity) end; end; put (x: G) is do put (x: G) is do count:= count + 1; count:= count + 1; array_put (x, count) imp.put (x, count) end; end;

Penalizacin rendimiento Tedioso uso prefijos

Toda manipulacin de la representacin requiere una llamada a una caracterstica de ARRAY con imp como receptor. 20

Clientela vs. Herencia de implementacin


B hereda de A es una decisin de diseo ms comprometedora que B es cliente de A. Si B es cliente de A podemos cambiar la implementacin de A sin afectar a B. Cundo es apropiada una herencia de implementacin? Cuando la eleccin de la implementacin es una parte esencial del diseo de la clase, y no va a cambiar, como en PILA_FIJA [G] En ese caso ofrece una solucin ms simple, eficiente y legible.
21

C++ y Herencia de implementacin


A {f,g}
class A { public: void f ( ); void g (); protected:... private:...} class B: private A { public: ... protected:... private:...}

C* oc; A* oa; B* ob oa = ob ob.f( ) {ERROR} {ERROR}

22

Ocultar las propiedades del padre


Eiffel:
export {NONE} class Pila inherit Array export {NONE} ALL

C++:
herencia privada class Pila: private Array{...};

Java:
throw new UnsupportedOperationException(); invocar con super a las propiedades del padre class Pila extends Array{ public void add(int pos, Object valor) { throw new UnsupportedOperationException(); } public void push(Object valor){ super.add(tope,valor); } 23 }

Ejemplo: Figuras Compuestas


Vamos a ver un patrn de diseo general (de utilidad en muchas reas) que describe estructuras compuestas a travs de la herencia mltiple, usando una clase contenedora (lista) como una de sus clases padre, PATRN COMPOSITE.
class FIGURA_COMPUESTA inherit FIGURA LINKED_LIST [FIGURA] feature end

Una figura compuesta es una figura Una figura compuesta es una lista de figuras
24

Figura Compuesta con herencia mltiple


FIGURA*

visualizar girar

LISTA[FIGURA] start after forth visualizaris do girar() is do from start until after loop item.visualizar item.girar() forth end end

FIGURA_COMPUESTA visualizar girar

Muchas rutinas con esta estructura (rotar, trasladar, )

25

Patrn Composite: Herencia simple


Componente operacion

Simple operacion

Compuesto operacion componentes

for (int i=0; i<componentes.length();++i) componentes[i].operacion();


26

Figura Compuesta con Herencia simple


Figura dibujar

Poligono dibujar

FiguraCompuesta dibujar componentes: LINKED_LIST[FIGURA] dibujar is do from componentes.start until componentes.after loop componentes.item.dibujar componentes.forth end 27 end

vs Herencia mltiple

Solucin: Figuras Compuestas e Iteradores


coleccion:LINEAR_LIST[G] forEach+ action* ... coleccion

LINEAR_ITERATOR*
redefine coleccion

FIGURA_COMPUESTA

FIGURA_COMPUESTA_ITERATOR*

visualizar rotar is is local local iv: VISUALIZAR_ITERATOR ir: ROTAR_ITERATOR do do !!iv.make(Current) !!ir.make(Current) action + iv.forEach ir.forEach end end VISUALIZAR_ITERATOR action (f: FIGURA) is do f.visualizar end

action +

...

ROTAR_ITERATOR
action (f: FIGURA) is do f.rotar end
28

FIGURAS COMPUESTAS + ITERADORES FIGURAS COMPUESTAS + ITERADORES

deferred class FIGURA_COMPUESTA_ITERATOR inherit LINEAR_ITERATOR [FIGURA_COMPUESTA] redefine coleccion end creation make feature coleccion: FIGURA_COMPUESTA -- Coleccin sobre la que itera -- (lista de figuras) end -- antes era Linear_List[G]

class VISUALIZAR_ITERATOR inherit FIGURA_COMPUESTA_ITERATOR redefine action end creation make feature action(f: FIGURA) is do f.visualizar end end 29

class FIGURA_COMPUESTA inherit FIGURA LINKED_LIST[FIGURA] feature ... visualizar is local iv: VISUALIZAR_ITERATOR do !!iv.make (Current) iv.forEach end ... end -- coleccin:= Figura_compuesta actual

NO HAY NADA MALO EN TENER CLASES TAN PEQUEAS NO ES ACEPTABLE PASAR RUTINAS COMO ARGUMENTOS 30 (B. Meyer)

3.-Problemas con la Herencia Mltiple


(a) Colisin de nombres

{f} A C

B {f}
Solucin: Renombrar [y redefinir]

(b) Herencia repetida

A B D

{at, f} C
Solucin: compartir o duplicar?
31

Colisin de nombres en Eiffel


Se considera un problema sintctico Debe ser resuelto por la clase que hereda Solucin: RENOMBRAR en la clase C, al menos una de las dos caractersticas heredadas que colisionan

{f} A {af, bf} C

B {f}

class C inherit A rename f as af B rename f as bf feature ... end

No hay colisin de nombres si: i) colisiona una rutina diferida con otra efectiva ii) hay herencia repetida con comparticin

32

Renombrar & Redefinir


Importante distinguir entre la versin de una caracterstica y su nombre Redefinir: cambiamos la versin Mecanismo semntico Renombrar: cambiamos el nombre Mecanismo sintctico Resolver colisiones de nombres Ofrecer nombres ms adecuados.
Ejemplo: class WINDOW inherit RECTANGLE TREE [WINDOW] rename put as add_window, remove as delete_window, parent as super_window,... end .... 33 end

Renombrar & Redefinir


Una caracterstica con nombre final f en la clase C podr tener un nombre original g distinto en la clase origen A dnde se introdujo inicialmente. Cada caracterstica f de una clase C tiene un nombre final en C, que se define segn
Si f es inmediato: nombre final = nombre original Si f es heredado de A y no se renombra: nombre final = nombre final en A Si f es heredado de A y se renombra nombre final = nuevo nombre
34

Combinar redefinir y renombrar


B {f,g,h} class C inherit B rename f as nf redefine g, nf end; feature nf is do .. end; g is do .. end; ... end

-- debe ir antes de redefine


Clase donde est B B B Clase origen B B B Nombre final f g h Nombre original f g h

Versin

C {nf, g, h}

C C C

B B B

nf g h

f g h

* Ejercicio 1:
A {f} rename f as g B {g}

* Ejercicio 2:
A {f} rename f as g redefine g B {g}

oa: A; ob: B !!ob oa:= ob oa.f -- {} oa.g -- {error t.c.} ob.f -- {error t.c.} ob.g -- {}

oa: A; ob: B !!ob oa:= ob oa.f -- {} oa.g -- {error t.c.} ob.f -- {error t.c.} ob.g -- {}

36

* Ejercicio 3:
B {f, g}
rename f as h redefine h

{h, i }
Clase B B C C C Nombre final f g h g i

ob: B; oc: !!ob; ob.f () ob.g() ob:= oc ob.f () ob.i () oc.h () oc.f ()

C -- se ejecuta -- se ejecuta -- se ejecuta -- error en compilacin -- se ejecuta -- error en compilacin

Nombre original Versin Clase Origen f B g f g i B B B C

37

Ejercicio 4
class C inherit A rename f as g; B rename f as h; redefine h; feature h is do end f is do end end
oa: A; ob: B; oc: C; !!oc; oc.f; oc.g; oc.h; oa:= oc; oa.f; oa.g; ob:= oc; ob.f; ob.h;
38

Colisin de nombres en C++


No es posible renombrar No sera suficiente con la sobrecarga? Solucin: Calificacin de las rutinas
poco adecuada para los clientes elimina la Ligadura Dinmica (A::f puede aplicarse desde cualquier clase)

{f}

{f}
class C: private A, private B { public: void af ( ) {return A::f ()}; void bf ( ) {return B::f ()}; // reexportar las otras funciones de A y B // no renombradas ... 39 }

C
C* oc c -> A::f ( ) c- > B::f ( )

Colisin de nombres en C++


Y si las funciones son virtual y quiero conservas ambas porque tienen significados distintos? fA {virtual f ()} A B {virtual f ()} fB

{f ()} fC

C* pc = new C; A* pa = pc; B* pb = pc pa -> f (); pb -> f (); pc -> f () Todos los mensajes invocan a C:: f () !!!
40

Cambio de nombre en C++


Solucin: Introducir una clase extra por cada clase que tenga una funcin virtual a la que se quiera cambiar el nombre en la que se define el nuevo nombre de la funcin. {virtual f ()} class A1 { ... virtual a_f()=0; void f () { return a_f();} }; A B {virtual f ()}

A1*

B1*

C {b_f (), a_f()}

class B1 { ... virtual b_f()=0; void f () { return b_f();} }; 41

Ejemplo:

quiero redefinir los mtodos de las clases bases y mantener los dos.
class Lloteria:public Loteria{ virtual int l_dibuja()=0; int dibuja() //redefine Loteria::dibuja {return l_dibuja();} }; class OObjetoGrafico: public ObjetoGrafico{ virtual int ir_a_dibuja()=0; void dibuja() //redefine ObjetoGrafico::dibuja {ir_a_dibuja();} }; class SimulaLoteria :public LLoteria, public OObjetoGrafico{ //... int l_dibuja(); void ir_a_dibuja(); };

class Loteria{ //... virtual int dibuja(); }; class ObjetoGrafico{ //... virtual void dibuja(); }; class SimulaLoteria :public Loteria, public ObjetoGrafico{ //... };

Loteria::dibuja() y ObjetoGrafico::dibuja() tienen significados diferentes

42

Problemas con la Herencia Mltiple: (a) Colisin de nombres rename

(b) Herencia repetida


A B D {at, f} C D A

Qu sucede con las propiedades heredadas ms de una vez? REPLICACIN o COMPARTICIN


43

Ejemplo: Herencia repetida


PERSONA
{nombre, direccion edad} direccion,

{num_exp, ...} ESTUDIANTE

PROFESOR

{ingresos, ...}

PROFESOR_AYUDANTE {nombre, edad,


dir_casa, dir_dpto}

edad Comparticin direccion particular o del Dpto? Replicacin


44

Herencia repetida: Replicar o Compartir?


atributos y rutinas Sea la clase D y B1, .., Bn (n1) son ascendientes de D que tienen la clase A como ascendiente comn; sean f1, .., fn, caractersticas de B1, .., Bn, respectivamente, que tienen como semilla la propiedad f de A, entonces:

1) Cualquier subconjunto de f1, .., fn heredado bajo el mismo nombre final genera una nica caracterstica en D (COMPARTICIN) 2) Cualesquiera dos de las f1, .., fn heredadas bajo diferente nombre, generan caractersticas diferentes en D (REPLICACIN) El primer caso es lo que normalmente se necesita
45

Regla del nombre nico


Dos caractersticas efectivas diferentes de una misma clase NO pueden tener el mismo nombre final.

{f}
f no provoca conflicto (comparticin) g causa conflicto

{g}

{g}

D
Ocurre un conflicto de nombres si una clase hereda dos caractersticas diferentes, ambas efectivas, con el mismo nombre. 46

b.1) Conflicto cuando hay comparticin


Si se heredan dos caractersticas bajo el mismo nombre puede ocurrir: (c1)

{f*}

(c2)
redefine f

{f}

{f}

{f} B
redefine f

C
redefine f

D LEGAL
Solo hay conflicto entre dos efectivas

{f}

LEGAL
Ambas versiones se funden 47 en una nueva

Conflictos cuando hay comparticin:


(c3) Ambas versiones efectivas y ambas no se redefinen:

A
redefine f

{f}
Soluciones: rename replicacin undefined (c1)

{f}

C {f}

D ILEGAL
Viola la Regla del nombre nico
48

Conversin en diferida
Dejar que una de las variantes se imponga sobre las otras Es posible al heredar transformar una rutina efectiva en diferida. class C inherit B undefine f feature ... end B {f+} undefine f C {f*}

Viene despus de rename (se aplica al nombre final) pero antes de redefine.
49

Indefinicin y unin
El mecanismo undefine proporciona la capacidad de unir caractersticas bajo herencia mltiple (no necesariamente repetida). Ejemplo: Se desea que C trate a f y g como una nica caracterstica (requiere semntica y signatura compatibles) {fA} A B {fB}
undefine f

{f}

{g}
rename g as f undefine f

C {fA} A impone la caracterstica

{f}
50

Combinacin de propiedades
Todas las restantes combinaciones son posibles: tomar la caracterstica de A y el nombre de B renombrar f y g y darle un nombre nuevo en C Reemplazar ambas versiones por una nueva (caso (c2))
ambas tienen el mismo nombre final (utilizar rename si no)

{fA} A redefine f

{fB} redefine f

C {fC}
51

b.2) Conflicto cuando hay replicacin


A
redefine f

{f}

oa:A; ob:B; oc:C; od:D; !!od ob:= od; ob. f oc:= od; oc. f oa:= od oa.f { o }

redefine f

{}

{f} B
rename f as bf

C {f}
rename f as cf

{}

{bf, cf}
No hay conflicto de nombres pero surge un nuevo problema debido a la ligadura dinmica.

52

Solucin al conflicto con la replicacin


class D inherit B rename select C rename select feature ... end f as bf; bf f as cf; cf

-- elimina ambigedad -- elimina ambigedad Regla del Select

Una clase, que de un antecesor repetido, hereda dos o ms versiones efectivas diferentes de una caracterstica y no las redefine a ambas, debe entonces incluir a una de las dos en una clusula select
53

La clausula select debe aparecer despus de rename, undefine y redefine.

Ejemplo: Conflicto con la replicacin


class A feature at: INTEGER proc is do print(at) end; end class B inherit A rename at as at1; select at1 A rename at as at2 feature ... end

A {at, proc}
rename at as at1 rename at as at2

B oa: A; ob: B !!ob oa:= ob oa. proc


se imprime at1 o at2?
54

Ejemplo: Conflicto con la replicacin


class A feature at: INTEGER redefine proc1 redefine proc1 proc1 is do .. end; B C proc2 is do proc1 rename proc1 print(at) as rut1 end; D end oa:A; od: D; {rut1, proc1, proc2} !!od; oa:=od; oa. proc2 ?? 55

{at, proc1, proc2}

Utilidad de la herencia repetida: mantener la


versin original junto con la redefinida.
class B inherit A redefine f select f A rename f as g feature ... end

A {f}
rename f as g redefine f select f

B {f, g}

Antes de introducir Precursor era la tcnica usada para que una rutina redefinida pudiese invocar a la rutina original.
56

Entidad Precursor (Eiffel)


Que sucede si hay herencia mltiple y una rutina tiene varios precursores ? A B C Que hacemos si queremos disponer en la nueva clase de la rutina original y la redefinida?
VENTANA {dibujar} rename dibujar as dibujar_ventana BOTON redefine dibujar {dibujar, dibujar_ventana}

{A} Precursor {B} Precursor

OJO!! AMBIGEDAD (ver Herencia Repetida) En JAVA?


57

Ejemplo:
VENTANA
redefine display display is do Precursor dibujar_bordes end

{display}
redefine display display is do Precursor dibujar_menu end

VENTANA_ BORDES

VENTANA_ MENU

redefine display

redefine display display is do {VENTANA_BORDES}Precursor {VENTANA_MENU} Precursor end


58

VENTANA_ BORDES_MENU

display de ventana se llama dos veces !!

Solucin:

no ser necesario el uso de la clusula select en VENTANA_BORDES_MENU por qu? VENTANA

{display}
redefine display display is do VENTANA_ Precursor MENU dibujar_menu end redefine display display is do {VENTANA}Precursor dibujar_menu dibujar_bordes 59 end

redefine display display is do Precursor dibujar_bordes end

VENTANA_ BORDES
redefine display

redefine display

VENTANA_ BORDES_MENU

Herencia repetida en C++: Replicacin


Por defecto, NO HAY COMPARTICIN, SE REPLICA TODO
class class class class A B D C A {int at1; ...} B: public A {...}; C: public A {...} D: public B, public C {...} A B D A C

El nivel de granularidad para decidir si compartir o duplicar es la clase Ambigedad se resuelve con calificacin de nombres: C::at1; B::at1 60

Herencia repetida en C++


Hay dos objetos A en un objeto D La asignacin entre un puntero a A y otro a D no est permita, es ambigua
parte A (de B) parte B parte A (de C) parte C parte D Estructura del objeto D
61

D* od = new D(); A* oa = od; oa=(A*)od; oa=(A*)(B*)od;

//ERROR: ambiguo //ERROR: ambiguo //OK!! //asigna el //subobjeto A de B

Herencia repetida en C++: Replicacin


class B {public: int b; ...} class D: public B, public B {...} {ILEGAL}

No se pueden resolver las ambigedades. B {int b}

void f (D *p) { p->b=7; }

//ambiguo
62

Herencia repetida en C++: Comparticin


Si queremos que la clase derivada herede slo una copia de la clase abuelo entonces las clases intermedias tienen que declarar que su herencia de la clase paterna es virtual.
Clase base virtual Significado distinto en este class A {char* at1; int f (); ...} contexto que en el de las class B: virtual public A {...}; funciones class C: virtual public A {...} No significa que todas las funciones son virtuales

class D: public B, public C {...}

Mecanismo que se opone a la extensibilidad


63

Cuando se utilizan clases base virtuales se puede llegar a la misma caracterstica a travs de mas de un camino sin que exista ambigedad.
{f,g,h,k} (virtuales) redefine f

clase base virtual redefine g

D* od= new D od->f(); od->g(); od->h(); C* oc = od oc->f();

C
redefine h

//B::f() //C::g() //D::h()

//B::f()

La versin redefinida domina a la virtual La misma situacin con clases base no virtuales produce 64 ambigedad (implica ms de un objeto).

Herencia repetida en C++ y clases virtuales


class V {public: int v}; class A {public: int a}; class B:public A, public virtual V {}; class C:public A, public virtual V {}; classD : public B, public C { public: void f();};

A B

{int v} V

A {int a} C
void D::f() { v++; //correcto solo hay un v a++; //ambiguo hay dos a }

D {f}

class V {public: int x; int f();}; class B: public virtual V { public: int x; int f();}; class C: public virtual V {}; classD : public B, public C {void g();};

{int f(); int x;} V int f(); B int x; D {void g();} C

void D::g() { x++; //OK! B::x domina a V::x f(); //OK! B::f() domina a V::f() }

65

Resumen Adaptaciones en Eiffel


Redefinir (redefine) Renombrar (rename) Resolver ambigedades en los nombres de las caractersticas Hacer efectiva una rutina Cambiar el tipo de un atributo o un parmetro de una rutina Combinar caractersticas (join) Cambiar el status de visibilidad de una caracterstica (export) Convertir en diferida una rutina efectiva (undefine) Eliminar conflictos de ligadura dinmica cuando existe herencia repetida (select)
66

4.-Herencia mltiple en Java: Interfaces


Java soporta herencia simple. Herencia mltiple:
til cuando una clase quiere aadir nuevo comportamiento y conservar parte del antiguo origina problemas: Herencia repetida (herencia de implementacin).

Solucin Java: herencia mltiple de interfaces. Java permite que una clase pueda heredar de ms de una INTERFACE Interface es el modo de declarar un tipo formado slo por mtodos abstractos (pblicos) y constantes, permitiendo que se escriba cualquier implementacin para estos mtodos. 67

Ejemplo: Interfaces en Java


interface Pila { void push(Object elem); void pop; Object top; boolean empty; boolean full; }
implcitamente abstract siempre public

Varias implementaciones posibles


class PilaFija implements Pila {..} class PilaVariable implements Pila {..}
68

Interfaces Java
SUPERTIPOS

Puede utilizarse como nombre de tipo

A oa; B ob; C oc = new C; oa = oc; ob = oc;

Puede utilizarse polimrficamente

SUBTIPO

Surgen colisiones de nombre 1) Sobrecarga 2) Comparticin 3) Ilegal (si difieren en el tipo del objeto que retorna)

Se le puede asignar cualquier obj que implemente la interfaz

69

Herencia de interfaces
A diferencia de las clases una interfaz puede heredar de ms de una interfaz Se utiliza herencia mltiple si se quiere que una clase implemente un interfaz y herede de otra clase
W X Z interface W { } interface X extends W { } class Y implements W { } class Z extends Y implements X { } Y X Z interface W { } interface X extends W { } interface Y extends W { } class Z implements X, Y {70 } W Y

Implementacin de una Interface


Una interfaz slo es interesante si una clase la implementa:
Un conjunto de implementaciones generales agrupadas en un paquete Implementacin especfica de cada clase

Utilizacin de una Interface


Simplemente heredando de la clase que implementa el interfaz Que hacemos si una clase hereda de otra y desea utilizar cierta implementacin de una interface?
!NO PODEMOS HEREDAR DOS VECES!
71

Uso de interface en Java


Solucin: crear un objeto de la clase de implementacin y remitirle los mtodos de la interface class B extends A implements X { Ximplem at1; public void metodo1(..) {at1.metodo1(..)} public int metodo2(..) {return at1.metodo2} } class Ximplem implements X {}
72

Ejemplo: uso de interfaces 1/2


Abstraccin de una mquina que se mueve con motor
interface Movil{ void enMarcha(); void alto(); void girar(double grados); void cambiaVelocidad(double kmHora); boolean quedaCombustible(); }

Un Barco que se mueve a motor


public class Barco implements Movil { }

Suponiendo que existe la clase Velero Cmo modelaramos un VeleroMotor que debe heredar de Barco y de Velero? 73

Ejemplo: uso de interfaces 2/2


Movil Barco Velero

VeleroMotor

74

Ejemplo: uso de interfaces 2/2


Movil Barco Barco Velero
class VeleroMotor extends Velero implements Movil{ Barco b; void enMarcha(){ b.enMarcha(); } boolean quedaCombustible(){ return b.quedaCombustible(); } }
75

VeleroMotor

Interfaces vs clases abstractas


Una interface no es una clase abstracta. Una clase abstracta puede estar parcialmente implementada. Una clase puede heredar de una nica clase, incluso si slo tiene mtodos abstractos.

Importante:
Es conveniente que el programador Java declare interfaces para las clases que cree, ya que NO EXISTE HERENCIA MULTIPLE.
76

Conclusin: OO y Objetivos Iniciales

La combinacin de clases, genericidad, herencia, redefinicin, polimorfismo, ligadura dinmica y clases diferidas permite satisfacer:
los principios/ reglas/ criterios de modularidad

los requisitos para la reutilizacin planteados en el primer tema.

77