Programación Orientada a
Objetos en Java
Sesión 11: Clases abstractas e
Interfaces
Motivación
! "#$%&'#()*+,(-($.+/$()($+ ! 01#(2()*+3'454.+2%&'67+ ! "#$%&'#()*+,48#$(.+$72%(+ ! 01#(2()*+3'454.+2%&'67+ ! "#$%&'#()*+4)9'%87:.+4)9'%87;+ ! 01#(2()*+3'454.+2%&'67+ Figura Circulo Cuadrado ! <87+=73%-%7+24+,-7)4)+3'>+?7$4,%27)+48+,'78#(+7+@9'1A+B7,48+?4$(+ 8(+48+@,C3(A+-(+B7,48+)(8+,782%27#7)+7+B4$427$+24+'87+,-7)4+?72$4+ ,(3D8+2(824+)4+24E84+4-+@9'1A+,(3?7$F2(G+ ! H$473()+-7+,-7)4+?72$4+,(8+-7+?7$#4+,(3D8+I3%43&$()J+>+-()+ 31#(2()+9'4+9'4$43()+(&-%/7$+9'4+#48/78+-7)+B%67)G+ ! KL'1+,(3?($#73%48#(+?(8/(+48+-7+,-7)4+?72$4M+ ! KHC3(+?(243()+(&-%/7$+7+9'4+-7)+)'&,-7)4)+#48/78+'8+9'1+,(3D8+ I%8#4$=7,4J+)%8+27$-4+'8+,'4$?(+,(8,$4#(+48+-7+,-7)4+?72$4M+Métodos abstractos en Java
• Se declaran utilizando el modificador abstract tras el de visibilidad y no se les da cuerpo, sólo un símbolo de punto y coma.
• Sólo los métodos de instancia pueden ser abstractos. • Sólo los métodos públicos y protegidos pueden ser
abstractos.
• El constructor no puede ser abstracto
public abstract void mueve(double dx, double dy); public abstract void dibuja();
Clases abstractas en Java
• Una clase que tenga uno o más métodos abstractos estáincompleta por lo que debe indicarse que es abstracta
• Para indicar que es abstracta se usa el modificador abstract tras el de visibilidad en la definición de la clase
• Una clase abstracta puede tener además métodos concretos (con cuerpo)
public abstract class Figura { private Color color;
private int grosor; public Figura() { this(Color.BLACK, 1); }
public Figura(Color color, int grosor) { this.color = color;
this.grosor = grosor; }
// Métodos get y set de color y grosor
public abstract void mueve(double dx, double dy); public abstract void dibuja();
Herencia y clases abstractas
• Las subclases de clases abstractas heredan los métodos abstractos del padre y deben implementarlos (darles cuerpo). • De no hacerlo, o de hacerlo parcialmente, se deben declarar
también como abstractas.
public class Circulo extends Figura { private Punto centro;
private double radio;
public Circulo(Punto centro, double radio) { super();
this.centro = new Punto(centro); // constructor de copia this.radio = radio;
}
// Métodos get y set de centro y radio public void mueve(double dx, double dy) { centro.mueve(dx,dy);
}
public void dibuja() { /* Dibujo un circulo */ } }
Uso de clases abstractas
• Podemos declarar variables, miembros y parámetros del tipo que definen las clases abstractas
• Podemos heredar de ellas para definir nuevas clases
• Pero NO podemos crear objetos del tipo que definen porque son clases INCOMPLETAS
public class Test {
public static void anima(Figura f) { for ( int i = 0 ; i < 10 ; i++ ) { f.dibuja();
f.mueve(10,0); }
}
public static void main(String args[]) { Figura f = new Circulo(new Punto(5,5), 3);
Cuadrado c = new Cuadrado(new Punto(0,0), new Punto(10,10)); anima(f);
anima(c);
Figura amorfa = new Figura(); }
}
Clases abstractas vs Interfaces
• Una clase abstracta sin ningún miembro y sin ningún método concreto es equivalente a un interface (mejor definirla como interface).
• Las clases abstractas hay que usarlas cuando el interface se queda corto (no podemos ponerle miembros ni métodos concretos).
• Tanto las clases abstractas como los interfaces definen un
“interface público” y un tipo de dato. Podemos declarar variables y parámetros de este tipo pero no crear objetos del mismo.
• Heredar sirve para conseguir que un objeto también “sea” del tipo del padre.
• Implementar un interface sirve para conseguir que un objeto “sea capaz de hacer” lo indicado por el interface.
Clases abstractas vs Interfaces
!"#$%&'($)* +,')$)*'-)#%'(#')* +.")#'"#$)* /!* /!* 01$2-%.)* 34* /!* 05#.6.)*(."(%$#.)* 34* /!* 05#.6.)*'-)#%'(#.)* /!* /!* 05#.6.)*$)#78(.)9* 34* /!* :$;"$*<"*8=.* /!* /!* >).* ?$@$A'*,.*B<$*$)* ('='C*6$*D'($%* ?$@$A'*,.*B<$*$)*Herencia e interfaces
• La herencia y la implementación de interfaces son compatibles. • Es posible heredar e implementar uno o varios interfaces
simultáneamente.
• Implementar un interface añade a una clase un conjunto de métodos abstractos que podemos definir o, de no hacerlo, convertir la clase en abstracta.
• Las subclases heredan todos los métodos de su clase padre incluidos los abstractos, por lo tanto, las subclases
implementan los mismos interfaces que sus ancestros.
• Implementar un interface o heredar de una clase abstracta nos obliga a cumplir un interface dando cuerpo a los métodos parcialmente definidos (o a convertir la clase en abstracta).
public interface Volador { void vuela(); } public interface Nadador { void nada(); } public interface Andador { void anda(); } public
class Pato extends Animal implements Volador,
Nadador, Andador
{
public Pato(String apellido) { super(“Pato” + apellido); }
public void vuela() {...}; public void nada() {...}; public void anda() {...}; }
public class Animal { private String nombre; public Animal(String nombre) { this.nombre = nombre } public String getNombre() { return nombre;
} }
• Una clase que herede de otra está heredando a su vez todos los interfaces que tuviera el padre.
public class Donald extends Pato {
public Donald() { super(“ Donald”); }
public String saluda () { return “cuajola”; }
}
public class Test {
public static void test() { Donald d = new Donald(); d.vuela(); d.nada(); d.anda(); Volador v = (Volador)d; v.vuela(); S.O.println(d.getNombre() + “: ” + d.saluda()); } }
Herencia e Interfaces
Herencia de Interfaces
• Se puede crear un interface a partir de otro por herencia • Basta con añadir extends y el nombre de los interfaces de losque se quiera heredar separados por comas
• A diferencia de las clases, se puede heredar de varios y el resultado es un nuevo interface compuesto por todos los métodos y constantes de ambos
Herencia de Interfaces
public interface Monstruoso { void asusta(); } publicinterface Vampirico extends Monstruoso {
void muerde(); }
public class Frankenstein implements Monstruoso { public void asusta() {
S.O.println(“Ven a contar florecitas”); }
}
public class Nosferatu implements Vampirico { public void asusta() {
S.O.println(“Enseñame el cuello”); }
public void muerde() {S.O.println(“ñam”);} }
Ejercicios
• Escribe la clase Musico con el método público interpreta (Melodia m, Instrumento i)
• Los músicos pueden tocar con diversos instrumentos (Trompeta, Piano)
• Los instrumentos son capaces de reproducir Notas musicales (cada uno a su manera)
• Para hacer un programa que juegue al ajedrez escribe la clase Ficha y sus derivadas de modo que sean capaces de determinar, a partir de la posición en la que se encuentren, todas las posiciones válidas