Trabajando con clases abstractas en JDeveloper 11g
Una clase es abstracta si al menos contiene un método declarado como abstracto usando el modificador abstract. Los métodos declarados como abstractos no implementan código y difieren la implementación del código a otra clase.Tabla de contenido
- ¿Qué son las clases abstractas en Java?
- Formas de diferir código Java
- Características de una clase abstracta.
- ¿Cuándo utilizar clases abstractas?
- Para saber más sobre los diagramas Java de Oracle visitar los siguientes sitios
- Para saber más sobre los diagramas UML.org visitar los siguientes sitios
- ¿Qué son las interfaces en Java?
- Relación entre una clase y una interfaz
- En Java hay tres tipos de relaciones:
- Heredar clases abstractas
- Tres situaciones de heredar clases abstractas
- Situación 1 - Se crearán instancias de la clase padre, superclase o abstracta
- Situación 2 - Se crearán instancias de la clase padre, superclase o abstracta pero usando los constructores de los hijos, subclases
- Situación 3 - Se crearán instancias de los hijos, subclases
Formas de diferir código Java
Hay dos formas de diferir código de una clase abstracta a otra clase:- Forma 1 - Cuando se crea una referencia de objeto de una clase abstracta y se instancia usando el operador new
- Forma 2 - Cuando se hereda una clase abstracta usando la palabra clave extends
Características de una clase abstracta.
- Si una clase abstracta es instanciada el compilador dará un error de sintaxis, el compilador dejará de dar un error cuando la clase que crea la instancia de la clase abstracta sobrescriba, override, los métodos abstractos e implemente el código faltante que no se definió durante el proceso de abstracción cuando se creó la clase abstracta.
- Si al menos un método de la clase es declarado abstract, es obligación que la clase completa sea definida como abstract, la clase puede tener el resto de los métodos no abstractos.
- Los métodos abstract no llevan cuerpo, no llevan las llaves { … }, simplemente termina con un punto y coma “;”
- Si una clase hereda a una clase abstracta usando la palabra clave extends el compilador dará un error de sintaxis, el compilador dejará de dar un error cuando la clase que hereda sobrescriba los métodos abstractos e implemente el código faltante que no se definió durante el proceso de abstracción cuando se creó la clase abstracta.
- Existe el caso extremo de declarar todos los atributos de una clase con el modificador estático, static, y todos los métodos como abstractos, abstract. En estas clases no hace falta instanciar un objeto de la clase padre o heredada ya que las clases hijas o herederas se harán cargo de implementar todos los métodos abstractos, es suficiente con crear objetos de las clases herederas para acceder a los métodos. El compilador no da error si se crea un objeto de una clase totalmente abstracta, el compilador se queda a la espera que en el futuro se implemente un método no abstracto para la clase padre o que se utilice un constructor de alguno de los hijos al crear una instancia del padre. El compilador se queda esperando que se utilice el poder del polimorfismo.
¿Cuándo utilizar clases abstractas?
- Cuando se necesita implementar distintos comportamientos para un mismo método
- En la fase de análisis, es cuando se intenta definir qué es el problema y se deja la implementación, programación, para más tarde
- En la fase de diseño, es cuando se intenta definir cómo es el problema y se deja la implementación, programación, para más tarde
- Cuando se desea usar el mecanismo del polimorfismo, es cuando un objeto cambia de tipo y de comportamiento.
- Cuando el objetivo es producir código reutilizable por medio del polimorfismo
- Cuando el objetivo es crear componentes reutilizables
- Cuando se quiere relacionar dos clases y establecer un medio de comunicación entre las clases
Forma 1 - Cómo diferir código de una clase abstracta a otra clase usando el operador new
package client1;
public class Main {
public Main() {
super();
}
private static Figura figura = null;
public static void main(String[] args) {
figura = new Figura(1){ //creando un tipo Figura
@Override
public float area() {
return resultado;
}
};
System.out.print("Área Figura: " + figura.tipoFigura + "=");
System.out.println(figura.area()); //línea polimórfica del tipo Figura
figura = new Figura(3, 4){ //creando un tipo Figura
@Override
public float area() {
return resultado;
}
};
System.out.print("Área Figura: " + figura.tipoFigura + "=");
System.out.println(figura.area()); //línea polimórfica del tipo Figura
}
}
package client1;
public abstract class Figura {
public Figura() {
super();
}
public Figura(int r) {
super();
this.r = r;
resultado = (float)3.14 * (r * r);
tipoFigura = "Círculo";
}
public Figura(int a, int b) {
super();
this.a = a;
this.b = b;
resultado = a * b;
tipoFigura = "Cuadrilátero";
}
public float a=3, b=4, r=1, resultado=0;
public String tipoFigura="";
public abstract float area();
}
Para saber más sobre los diagramas Java de Oracle visitar los siguientes sitios
- https://docs.oracle.com/cd/E37975_01/user.111240/e17455/prog_java.htm#OJDUG1490
- https://docs.oracle.com/cd/E37975_01/user.111240/e17455/creating_diagrams.htm#OJDUG4588
- https://docs.oracle.com/cd/E37975_01/user.111240/e17455/creating_diagrams.htm#OJDUG4596
- https://docs.oracle.com/cd/E37975_01/user.111240/e17455/creating_diagrams.htm#OJDUG4608
Para saber más sobre los diagramas UML.org visitar los siguientes sitios
- http://www.uml.org/
- http://www.uml-diagrams.org/
- http://www.omg.org/
- http://www.omg.org/spec/UML/
- https://es.wikipedia.org/wiki/Lenguaje_unificado_de_modelado
¿Qué son las interfaces en Java?
Las interfaces son un tipo de clases Java donde todos sus métodos son abstractos. Una clase declarada como interfaz usando la palabra clave interface es una clase abstracta que tiene todos sus métodos declarados como abstractos. Un método abstracto no tiene código implementado y difiere a que otra clase implemente el código no implementado.Java es un lenguaje que no permite la herencia múltiple, a acepción de las clases que son declaradas como interfaz. Una clase puede heredar muchas clases que sean declaradas como interfaz. Una clase puede heredar una o más clases del tipo interfaz y la clase que hereda está obligada a implementar el código de la clase heredada.
- Las clases abstractas del tipo interfaz no se pueden instanciar.
- Las clases abstractas del tipo interfaz pueden tener declaraciones de valores constantes, static, final
- Las clases abstractas del tipo interfaz pueden tener definiciones de métodos abstractos, abstract
- Para acceder a un valor constante de una interfaz se utiliza su nombre y el operador punto o por medio de la clase que la herede
Las interfaces son usadas para definir partes de un producto software, las interfaces son definidas en la fase de análisis del desarrollo de un producto software. Durante la fase de análisis muchos casos de usos se agrupan para definir clases e interfaces. Las clases y las interfaces son consecuencia directa de la agrupación de los datos, casos de usos. Los métodos declarados en las clases y las interfaces serán los encargados de operar con los datos y producir la salida deseada según el problema a resolver.
Relación entre una clase y una interfaz
La relación entre una interfaz y una clase es una relación que indica que la interfaz es parte de la clase.En Java hay tres tipos de relaciones:
- Relación “Tiene”, es cuando se usa el operador new
- Relación “Es del mismo tipo”, es cuando se usa la palabra clave extends
- Relación “Es parte”, es cuando se usa la palabra clave implements
En un ambiente de programación Java las palabras agregación y composición se deben entender como actividades y tareas del proceso de abstracción en el desarrollo de un producto software.
Los conceptos de abstracción, agregación y composición no son relaciones en Java, Java tiene tres tipos de relaciones y sus correspondientes palabras claves.
Hay grandes diferencias entre los diagramas UML.org y los diagramas UML Java Oracle, definen distintos estereotipos.
Oracle toma el modelo de referencia UML.org y hereda muchos de los estereotipos definidos por el UML.org y los redefine para crear los diagramas de clases Java específicos para el desarrollo de productos software con el lenguaje Java
El diagrama se lee de la siguiente forma:
La clase VentanaPrincipal y la clase Reloj implementan una parte en común, la parte en común es el método notificarHora(…)La clase VentanaPrincipal es la responsable de crear una instancia de la clase Reloj y de implementar el código faltante.
La clase Reloj notificará la hora a la clase VentanaPrincipal por medio del código implementado por la clase ventanaPrincipal
package client;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class VentanaPrincipal extends JFrame implements MiNotificador {
private JLabel jLabel1 = new JLabel();
public VentanaPrincipal() {
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}
private Reloj reloj = null;
private void jbInit() throws Exception {
this.getContentPane().setLayout( null );
this.setSize( new Dimension(400, 300) );
jLabel1.setText("jLabel1");
jLabel1.setBounds(new Rectangle(55, 50, 270, 30));
this.getContentPane().add(jLabel1, null);
reloj = new Reloj(){
@Override
public void notificarHora(Date date) {
miNotificarHora(date);
}
};
reloj.start();
}
public void miNotificarHora(Date date) {
notificarHora(date);
}
@Override
public void notificarHora(Date hora) {
this.jLabel1.setText(hora.toString());
}
public static void main(String[] args) {
VentanaPrincipal vp = new VentanaPrincipal();
vp.setDefaultCloseOperation(vp.EXIT_ON_CLOSE);
vp.setLocationRelativeTo(null);
vp.setVisible(true);
}
}
package client;
import java.util.Date;
public abstract class Reloj extends Thread implements MiNotificador {
public Reloj() {
super();
}
public void run() {
super.run();
Date date = null;
do {
date = new Date();
notificarHora(date);
try {
this.sleep(500);
} catch (InterruptedException e) {
}
} while (true);
}
public abstract void notificarHora(Date date);
}
package client;
import java.util.Date;
public interface MiNotificador {
public void notificarHora(Date hora);
}
Heredar clases abstractas
Forma 2 - Cuando se hereda una clase abstracta usando la palabra clave extends
Tres situaciones de heredar clases abstractas
Existen tres situaciones cuando se heredan clases abstractas al momento de crear instancias con new
- Se crearán instancias de la clase padre, superclase o abstracta
- Se crearán instancias de la clase padre, superclase o abstracta pero usando los constructores de los hijos, subclases
- Se crearán instancias de los hijos, subclases
No se puede crear instancias de las clases abstractas, el motivo es que no tienen código implementado. Pero si la clase que intenta crear una instancia de la clase abstracta se hace cargo de implementar el código faltante si se puede crear una instancia de una clase declarada como abstracta.
De la única clase abstracta que no se puede crear instancias es de la clase tipo interfaz. Es obligación que las interfaces sean heredadas para que otra clase se haga cargo del código faltante.
Situación 1 - Se crearán instancias de la clase padre, superclase o abstracta
La clase Main es la responsable de sobrescribir el método abstracto definido por la clase Figura
package client1;
public class Main {
public Main() {
super();
}
private static Figura figura = null;
public static void main(String[] args) {
figura = new Figura(1){ //creando un tipo Figura
@Override
public float area() {
return resultado;
}
};
System.out.print("Área Figura: " + figura.tipoFigura + "=");
System.out.println(figura.area()); //línea polimórfica del tipo Figura
figura = new Figura(3, 4){ //creando un tipo Figura
@Override
public float area() {
return resultado;
}
};
System.out.print("Área Figura: " + figura.tipoFigura + "=");
System.out.println(figura.area()); //línea polimórfica del tipo Figura
}
}
package client1;
public abstract class Figura {
public Figura() {
super();
}
public Figura(int r) {
super();
this.r = r;
resultado = (float)3.14 * (r * r);
tipoFigura = "Círculo";
}
public Figura(int a, int b) {
super();
this.a = a;
this.b = b;
resultado = a * b;
tipoFigura = "Cuadrilátero";
}
public float a=3, b=4, r=1, resultado=0;
public String tipoFigura="";
public abstract float area();
}
Situación 2 - Se crearán instancias de la clase padre, superclase o abstracta pero usando los constructores de los hijos, subclases
package client2;
public class Main {
public Main() {
super();
}
private static Figura figura = null;
public static void main(String[] args) {
figura = new Circulo(1); //Creando un tipo Círculo
System.out.println(figura.area()); //línea polimórfica del tipo Círculo
figura = new Cuadrilatero(2, 4); //Creando un tipo Cuadrilátero
System.out.println(figura.area()); //línea polimórfica del tipo Cuadrilátero
}
}
package client2;
public abstract class Figura {
public Figura() {
super();
}
public float a=3, b=4, r=1, resultado=0;
public String tipoFigura="";
public abstract float area();
}
package client2;
public class Circulo extends Figura{
public Circulo(float r) {
super();
this.r = r;
this.tipoFigura = "Círculo";
}
@Override
public float area() {
resultado = (float)3.14 * (r * r);
return resultado;
}
}
package client2;
public class Cuadrilatero extends Figura{
public Cuadrilatero(int a, int b) {
super();
this.a = a;
this.b = b;
this.tipoFigura = "Cuadrilátero";
}
@Override
public float area() {
resultado = a * b;
return resultado;
}
}
Situación 3 - Se crearán instancias de los hijos, subclases
package client3;
public class Main {
public Main() {
super();
}
private static Circulo circulo = null;
private static Cuadrilatero cuadrilatero = null;
public static void main(String[] args) {
circulo = new Circulo(1);
System.out.println("Área círculo = " + circulo.area());
cuadrilatero = new Cuadrilatero(3,4);
System.out.println("Área cuadrilátero = " + cuadrilatero.area());
}
}
package client3;
public abstract class Figura {
public Figura() {
super();
}
public float a=3, b=4, r=1, resultado=0;
public String tipoFigura="";
public abstract float area();
}
package client3;
public class Cuadrilatero extends Figura {
public Cuadrilatero(int a, int b) {
super();
this.a = a;
this.b = b;
tipoFigura = "Cuadrilátero";
}
@Override
public float area() {
resultado = a * b;
return resultado;
}
}
package client3;
public class Circulo extends Figura {
public Circulo(float r) {
super();
this.r = r;
tipoFigura = "Círculo";
}
@Override
public float area() {
resultado = (float)3.14 * (r * r);
return resultado;
}
}
No hay comentarios.:
Publicar un comentario
Realiza un comentario, debes autenticar una cuenta Gmail, Yahoo, OpenID, etc.