O slideshow foi denunciado.
Seu SlideShare está sendo baixado. ×

Herencia_POO.ppt

Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Carregando em…3
×

Confira estes a seguir

1 de 80 Anúncio

Herencia_POO.ppt

Baixar para ler offline

Herencia es uno de los pilares en la Programacion Orientada a Objetos.
En esta diapositiva se muestra los principios de herencia y su implementacion en Java con clases abstractas e interfaces

Herencia es uno de los pilares en la Programacion Orientada a Objetos.
En esta diapositiva se muestra los principios de herencia y su implementacion en Java con clases abstractas e interfaces

Anúncio
Anúncio

Mais Conteúdo rRelacionado

Semelhante a Herencia_POO.ppt (20)

Mais recentes (20)

Anúncio

Herencia_POO.ppt

  1. 1. Lenguajes de Programación 2 Programación Orientada a Objetos Herencia Ing. Gustavo Arsenio Sosa Cataldo FACULTAD POLITÉCNICA - UNA
  2. 2. • Las clases solas no son suficientes para conseguir: • Reutilización • Generar código que: • Capture los aspectos comunes en grupos de estructuras similares, y • Permita la variación de estructuras de datos y algoritmos subyacentes • Extensibilidad • Necesidad de mecanismos para lograr: • Principio Abierto-Cerrado • Principio de la Elección Única Introducción
  3. 3.  Entre algunas clases pueden existir relaciones conceptuales:  Generalización: Se detectan las propiedades comunes.  Extensión: Se amplían las funcionalidades.  Especialización: Se implementan funcionalidades que son especificas  Combinación: Se combinan las funcionalidades de dos o más objetos  ¿Tiene sentido crear una clase a partir de otra(s)?  Herencia: soporte para registrar y utilizar estas relaciones, que posibilita la definición de una clase a partir de otra(s). Introducción
  4. 4. Jerarquía de Clases  La herencia permite organizar las clases en jerarquías en las cuales se:  Reutiliza el código de los objetos Padres.  Extiende los tipos de objetos del sistema.  Puede existir una clase “raíz” en la jerarquía de la cual heredan las demás directa o indirectamente.  La clase raíz incluye todas las características comunes a todas las clases  En Java esta clase es la clase Object • boolean equals(Object o) • String toString() • int hashCode()
  5. 5. Jerarquía de Clases Object Number Integer Float Double Figura FiguraCerrada Polígono Círculo Rectángulo
  6. 6. Herencia entre clases  Si una clase B hereda de otra A, entonces:  B incorpora la estructura (atributos) y comportamiento (métodos) de A,  B puede incluir adaptaciones:  B puede añadir nuevos atributos y métodos  B puede redefinir métodos de A • Refinamiento: Extendiendo el uso de un método de A • Reemplazo: Sobrescribir la implementación de un método de A  B puede implementar un método abstracto en A B hereda de A (A es la superclase y B la subclase) C hereda de B y A B y C son subclases de A B es un descendiente directo de A C es un descendiente indirecto de A
  7. 7. Tipos de Herencia • Herencia simple • Una clase puede heredar de una única clase. • Java, C# • Herencia múltiple • Una clase puede heredar de varias clases. • Clases forman un grafo dirigido acíclico • Problemas: • Herencia Repetida. • Conflicto de Nombres. A B C D B C D
  8. 8. Problemas de la Herencia Múltiple • Herencia Repetida Ocurre cuando se hereda una misma característica de dos o más líneas de herencia. • Solución 1.Especificar que línea de herencia usar. 2.Herencia Parcial, se elige que heredar de cada línea de herencia. 3.Renombrar características heredadas B a, b C a, c D a, b, c, d A a
  9. 9. Problemas de la Herencia Múltiple • Conflicto de Nombres Ocurre cuando se heredan característica diferentes pero con mismo nombre de dos o más líneas de herencia. • Solución 1.Especificar que línea de herencia usar. 2.Herencia Parcial, se elige que heredar de cada línea de herencia. 3.Renombrar características heredadas B b, x C c, x D b, c, x
  10. 10. ¿Cómo detectar la herencia durante el diseño? • Generalización (Factorización) Se detectan clases con un comportamiento común (p.e. Libro y Revista son de tipos de Publicación) • Especialización (Abstracción) Se detecta que una clase es un caso especial de otra (p.e. Rectángulo de Polígono)
  11. 11. Polígonos y Rectángulos  Tenemos la clase Poligono y necesitamos representar rectángulos:  ¿Debemos crear la clase Rectángulo partiendo de cero?  Podemos aprovechar la existencia de similitudes y particularidades entre ambas clases Polígono vértices : List<Punto> trasladar(int a, int b) dibujar() borrar() perimetro() Polígono(List<Punto> v) Rectángulo lado1 : int lado2 : int perimetro() Rectángulo(List<Punto> v, int l1, int l2) diagonal()
  12. 12. Polígonos y Rectángulos  Un rectángulo tiene muchas de las características de un polígono (dibujar(), borrar(), trasladar())  Pero tiene características especiales (diagonal(), lado1, lado2)  Algunas características de polígono pueden implementarse más eficientemente (perímetro()) Polígono vértices : List<Punto> trasladar(int a, int b) dibujar() borrar() perimetro() Polígono(List<Punto> v) Rectángulo lado1 : int lado2 : int perimetro() Rectángulo(Punto vsi, int l1, int l2) diagonal()
  13. 13. import gráficos.Punto; Import java.util.List; public class Polígono { //Un polígono es una lista de puntos protected List<Punto> vértices = null; public Polígono(List<Punto> vértices) { this.vértices = vértices; } public void trasladar (double a, double b) {…} public void dibujar() {…} public void borrar() {…} public double perímetro() {…} } Polígonos y Rectángulos
  14. 14. public double perímetro() { double total = 0; Punto ant = null; Punto actual = vertices.get(0); for (int i = 1; i < vertices.size(); i++){ ant = actual; actual = vertices.get(i); total = total + actual.distancia(ant); } total = total + actual.distancia(vertices.get(0)); return total; } Polígonos y Rectángulos
  15. 15. public class Rectángulo extends Polígono { protected double lado1, lado2; //Nuevos atributos public Rectángulo(Punto vsi; double lado1, double lado2) { this.vértices = new List<Punto>; this.vértices.add(vsi); Punto vsd = new Punto (vsi) vsd.trasladar (0, lado1); this.vertices.add(vsd); ... this.lado1 = lado1; this.lado2 = lado2; } ... Polígonos y Rectángulos
  16. 16. public double perímetro() { return (2*(lado1 + lado2 )); } public double diagonal() { return Math.sqrt(Math.pow(lado1, 2) + Math.pow(lado2, 2)) } // ¿Y que pasa con los demás métodos ? }  Todas las demás características de Polígono están disponibles automáticamente para la clase Rectángulo, no es necesario que se repitan. Polígonos y Rectángulos
  17. 17. Significado de la herencia Clases Herencia Módulo Mecanismo de Extensión Mecanismo de Reutilización Tipo Mecanismo de Especialización Clasificador de Tipos Sean: • Prop(X): Conjunto de características de la clase X • Dom(X): Conjunto de instancias de la clase X A {Prop(A)} B {Prop(B)} • B Hereda de A  Prop(A)  Prop(B) • Cualquier objeto de B puede ser considerado un objeto de A • Dom(B)  Dom(A)  B es un Subtipo de A • Si se espera un objeto A, podemos recibir o enviar un objeto B.
  18. 18. Significado de la herencia Polígono vértices : List<Punto> trasladar(int a, int b) dibujar() borrar() perimetro() Polígono(List<Punto> v) Rectángulo lado1 : int lado2 : int perimetro() Rectángulo(Punto vsi, int l1, int l2) diagonal() 1. Prop(Polígono) = {vértices, trasladar(), dibujar(), borrar(), perímetro()} 2. Prop(Rectángulo) = {vértices, trasladar(), dibujar(), borrar(), perímetro(), lado1, lado2, diagonal()}
  19. 19. Significado de la herencia 1. Dom(Polígono) = {recA, recB, polA, polB} 2. Dom(Rectángulo) = {recA, recB, PolB} Rectángulo recA = new Rectángulo(…); Polígono polA = new Polígono(…); Polígono polB = new Rectángulo(…); Rectángulo recB = new Rectángulo(…); Polígono polC = null; Rectangulo recC = null;
  20. 20. Significado de los subtipos • El principio de sustitución de Liskov [B. Liskov 88]: • “ Si para cada objeto O1 de tipo S hay un objeto O2 de tipo T, tal que para todos los programas P definidos en términos de T, sí el comportamiento de P no varía cuando se sustituye O2 por O1 entonces S es un subtipo de T ” • Funciones que utilizan referencias a superclases deben ser capaces de utilizar objetos de sus subclases sin saberlo. • public static void dibujarEnPantalla(Polígono p); • dibujarEnPantalla(new Rectangulo(...))
  21. 21. Herencia y Creación  Los constructores no se heredan  El constructor de la clase hija refina el comportamiento del constructor del padre  La primera sentencia del constructor de la clase hija SIEMPRE es una llamada al constructor de la clase padre.  La llamada al constructor del padre puede ser:  Implícita: • Si se omite, se llamará implícitamente al constructor por defecto de la clase padre • Equivale a poner como primera sentencia super();  Explícita: • super(); o super(a,b); o . . . • Dependiendo del número y tipo de parámetros se invoca uno de los constructores de la clase padre
  22. 22. Acceso protegido en Java • Una subclase no puede acceder a los atributos o métodos privados de su superclase • Para permitir que un método de la subclase pueda acceder a un atributo o un método de la superclase, éste tiene que declararse como protected o public • Resumen de modificadores de acceso: – private – visible sólo en la clase – public – visible a todas las clases – protected – visible a las subclases y a (sub)clases del paquete – default – visible en las clases del paquete
  23. 23. Herencia en Java • Toda clase hereda directa o indirectamente de la clase Object • public class Poligono {...} // hereda de Object • public class Rectangulo extends Poligono {...} • Una subclase hereda de su superclase métodos y atributos tanto de clase como de instancia, pero solo puede acceder a las que están definidas como public o protected. • Una subclase puede añadir nuevos métodos y atributos. • Una subclase puede redefinir métodos heredados.
  24. 24. Redefinición • La redefinición reconcilia la Reutilización con la Extensibilidad: • “Es raro reutilizar un componente software sin necesidad de cambios” • Los atributos no se pueden redefinir, sólo se OCULTAN • El campo de la superclase todavía existe pero solo se puede acceder por medio de super • Un método de la subclase con la misma signatura y valor de retorno que un método de la superclase lo está REDEFINIENDO. • Si se cambia el tipo de los parámetros se está SOBRECARGANDO el método original y no redefiniendo
  25. 25. Redefinición de métodos • Una clase hija puede redefinir un método de la clase padre por dos motivos: • Reemplazo: • Mejorar implementación. • Ej: redefinición de perímetro() en la clase Rectángulo. • Cambiar la Implementación sin variar la semantica. • Refinamiento: • Método del padre + acciones específicas. • La invocación al método del padre se hace usando la palabra super
  26. 26. Refinamiento. Ejemplo public class CuentaAhorro extends Cuenta { ... public void ingresar(double cantidad) { //Hace lo mismo que el método de la clase padre super.ingresar(cantidad); //Además hace cosas propias de la CuentaAhorro beneficio = cantidad * PORCENTAJE_BENEFICIO; } }
  27. 27. ¿Qué se puede cambiar en la redefinición? • El nivel de acceso • Siempre que se relaje • Puede pasar de protected a public • Por ejemplo, método clone en Object es protected • No se puede pasar de public a private • El tipo de retorno • Siempre que el tipo de retorno del método redefinido sea compatible con el tipo de retorno del método original. • Object  protected Object clone() … (desde Java 1.5) • Punto  public Punto clone() …
  28. 28. Restringir la herencia y redefinición  En Java se puede aplicar el modificador final a un método para indicar que no puede ser redefinido.  El modificador final es aplicable a una clase indicando que no se puede heredar de ella.  ¿El modificador final va contra el principio abierto- cerrado?
  29. 29. Polimorfismo • El término polimorfismo significa que hay un nombre (referencia, método o clase) y muchos significados diferentes para el mismo (distintas definiciones). • Formas de polimorfismo [Budd’02]: – Polimorfismo de asignación (variables polimorfas) – Polimorfismo puro (función polimorfa) – Polimorfismo ad hoc (sobrecarga) – Polimorfismo de inclusión (redefinición) – Polimorfismo paramétrico (genericidad)
  30. 30. Polimorfismo de Asignación  Capacidad de una entidad de referenciar en tiempo de ejecución a instancias de diferentes clases  El conjunto de clases a la que se puede hacer referencia está restringido por la Herencia.  Dada una referencia R de tipo T, en un lenguaje orientado a objetos fuertemente tipado R puede referenciar a cualquier objeto de tipo S, siempre que S sea un subtipo de T.  Number n; n = new Integer(); n = new Double(); n = new BigDecimal();
  31. 31. Tipo estático y tipo dinámico • Tipo estático (te): – Tipo asociado en la declaración. Ej: Number n; • Tipo dinámico: – Tipo correspondiente a la clase del objeto conectado a la entidad en tiempo de ejecución. Ej: n = new Float(3.14); • Conjunto de tipos dinámicos (ctd): – Conjunto de posibles tipos dinámicos de una entidad A oa; B ob; C oc; te(oa) = A ctd(oa) = {A,B,C,D,E,F} te(ob) = B ctd(ob) = {B, D, E} te(oc) = C ctd(oc) = {C,F}
  32. 32. Entidades y rutinas polimorfas Conexión polimorfa: el origen y el destino tiene tipos diferentes Poligono p; Rectangulo r; a) asignación: p = r; -- p es una entidad polimorfa (polimorfismo de asignación) b) paso de parámetros: void f (Poligono p)… -- f es una rutina polimorfa (polimorfismo puro)
  33. 33. Polimorfismo puro vs. Sobrecarga • Funciones sobrecargadas ≠ funciones polimórficas • Sobrecarga: – Dos o mas funciones comparten el nombre y distintos argumentos (nº y tipo). El nombre es polimórfico. – Distintas definiciones (distintos comportamientos) – Función correcta se determina en tiempo de compilación según la signatura. • Funciones polimórficas: – Una única función que puede recibir una variedad de argumentos (comportamiento uniforme). – La ejecución correcta se determina dinámicamente en tiempo de ejecución.
  34. 34. Herencia y sistema de tipos A a; B b; C c; D d; ¿Son válidas las siguientes asignaciones? a = b; c = b; a = d
  35. 35. Ligadura dinámica ó Enlace dinámico {fδ} redefine f ¿qué versión de f se ejecuta? A oa; … // asignacion de oa oa.f(..); Regla de la ligadura dinámica La forma dinámica del objeto determina la versión de la operación que se aplicará.
  36. 36. • La versión de un método en una clase es la introducida por la clase (redefinición u original) o es la heredada. • Ejemplo: Poligono p = new Poligono(); Rectangulo r = new Rectangulo(); Double x; x = p.perimetro() → perimetro POLIGONO x = r.perimetro() → perimetro RECTANGULO p = r; x = p.perimetro() → perimetro RECTANGULO Ligadura dinámica ó Enlace dinámico
  37. 37. {fδ} redefine f A a; B b = new B(); D d = new D(); a = b; a.f(); //q versión? a = d a.f(); //q versión? Ligadura dinámica ó Enlace dinámico
  38. 38. Ejemplo 2: void visualizar (Figura [] figuras){ for (Figura figura : figuras) figura.dibujar(); } ¿Qué sucede si aparece un nuevo tipo de figura? ¿Qué relación existe entre ligadura dinámica y comprobación estática de tipos? Sea el mensaje x.f (), la comprobación estática de tipos garantiza que al menos el mensaje sea válido, y la ligadura dinámica garantiza que se ejecutará la versión más apropiada. Ligadura dinámica ó Enlace dinámico
  39. 39. Ejemplo ligadura dinámica, super y this class Uno { public int test(){return 1;} public int result1(){return this.test();} } class Dos extends Uno{ public int test(){return 2;} } class Tres extends Dos{ public int result2(){return this.result1();} public int result3(){return super.test();} } class Cuatro extends Tres{ public int test(){return 4;} }
  40. 40. public class PruebaSuperThis{ public static void main (String args[]){ Uno ob1 = new Uno(); Dos ob2 = new Dos(); Tres ob3 = new Tres(); Cuatro ob4 = new Cuatro(); System.out.println("ob1.test = "+ ob1.test()); System.out.println("ob1.result1 = " + ob1.result1()); System.out.println("ob2.test = " + ob2.test()); System.out.println("ob2.result1 = " + ob2.result1()); System.out.println("ob3.test = " + ob3.test()); System.out.println("ob4.result1 = " + ob4.result1()); System.out.println("ob3.result2 = " + ob3.result2()); System.out.println("ob4.result2 = " + ob4.result2()); System.out.println("ob3.result3 = " + ob3.result3()); System.out.println("ob4.result3 = " + ob4.result3()); } } Ejemplo ligadura dinámica, super y this 1
  41. 41. {fδ} redefine f A a; B b = new B(); D d = new D(); a = b; a.f(); //versión B a = d a.f(); //versión D Principio de la Elección Única Principio de la Elección Única Gracias al polimorfismo el modulo A conoce todas sus variantes por medio del enlace dinámico se aplica la versión correcta de una operación
  42. 42. Código Genérico  Un único código con diferentes interpretaciones en tiempo de ejecución  Es fundamental que el lenguaje soporte:  Polimorfismo  Ligadura Dinámica  El mismo código ejecutará cosas distintas en función del Tipo Dinámico de la entidad polimórfica (ligadura dinámica)  Gracias al polimorfismo y la ligadura dinámica se satisface el criterio de reutilización de Variación de la Implementación.
  43. 43. Código Genérico  class CalculadorDeCostos { /* Los objetos de esta clase calculan el costo de diversas cosas */ ... public double precioDeVallado(Parcela p) { Poligono forma = p.getForma(); double costo = forma.getPerimetro() * this.getCostoVallado(); return costo; } }  forma puede ser cualquier objeto de tipo Poligono.  El mensaje forma.getPerimetro() tendrá diferentes significados según sea el tipo dinámico de forma.
  44. 44. Copias de Objetos  Tipos de copia:  Copia superficial: los campos de la copia son exactamente iguales a los del objeto original.  Copia profunda: los campos primitivos de la copia son iguales y las referencias son copias de los objetos referenciados por el original.  Adaptada: adaptada a la necesidad de la aplicación.
  45. 45. Copia superficial  Alias Dinámico: Incorrecto al compartir las últimas operaciones  No deberían tener el mismo valor de código
  46. 46. Copia profunda  No tiene sentido duplicar el objeto Persona  No deberían tener el mismo código
  47. 47. Copia adaptada
  48. 48. Copia adaptada  Para implementar la copia se debe redefinir el método:  protected Object clone();  class Cuenta { ... public Cuenta clone() { Cuenta clon = super.clone(); // copia superficial clon.codigo = Cuenta.getSgteCodigo(); // código nuevo clon.ultOper = new ArrayList<Integer>(); // se copian las operaciones for (Integer oper : this.ultOper) { clon.ultOper.add(new Integer(oper)); } return clon; } }
  49. 49. Igualdad de Objetos  Tipos de igualdad:  Superficial: los campos primitivos de los dos objetos son iguales y las referencias apuntan a los mismos objetos (==).  Profunda: los campos primitivos son iguales y las referencias no son los mismos objetos pero estos son iguales en profundidad (equals).  Adaptada: adaptada a las necesidades de la aplicación.  ¿Cuándo dos cuentas son iguales?
  50. 50. Igualdad de Objetos  Para implementar la comparación se debe redefinir el método:  public boolean equals(Object o2);  class Cuenta { ... public boolean equals(Object o2) { if(!(o2 instanceof Cuenta) ) return false; Cuenta c2 = (Cuenta) o2; if ( this.saldo != c2.saldo || this.titular != c2.titular || this.ultOper.size() != c2.ultOper.size() ) return false; for (int i = 0; i < this.ultOper.size() ; i++) { if (! this.ultOper.get(i).equals( c2.ultOper.get(i)) ) return false; } return true; } }
  51. 51. Genericidad restringida  Public class Vector <T> { private int count; public T item( int i ){…} public void put (T v, int index){…} public Vector<T> suma (Vector<T> otro){ Vector<T> result= new Vector<T>(); for(int i = 1; i <= count; i++) { result.put( this.item(i) + otro.item(i) , i); } return result; } }
  52. 52. Genericidad restringida  Public class Vector <T extends Number> { private int count; public T item( int i ){…} public void put (T v, int index){…} public Vector<T> suma (Vector<T> otro){ Vector<T> result = new Vector<T>(); for(int i = 1; i <= count; i++) { result.put( this.item(i) + otro.item(i) , i); } return result; } }
  53. 53. Herencia de una clase Genérica  La subclase puede seguir siendo genérica:  Class Pila<T> extends ArrayList<T> {…}  Al heredar de una clase genérica se puede restringir el tipo:  class ListaOrdenada<T extends Comparable> extends LinkedList<T> {…}  Al heredar de una clase genérica se puede instanciar el tipo:  Class CajaSeguridad extends LinkedList<Valorable> {…}
  54. 54. Genericidad y Herencia 1. List<Poligono> lp; 2. List<Rectangulo> lr = new List<Rectangulo>(); 3. lp = lr; //Error de compilación
  55. 55. Tipos Comodín  Dado el código de la clase Paint: Class Paint { public static void imprimir (List<Poligono> poligonos) { for(Poligono p : poligonos) System.out.println(p); } }  El siguiente código daría error: List<Rectangulo> lr = new LinkedList <Rectangulo> (); Paint.imprimir(lr); //Error no es una List<Poligono>  Para que no de error hay que usar el tipo comodín en la declaración del método void imprimir (List<? extends Poligono> poligonos)
  56. 56.  Dado el siguiente código:  Figura f; Rectangulo p; p = new Rectangulo(...); f = p; f.dibujar();  ¿Como se implementa el método dibujar en la clase Figura? Clases Abstractas
  57. 57. Clases Abstractas  public abstract class Figura { public abstract double perimetro(); public abstract void dibujar(); public abstract void borrar(); public abstract void mover(); public abstract void rotar(); … }  public abstract class FiguraCerrada extends Figura { public abstract double area(); }  public abstract class Poligono extends FiguraCerrada { ArrayList<Punto> vertices; public double perimetro() {...} public void dibujar() {...} public void borrar() {...} public void mover() {...} public void rotar() {...} }  public class Rectangulo extends Poligono { double largo, ancho; public double area() {...} public double perimetro {...} public double diagonal() {...} } Figura +perimetro():double +dibujar(): void +borrar(): void +mover(): void +rotar():void FiguraCerrada Polígono Elipse Rectángulo Circulo Rombo FiguraAbierta
  58. 58. Clases Abstractas  Toda clase que contenga algún método abstracto (heredado o no) es abstracta.  Una clase puede ser abstracta y no contener ningún método abstracto.  Especifica una funcionalidad que es común a sus subclases.  Puede ser total o parcialmente abstracta.  No es posible crear instancias de una clase abstracta, pero si declarar referencias del tipo de la clase.  La clase puede incluir la definición del constructor.  Las clases abstractas sólo tienen sentido en un lenguaje con comprobación estática de tipos.
  59. 59. Clases Parcialmente Abstractas  Contienen métodos abstractos y efectivos.  Los métodos efectivos pueden hacer uso de los abstractos.  Importante mecanismo para incluir código genérico.  Incluyen comportamiento abstracto común a todos los descendientes.  “programming with holes” - Programación con hoyos  Capturar lo conocido sobre el comportamiento y la estructura de datos que caracterizan a cierta área de aplicación, dejando una puerta abierta a la variación  Factorización del comportamiento común
  60. 60. Clases Parcialmente Abstractas Método de la Plantilla
  61. 61. Interfaces  Son similares a “clases totalmente abstractas” que solo declaran el comportamiento para un objeto pero no lo implementan  Se declaran utilizando la palabra interface.  public interface Comparable <T> { public int compararCon(T o2); }  Por defectos todos sus métodos son públicos y abstractos.  Sus atributos solo pueden ser públicos, constantes y de clase.  public static final int ATRIBUTO = 1;
  62. 62. Interfaces  Las clases pueden implementar un interfaz  class Entero implements Comparable<Numero> { ... Public int compararCon (Numero o2) { return this.valorEntero() – o2.valorEntero(); ... }  Cualquier clase efectiva que implemente una interfase debe definir todos los métodos de dicho interfase  Si la clase no proporciona la implementación para todos los métodos del interfase debe ser declarada como abstracta  No se pueden crear objetos de una Interfaz, pero si puede ser utilizada como tipo de dato.  Comparable<Numero> c = new Entero();
  63. 63. Interfaces Parametrización del Comportamiento ... Colección <Cuenta> cuentas = Banco.getCuentas(); if (cuentas.buscarCuentasSaldoCero(cuentas)) { System.out.println(“Hay cuentas con saldo cero”) } if (cuentas.buscarCuentasSaldoNegativo(cuentas)) { System.out.println(“Hay cuentas con saldo negativo”) } ...
  64. 64. Interfaces Parametrización del Comportamiento
  65. 65. Interfaces Parametrización del Comportamiento
  66. 66. Interfaces Parametrización del Comportamiento Método de Composición <<usa>> <<implementan>>
  67. 67. Interfaces Parametrización del Comportamiento  public interface ICondicion<T> { public boolean test ( T obj ); }  public class CuentaSaldoCero implements ICondicion<Cuenta> { public boolean test ( Cuenta obj ) { if (obj.getSaldo() == 0.0) { return true; } return false; } }  public class CuentaSaldoNegativo implements ICondicion<Cuenta> { public boolean test ( Cuenta obj ) { if (obj.getSaldo() < 0.0) { return true; } return false; } }
  68. 68. Interfaces Parametrización del Comportamiento ... Colección <Cuenta> cuentas = Banco.getCuentas(); if (cuentas.buscar (new CuentaSaldoCero())) { System.out.println(“Hay cuentas con saldo cero”); } if (cuentas.buscar (new CuentaSaldoNegativo())) { System.out.println(“Hay cuentas con saldo negativo”); } ...
  69. 69. Clases Anónimas • A veces no es necesario usar la clase más de una vez! Colección <Cuenta> cuentas = Banco.getCuentas(); // buscar cuentas con saldo mayor a 10.000 if (cuentas.buscar (new ICondicion<Cuenta> (){ public boolean test (Cuenta obj) { return obj.getSaldo > 10000.0; } } ) { System.out.println(“Hay cuentas con saldo mayor a 10.000”); } ...
  70. 70. Herencia de Interfaces  Una interfaz puede ser extendida para definir más funcionalidades necesarias en otros objetos. public interface Nombrable { public void setNombre(); public String getNombre(); } public interface NombrableGraficamente extends Nombrable { public void graficarNombre(); }
  71. 71. Implementación de múltiples Interfaces  Una clase puede implementar más de una interfaz public interface Nombrable { public void setNombre(String n); public String getNombre(); } public class BienActivoFijo implements Nombrable, Codificable { ... } public interface Codificable { public void setCodigo(Integer n); public Integer getCodigo(); }
  72. 72. Herencia Múltiple  La herencia múltiple permite:  Extender el sistema de tipos, permitiendo que la clase heredada sea compatible con los tipos de las clases de cuales hereda.  Reutilizar el código de dos o más clases en la clase hija  En Java no existe la Herencia Múltiple, sin embargo puede ser esta puede ser emulada a través del uso de las interfaces
  73. 73. Herencia Múltiple  Supóngase que un sistema académico posee las clases Alumno y Profesor de las cuales se desea extender un nuevo objeto llamado AlumnoAsistente  En un sistema OO con herencia múltiple la solución sería la siguiente: Alumno private String nombre private String cedula private Asignatura materias[] public Alumno(String n, String c, Asignatura m[]) public String getNombre() public String getCedula() public Asignatura[] getMaterias() public void estudiar () public void irAClases() public void rendir() Profesor private String nombre private String cedula private Asignatura asignaturas[] public Profesor(String n, String c, Asignatura a[]) public String getNombre() public String getCedula() public Asignatura[] getAsignaturas() public void preprarClases() public void darClases() public void tomarExamen() AlumnoAsistente
  74. 74. Herencia Múltiple  En Java, un sistema OO sin herencia múltiple, la solución consiste en heredar de una de las clases e implementar una interfaz que defina el comportamiento de la otra clase Alumno private String nombre private String cedula private Asignatura materias[] public Alumno(String n, String c, Asignatura m[]) public String getNombre() public String getCedula() public Asignatura[] getMaterias() public void estudiar () public void irAClases() public void rendir() Profesor public String getNombre() public String getCedula() public Asignatura[] getAsignaturas() public void preprarClases() public void darClases() public void tomarExamen() AlumnoAsistente
  75. 75. Herencia Múltiple  Sin embargo esta solución es parcial con respecto a la herencia múltiple:  Se extiende el sistema de tipos pues AlumnoAsistente hereda el comportamiento de Alumno e implementa el comportamiento definido por la interface Profesor .  Sin embargo la reutilización es parcial ya que AlumnoAsistente debe repetir código de los métodos de Profesor. Alumno private String nombre private String cedula private Asignatura materias[] public Alumno(String n, String c, Asignatura m[]) public String getNombre() public String getCedula() public Asignatura[] getMaterias() public void estudiar () public void irAClases() public void rendir() Profesor public String getNombre() public String getCedula() public Asignatura[] getAsignaturas() public void preprarClases() public void darClases() public void tomarExamen() AlumnoAsistente
  76. 76. Herencia Múltiple  Los métodos con el mismo nombre en Alumno e Profesor no entran en conflicto pues para ambos casos getNombre y getCedula se refieren al mismo dato Alumno private String nombre private String cedula private Asignatura materias[] public Alumno(String n, String c, Asignatura m[]) public String getNombre() public String getCedula() public Asignatura[] getMaterias() public void estudiar () public void irAClases() public void rendir() Profesor public String getNombre() public String getCedula() public Asignatura[] getAsignaturas() public void preprarClases() public void darClases() public void tomarExamen() AlumnoAsistente
  77. 77. Herencia Múltiple  Una solución equivalente a la Herencia Múltiple sería que los objetos de la clase AlumnoAsistente deleguen la implementación de los métodos de la interface Profesor en un objeto de alguna clase que los implementen  Para ello, los objetos de la clase AlumnoAsistente deben componerse de tal objeto. Alumno private String nombre private String cedula private Asignatura materias[] public Alumno(String n, String c, Asignatura m[]) public String getNombre() public String getCedula() public Asignatura[] getMaterias() public void estudiar () public void irAClases() public void rendir() Profesor public String getNombre() public String getCedula() public Asignatura[] getAsignaturas() public void preprarClases() public void darClases() public void tomarExamen() AlumnoAsistente ObjetoQue Implementa Profesor
  78. 78. Herencia Múltiple  Por ejemplo si se tiene una clase ImplProfesor que implementa el comportamiento de la interface Profesor, los objetos de la clase AlumnoAsistente pueden componerse de un objeto de la clase ImplProfesor sobre el cual delegar los comportamientos definidos por la interface Profesor. Alumno private String nombre private String cedula private Asignatura materias[] public Alumno(String n, String c, Asignatura m[]) public String getNombre() public String getCedula() public Asignatura[] getMaterias() public void estudiar () public void irAClases() public void rendir() Profesor public String getNombre() public String getCedula() public Asignatura[] getAsignaturas() public void preprarClases() public void darClases() public void tomarExamen() AlumnoAsistente ObjetoQue Implementa Profesor ImplProfesor private String nombre private String cedula private Asignatura asignaturas[] public String getNombre() public String getCedula() public Asignatura[] getAsignaturas() public void preprarClases() public void darClases() public void tomarExamen()
  79. 79. Herencia Múltiple 1. class AlumnoAsistente extends Alumno implements Profesor { 2. private Profesor p; // referencia al objeto que implementa Profesor 3. public AlumnoAsistente(String nom, String ced, Asignatura[] matAlu, Asignatura[] matProf) { 4. super(nom, ced, matAlu); 5. this.p = new ProfesorImpl(nom, ced, matProf); 6. } 7. // métodos delegados en el objeto que implementa Profesor 8. public Asignatura[] getAsignaturas() { return p.getAsignaturas() } 9. public void enseñar() { p.enseñar () } 10. public void prepararClases() { return p.prepararClase() } 11. public void tomarExamen() { return p.tomarExamen() } 12. 13. // los métodos heredados de Alumno complementan el comportamiento del tipo Alumno 14. // y también complementan la implementación de la interfaz Profesor 15. }
  80. 80. Herencia Múltiple El siguiente código es válido: 1. AlumnoAsistente alAs = new AlumnoAsistente(n, c, matAl, matPr); 2. // el objeto es de tipo Alumno por heredar de dicha clase 3. Alumno a = alAs; 4. // el objeto es de tipo Profesor por implementar dicha interfaz 5. Profesor p = alAs;

×