Hablar de Herencia y Polimorfismo es desgastante, debido
a que hay muchas cosas que explicar, así que para darme tiempo de terminar el
post "Herencia y Polimorfismo, parte II" hablare acerca de clases
abstractas e interfaces, que son parte importante de la Herencia y el
Polimorfismo y son más sencillos de explicar.
Clases Abstractas.
Una clase es definida como abstracta cuando uno o más de sus
métodos son declarados como abstractos, es decir no tienen ninguna
implementación y la primera clase concreta que herede de esta debe implementar
todos sus métodos abstractos. Cabe mencionar que una clase abstracta no puede
ser instanciada, sino que su propósito es ser extendida, quizás sea difícil imaginar
para que puede servir esto, pero intentaremos descubrirlo con un ejemplo.
Pensemos en los celulares, todos los celulares tienen
funciones básicas compartidas, como el llamar, contestar, recibir mensajes y enviar
mensajes, así que crearemos una clase abstracta con estas funciones.
package AbstractClassAndInterface; public abstract class Cellphone { private String myNumber; public Cellphone(String myNumber) { this.myNumber = myNumber; } public abstract void on(); public abstract void off(); public void call(String number) { System.out.println("Call to the number " + number); } public void response(String number) { System.out.println("Response to number " + number); } public abstract void sendMenssage(String message, String number); public abstract void readMessage(String message); public String getNumber() { return this.myNumber; } }
Hemos creado una clase abstracta, que tiene el
comportamiento de los celulares estándar todas las clases que hereden de ella,
heredaran los métodos call, response y getNumber que ya han sido implementados,
y si la clase es concreta deberá implementar los métodos, on, off, sendMessage,
readMessage. Podemos notar que la forma en que declaramos la clase Cellphone
incluye la palabra abstract que es la que le indica al compilador que la clase
es abstracta, al igual los métodos abstractos ocupan la palabra abstract y
terminan en punto y coma, sin tener un cuerpo de método.
Si la que extiende la clase abstracta es otra clase abstracta,
entonces puede delegar la implementación de los métodos abstractos a la primera
clase concreta que herede de ella, y agregar sus propios métodos tanto
abstractos como no abstractos.
package AbstractClassAndInterface; public abstract class Smartphone extends Cellphone { public Smartphone(String number) { super(number); } public void on() { System.out.println("Turn on a smartphone"); } public void off() { System.out.println("Turn off a smartphone"); } public abstract void surfWeb(String URL); }
Hemos creado la clase abstracta Smartphone que extiende
de la clase abstracta Cellphone, decidimos aquí implementar los métodos on y
off, que como se puede observar ahora tienen un cuerpo de método, han eliminado
la palabra abstract y el punto coma, además hemos agregado un método abstracto
más llamado surfWeb, ahora pasemos a las clases concretas haremos un Android y
un Blackberry.
package AbstractClassAndInterface; public class Android extends Smartphone { public Android(String number) { super(number); } public void sendMenssage(String message, String number) { System.out.println("Android Sending a message to number " + number + "\r\n" + message); } public void readMessage(String message) { System.out.println("Android Reading a message: " + message); } public void surfWeb(String URL) { System.out.println("Android Surfing on the web: " + URL); } }
package AbstractClassAndInterface; public class Blackberry extends Smartphone { public Blackberry(String number) { super(number); } public void sendMenssage(String message, String number) { System.out.println("Blackberry Sending a message to number " + number + "\r\n" + message); } public void readMessage(String message) { System.out.println("Blackberry Reading a message: " + message); } public void surfWeb(String URL) { System.out.println("Blackberry Surfing on the web: " + URL); } }
Hemos creado nuestros smartphone's, los cuales
implementan finalmente todos los métodos abstractos tanto los de la clase
abstracta Cellphone como los de Smartphone, es tiempo de probarlo.
package AbstractClassAndInterface; public class SmartphoneTestDrive { public static void main(String[] args) { SmartphoneTestDrive test = new SmartphoneTestDrive(); test.createCellphones(); } public void createCellphones() { Smartphone android = new Android("2291 23 45 67"); Smartphone blackberry = new Blackberry("2292 34 56 78"); System.out.println("\r\n----Android: " + android.getNumber()); useCellphone(android); System.out.println("\r\n----Blackberry: " + blackberry.getNumber()); useCellphone(blackberry); } private void useCellphone(Smartphone smartphone) { String cpNumber = "2299 01 23 45"; String cpNumber2 = "2290 12 34 56"; smartphone.on(); smartphone.call(cpNumber); smartphone.response(cpNumber2); smartphone.sendMenssage("Un mensaje de prueba", cpNumber); smartphone.readMessage("Te envie un mensaje lo recibiste?"); smartphone.surfWeb("www.google.com"); } }
Funciona, ahora podemos utilizar cualquier smartphone que
herede de la clase abstracta, y ejecutarlo con el método useCellphone, si te
preguntas por que funciona tendrás que esperar hasta la segunda parte de herencia
y polimorfismo, ya que es parte del polimorfismo.
Interfaces.
Una interfaz es básicamente un contrato, la clase que
implementa a una interfaz debe de implementar cada uno de los métodos que en
ella se definen, una interfaz no contiene variables solo métodos y constantes (al
menos en Java), las constantes siempre deben de ser declaradas como "public
static final" por el momento no las ocuparemos, vayamos directo al código.
Queremos mandar un mensaje vía Internet de un smartphone
a otro, podemos generar una interfaz genérica que envié un mensaje, pero
tenemos un problema, Blackberry ocupa BBM(Blackberry Messenger) y Android ocupa
WA(Whats App), podríamos crear dos clases abstractas distintas una para Android
y otra para Blackberry, pero eso arruinaría nuestro código de prueba anterior,
podríamos implementarlo directamente en las clases pero pueden existir tanto
Android's como Blackberry's que no soporten esos servicios, es en este momento
cuando se vuelve necesario hacer uso de las interfaces.
package AbstractClassAndInterface; public class Android extends Smartphone implements WhatsApp { public Android(String number) { super(number); } public void sendMenssage(String message, String number) { System.out.println("Android Sending a message to number " + number + "\r\n" + message); } public void readMessage(String message) { System.out.println("Android Reading a message: " + message); } public void surfWeb(String URL) { System.out.println("Android Surfing on the web: " + URL); } public void sendWhatsAppMessage(String message, String user) { System.out.println("Android Sending WhatsApp message to user " + user + "\r\n" + message); } public void receiveWhatsAppMessage(String Message) { System.out.println("Android Reading WhatsApp message: " + message); } }
package AbstractClassAndInterface; public class Blackberry extends Smartphone implements BlackberryMessenger, WhatsApp { public Blackberry(String number) { super(number); } public void sendMenssage(String message, String number) { System.out.println("Blackberry Sending a message to number " + number + "\r\n" + message); } public void readMessage(String message) { System.out.println("Blackberry Reading a message: " + message); } public void surfWeb(String URL) { System.out.println("Blackberry Surfing on the web: " + URL); } public void sendBlackberryMessenger(String message, String user) { System.out.println("Blackberry Sending BlackberyMessenger to user " + user + "\r\n" + message); } public void receiveBlackberryMessenger(String message) { System.out.println("Blackberry Reading BlackberyMessenger message: " + message); } public void sendWhatsAppMessage(String message, String user) { System.out.println("Blackberry Sending WhatsApp message to user " + user + "\r\n" + message); } public void receiveWhatsAppMessage(String Message) { System.out.println("Blackberry Reading WhatsApp message: " + message); } }
Hemos creado nuestras interfaces, cabe mencionar que una
interfaz puede implementar de otra, es decir podríamos hacer lo siguiente.
public BlackberryMessenger extends WhatsApp
Es decir quién implemente BlackberryMessenger también
debería implementar WhatsApp, pero vayamos a la acción modifiquemos Android y
Blackberry para enviar mensajes.
Ahora que hemos implementado las interfaces es hora de
hacer una prueba, cabe mencionar que por definición todos los métodos en las
interfaces son declarados como "public".
package AbstractClassAndInterface; public class SmartphoneTestDrive { public static void main(String[] args) { SmartphoneTestDrive test = new SmartphoneTestDrive(); test.createCellphones(); } public void createCellphones() { Smartphone android = new Android("2291 23 45 67"); Smartphone blackberry = new Blackberry("2292 34 56 78"); System.out.println("\r\n----Android: " + android.getNumber()); useCellphone(android); System.out.println("\r\n----Blackberry: " + blackberry.getNumber()); useCellphone(blackberry); } private void useCellphone(Smartphone smartphone) { String cpNumber = "2299 01 23 45"; String cpNumber2 = "2290 12 34 56"; smartphone.on(); smartphone.call(cpNumber); smartphone.response(cpNumber2); smartphone.sendMenssage("Un mensaje de prueba", cpNumber); smartphone.readMessage("Te envie un mensaje lo recibiste?"); smartphone.surfWeb("www.google.com"); sendWebMessage("Hello im sending a web message", "some user", smartphone); receiveMessage("Hi, i received your message, how are you?", smartphone); } private void sendWebMessage(String message, String user, Smartphone smartphone) { if(smartphone instanceof WhatsApp) ((WhatsApp)smartphone).sendWhatsAppMessage(message, user); if(smartphone instanceof BlackberryMessenger) ((BlackberryMessenger)smartphone).sendBlackberryMessenger(message, user); } private void receiveMessage(String message, Smartphone smartphone) { if(smartphone instanceof WhatsApp) ((WhatsApp)smartphone).receiveWhatsAppMessage(message); if(smartphone instanceof BlackberryMessenger) ((BlackberryMessenger)smartphone).receiveBlackberryMessenger(message); } }
Y básicamente es todo, ahora puedes agregar más
funcionalidades si así lo deseas.
Happy Coding...
No hay comentarios:
Publicar un comentario