Polimorfismo
Recuerde la definicion de Polimorfismo de P.O.O.
Polimorfismo es la utilización de interfaces idénticas con diferentes implementaciones.
Recuerde todo lo que hay en una interfaz es publico y que la palabra
implementar en este curso significara escribir codigo.
Hablando de un modo muy general el Polimorfismo tiene que ver con tratar
objetos de tipo distinto como si fueran del mismo tipo.
Mas en concreto el polimorfismo se da cuando hay un supertipo y se trata a
las instancias de sus subtipos como si fueran instancias de dicho supertipo.
Recuerde la definicion de clase abstracta de P.O.O.
Una clase abstracta es una clase que no tiene instancias directas.
Recuerde en Java una clase abstracta debe tener al menos un metodo abstracto.
Recuerde un metodo abstracto es un metodo que no tiene implementacion es decir
solo se declara.
Ejemplo de polimorfismo en java
Instrumento Superclase
|
____________________
| | |
Flauta Guitarra Piano Subclases
public abstract class Instrumento {
public abstract void tocaFa();//declaracion del metodo tocaFa 349 Hz.
public abstract void tocaRe();//declaracion del metodo tocaRe 294 Hz.
}
Dado que Instrumento es una clase abstracta no se pueden crear instancias de
Instrumento es decir new Instrumento() produce un error
En este caso la interfaz (de la que habla la definicion de polimorfismo) es
tocaFa() y tocaRe()
tocaFa() y tocaRe() son metodos abstractos porque cada subclase (Flauta,
Guitarra y Piano) los debe implementar de modo diferente dado que cada
instrumento musical produce los sonidos de las notas musicales de diferente forma.
Guitarra es un instrumento de cuerda compuesto de una caja de resonancia, un
mástil sobre el que va adosado el trastero y seis cuerdas.
Para tocar la guitarra se apoyan los dedos sobre las cuerdas, oprimiéndolas contra el trastero entre los trastes justo después del que delimitará el segmento de cuerda que vibra, de manera que quede libre la longitud correspondiente a la nota musical deseada.
Flauta es un instrumento de viento compuesto de un tubo con una serie de hoyos y una boquilla. El sonido se produce soplando por un extremo de la flauta.
Abriendo o cerrando los hoyos del tubo de la flauta se cambia la longitud del aire vibrante dentro del tubo.
Recapitulando el sonido de la nota en el caso de la Guitarra lo produce la vibracion de una cuerda y en el caso de la flauta el sonido de la nota lo produce la vibracion de una columna de aire.
______________________________________________________________________________
Recuerde en java todos los metodos abstractos de una clase abstracta deben ser implementados por una subclase no abstracta
Por eso cada subclase de Instrumento implementa todos los metodos abstractos
de la superclase. En este caso Flauta tiene que implementar los metodos
tocaFa() y tocaRe()
public class Flauta extends Instrumento {
public void tocaFa(){//implementacion del metodo tocaFa
System.out.println("Flauta Toca Fa");
}
public void tocaRe(){//implementacion del metodo tocaRe
System.out.println("Flauta Toca Re");
}
}
______________________________________________________________________________
public class Guitarra extends Instrumento {
public void tocaFa(){//superposicion del metodo tocaFa de la superclase
System.out.println("Guitarra Toca Fa");
}
public void tocaRe(){//superposicion del metodo tocaRe de la superclase
System.out.println("Guitarra Toca Re");
}
}
______________________________________________
public class Piano extends Instrumento {
public void tocaFa(){
System.out.println("Piano Toca Fa");//la ejecucion de la nota
}
public void tocaRe(){
System.out.println("Piano Toca Re");//solo se "platica"
}
}
______________________________________________________________________________
La clase Orquesta sirve para probar las clases Flauta, Guitarra y Piano
public class Orquesta {
Instrumento f, g, p;//Estas variables son del tipo de la superclase
public Orquesta(){
f = new Flauta();// se crea un objeto del tipo de una subclase
g = new Guitarra();
p = new Piano();
}
public void concierto(){
f.tocaFa();// se llama al metodo tocaFa de la subclase Flauta
f.tocaRe();
g.tocaFa();// se llama al metodo tocaFa de la subclase Guitarra
g.tocaRe();
p.tocaFa();// se llama al metodo tocaFa de la subclase Piano
p.tocaRe();
}
public static void main(String s[]){
Orquesta o= new Orquesta();
o.concierto();
}
}
_____________________________________________________________________________
Otra version de la clase orquesta donde queda mas evidente el polimorfismo.
Recuerde que una de las finalidades de la P.O.O es el manejo del cambio.
En particular el cambio al que es resistente este software es que si se agrega
una nueva subclase (por ejemplo Violin) el codigo del metodo concierto no tiene que ser modificado (haga la prueba).
import java.util.*;
public class Orquesta1 {
ArrayList<Instrumento> al;
public Orquesta1(){
al= new ArrayList<Instrumento>();
al.add(new Flauta());//upcasting Flauta -> Instrumento
al.add(new Guitarra());//upcasting Guitarra -> Instrumento
al.add(new Piano());//upcasting Piano -> Instrumento
}
public void concierto(){//el codigo del metodo concierto es polimorfico
for(int i=0; i< al.size(); i++){
//en esta parte se trata a Flauta, Guitarra y Piano como si fueran de tipo
//Instrumento es decir podemos llamar a los metodos tocaFa() y tocaRe()
//sin problema porque todas las subclases los implementan
al.get(i).tocaFa(); //se llama a metodos en la interfaz o dicho de otro
al.get(i).tocaRe(); //modo a los metodos abstractos de la superclase
}
}
public static void main(String s[]){
Orquesta1 o= new Orquesta1();
o.concierto();
}
}
_____________________________________________________________________________
public interface Tocable {//todo lo que hay dentro de una interfaz es publico
void tocaFa();//un metodo abstracto o dicho de
void tocaRe();//otro modo declaracion de un metodo
}
Recuerde antes de java8 las interfaces solo contenian declaraciones
_____________________________________________________________________________
Recuerde en java todos los metodos abstractos de una interfaz deben ser implementados por la clase que "diga yo los implemento".
Por ejemplo la clase Flauta "dice" (declara) que implementa todos los
metodos abstractos de la interfaz Tocable
public class Flauta implements Tocable {
//La clase Flauta implementa todos los metodos declarados en la interfaz
//Tocable
public void tocaFa(){
System.out.println("Flauta Toca Fa");
}
public void tocaRe(){
System.out.println("Flauta Toca Re");
}
}
_____________________________________________________________________________
public class Guitarra implements Tocable {
public void tocaFa(){
System.out.println("Guitarra Toca Fa");
}
public void tocaRe(){
System.out.println("Guitarra Toca Re");
}
}
_____________________________________________________________________________
public class Piano implements Tocable {
public void tocaFa(){
System.out.println("Piano Toca Fa");
}
public void tocaRe(){
System.out.println("Piano Toca Re");
}
}
______________________________________________________________________________
public class Orquesta {
Tocable f, g, p;//el tipo de f, g, y p es una interfaz
public Orquesta(){
f = new Flauta();//Flauta implementa la interfaz Tocable
g = new Guitarra();//Guitarra implementa la interfaz Tocable
p = new Piano();//Piano implementa la interfaz Tocable
}
public void concierto(){
f.tocaFa();
f.tocaRe();
g.tocaFa();
g.tocaRe();
p.tocaFa();
//Hablando de manera particular p es una instancia de la clase Piano
p.tocaRe();
//Hablando de forma general p es un objeto de una clase que implementa
//la interfaz Tocable por tanto es seguro llamar al metodo tocaRe
}
public static void main(String s[]){
Orquesta o = new Orquesta();
o.concierto();
}
}
______________________________________________________________________________
import java.util.*;
public class Orquesta1 {
ArrayList<Tocable> al;
public Orquesta1(){
al = new ArrayList<Tocable>();
al.add(new Flauta());
al.add(new Guitarra());
al.add(new Piano());
}
public void concierto(){
for(int i=0; i< al.size(); i++){
al.get(i).tocaFa();//Aqui hay polimorfismo (diga porque?)
al.get(i).tocaRe();
}
}
public static void main(String s[]){
Orquesta1 o = new Orquesta1();
o.concierto();
}
}
______________________________________________________________________________
upcasting
forzar el tipo de un objeto al tipo de una de sus superclases.
downcasting
forzar el tipo de un objeto al tipo de una de sus subclases.
Ejercicio 1
Escriba el codigo de una superclase Mascota que tenga un metodo hablar() y que tenga como subclases Gato, Perro y Canario las cuales superponen el metodo hablar().
Para escribir el codigo de del metodo hablar() tenga en cuenta que los gatos maullan, los perros ladran y los canarios pian.
Escriba el codigo de la clase que sirve para probar las clases Gato, Perro y Canario.
Ejercicio 2
Escriba el codigo de una superclase Animal que tenga un metodo mover() y que tenga como subclases Delfin, Lobo y Aguila las cuales superponen el metodo mover().
Para escribir el codigo de del metodo mover() tenga en cuenta que los Delfines
nadan, los Lobos corren y las Aguilas vuelan. O dicho de otro modo se nada en el agua usando aletas, se corre en la tierra usando patas y se vuela en el cielo
usando alas.
Escriba el codigo de la clase que sirve para probar las clases Delfin, Lobo y Aguila.
Haga la version con interfaces de los ejercicios 1 y 2