Fundamentos de Programación Extensión de clases: herencia y polimorfismo 13.12.2010 José A. Mañas <jmanas@dit.upm.es> Dpto. de Ingeniería de Sistemas Telemá@cos hcp://www.lab.dit.upm.es/~fprg/
extensión de clases class sub extends super {... super sub 13.12.2010 2
class B extends A public class A { private int m; public int getm() { return m; public class B extends A { private int n; public int getn() { return n; 13.12.2010 3
class B extends A 13.12.2010 4
herencia B hereda de A los campos que no sean private los métodos que no sean private class B extends A B puede aportar lo que quiera si no colisiona 13.12.2010 5
ventajas Se evita el código duplicado se escribe en 1 clase y se hereda en otras clases sólo hay que arreglar los errores en la clase madre Se abre la posibilidad de extender el programa sub@pos 13.12.2010 6
jerarquías sub@pos Poligono Triangulo Cuadrilatero Cuadrado Rectangulo Rombo 13.12.2010 7
... es un... Se dice que un triángulo es un polígono un cuadrilátero es un poligono un cuadrado es un cuadrilátero, que es un poligono un rectángulo es un cuadrilátero, que es un poligono un rombo es un cuadrilátero, que es un poligono 13.12.2010 8
inicialización: constructores class B extends A Para inicializar un objeto hay que inicializar antes la parte heredada Los constructores de B empiezan llamando a los constructores de A Bien explícitamente El programador escribe el código de la llamada super(argumentos del constructor de la superclase); Bien implícitamente Si el programado no lo escribe: el compilador lo inyecta super(); 13.12.2010 9
polimorfismo Una variable de @po superclase puede albergar valores de cualquier subclase Triangulo t =...; Poligono p = t; Rectangulo r =...; Cuadrilatero c = r; Poligono p = r; las variables pueden adoptar diferentes formas 13.12.2010 10
polimorfismo ArrayList<Poligono> dibujo= new ArrayList<Poligono>; dibujo.add (new Triangulo(...) ); dibujo.add (new Cuadrado(...) ); dibujo.add (new Cuadrilatero(...) ); for (Poligono p : dibujo) { p.dibuja(); 13.12.2010 11
susbtución - upcas(ng class B extends A Las variables de clase B sólo pueden referirse a objetos de clase B Las variables de clase A pueden referenciar objetos de clase A (normal) pueden referenciar objetos de clase B (upcas&ng) El upcas&ng es 100% seguro y siempre se puede aplicar A vara= new B(); 13.12.2010 12
de qué clase soy? Exactamente soy... System.out.print ( x.getclass() ) ; Pertenezco a la jerarquía de... Soy sub@po de... if (x instanceof Cuadrilatero)... 13.12.2010 13
subir y bajar Subir: upcas&ng Poligono poligono= new Cuadrado() siempre es posible Bajar: downcas&ng Cuadrado cuadrado= (Cuadrado) poligono; hay que hacerlo explícitamente sólo es posible si es cierto si no, se salta un error 13.12.2010 14
ámbitos de visibilidad Los miembros de una clase puede verse... afecta a campos y métodos private sólo dentro del fichero.java no se dice nada sólo dentro del directorio (paquete) protected public dentro del directorio y en las subclases desde cualquier si@o 13.12.2010 15
herencia B hereda de A los miembros (campos y métodos) B puede ocultar campos de A (los no private) B puede redefinir métodos de A (de objeto) class B extends A poco importante B puede aportar lo que quiera si no colisiona 13.12.2010 16
La subclase puede ocultar campos a base de definir campos con el mismo nombre ocultación poco importante Se puede acceder a los elementos de la superclase vía upcas&ng creando una variable de la clase que necesitamos 13.12.2010 17
ocultación poco importante public class A { protected char x = 'a'; A a = new A(); B b = new B(); A ab= new B(); System.out.println(a.x); System.out.println(b.x); System.out.println(ab.x); public class B extends A { protected char x = 'b'; // upcas@ng a b a // se cree que es A 13.12.2010 18
La subclase puede redefinir métodos de objetos a base de definir métodos con la misma signatura mismo nombre mismo número y @po de argumentos igual o más visible (paquete) public igual resultado redefinición signatura overriding 13.12.2010 19
polimorfismo Si class B extends A y B modifica metodo(), y hacemos upcas&ng A ab= new B (); class A { void metodo() {... class B extends A { void metodo() {... si escribimos el compilador cree que nos referimos a pero java ejecuta ab.metodo() A.metodo() B.metodo() 13.12.2010 20
public class A { public String getme() { return "Soy A"; polimorfismo public class B extends A { public String getme() { return "Soy B"; muy importante A a = new A(); B b = new B(); A ab= new B(); System.out.println(a.getMe()); System.out.println(b.getMe()); System.out.println(ab.getMe()); // upcas@ng Soy A Soy B Soy B // sabe que es B 13.12.2010 21
elección dinámica el programa A ab = new B(); ab.getme(); las clases A getme() B extends A el objeto getme() A ab instance of la variable 13.12.2010 22
estábco vs dinámico A ab = new B(); Tipo está@co el que @ene una variable en compilación ab es de @po A Tipo dinámico el del objeto al que se referencia en ejecución ab referencia un objeto de @po B 13.12.2010 23
super Sólo se puede acceder a un método redefinido desde la subclase inmediatamente inferior usando el prefijo super public class B extends A { public String getme() { return super.getme() + "Soy B"; A a = new B(); a.getme(); // upcas@ng Soy A Soy B 13.12.2010 24
super public class Punto2D { private double x, y; public void set(double[] coordenadas) { this.x = coordenadas[0]; this.y = coordenadas[1]; public class Punto3D extends Punto2D { private double z; public void set(double[] coordenadas) { super.set(coordenadas); this.z = coordenadas[2]; 13.12.2010 25 / 18
class Object Todas las clases de Java son extensiones de la clase Object (predefinida) Object x= new cualquiercosa (...); Object proporciona métodos generales public String tostring (); public boolean equals (Object x); 13.12.2010 26
class Object System.out.println(x) sabe imprimir cualquier objeto public class Fraccion { private int num; private int den; public String tostring() { return num + / + den; 13.12.2010 27
Cualquier objeto se puede comparar con cualquier otro class Object public class Object { public class Fraccion { private int num; private int den; public boolean equals(object x) { return x == this; public boolean equals(object x) { if (x == this) return true; if (x == null) return false; if (x.getclass()!= this.getclass()) return false; Fraccion fraccion = (Fraccion)x; return this.num * fraccion.den == this.den * fraccion.num; 13.12.2010 28 / 18
final Una clase final no se puede extender public final class String {... Un método final no se puede redefinir public final String cifra(string texto, String clave); evita sorpresas 13.12.2010 29
conceptos Extensión Herencia superclases y subclases Jerarquías de @pos super@pos y sub@pos Subir y bajar: cas@ng subir: sus@tución o upcas&ng bajar: downcas&ng 13.12.2010 30
conceptos protected Ocultación (un poco secundario) Redefinición Polimorfismo @po está@co vs @po dinámico elección dinámica de método (muy importante) final: clases y métodos 13.12.2010 31
ejercicio 1.1 Dado un mensajero public class Mensajero { public String recita() { return Feliz Navidad ; 1. hacer un refinamiento: mensajero borde que dice Ajo y Agua 2. hacer un refinamiento: mensajero redicho que dice dicen que diga Feliz Navidad 13.12.2010 32
Escribir clases para calcular el perímetro de ejercicio 2.1 Poligono ver@ces... Triangulo Cuadrilatero A, B, C A, B, C, D Rectangulo base, altura Rombo eje1, eje2 13.12.2010 33
ejercicio 3.1 Dada una cola public class Cola { private List<String> datos= new ArrayList<String>(); public Cola() { public void mete(string s) { datos.add(s); public String saca() { return datos.remove(0); hacer un refinamiento que impone un tamaño máximo si la cola está llena, no se inserta nada hacer otro refinamiento donde si la cola está llena, se elimina el primero antes de añadir 13.12.2010 34