INTRODUCCION
Los métodos estáticos
se caracterizan porque son métodos que se consideran propios de la clase y por
lo tanto no pueden ser referenciados por un objeto específico de la clase. Esta
característica hace que para referenciar un método estático se utiliza el nombre
de la clase. Por ejemplo, si el método sumar() es un método estático de la clase Operaciones; entonces el método sumar() se referenciaría en una aplicación como: Operaciones.sumar(). Cuando la clase donde se encuentra definido el método estático es la
clase ejecutable de la aplicación no es necesario anteponerle el nombre de la
clase cuando se llame desde el método estático main() de la clase ejecutable.
Generalmente, los
métodos estáticos se denominan métodos de la clase y no pueden manejar datos
que definen valores de los atributos de los objetos; es decir sólo pueden
manejar datos de valor o datos definidos dentro del mismo método.
MODELADO DE LOS MÉTODOS ESTÁTICOS
En un diagrama de
clases UML que modela una clase, los métodos estáticos se denotan con un
subrayado de la definición de la signatura del método.
Figura
1.
Diagrama de clases de ManejadoraFechas
|
En el diagrama de la
figura 1 se tiene tres métodos estáticos los cuales son definidos para la clase
ejecutable llamada ManejadoraFechas. Una clase se denomina la clase ejecutable
si contiene el método estático main(). Una aplicación sólo puede tener una clase
ejecutable. El objetivo del método main() es definir la entrada del sistema a la
ejecución de la aplicación y esta es la razón fundamental para el método main()
sea estática, porque de lo contrario tendría antes de llamar al método main()
crear un objeto de la clase ejecutable, lo cual sería imposible antes de entrar
el sistema a la aplicación.
PROGRAMACIÓN DE LOS MÉTODOS ESTÁTICOS
En Java los métodos
estáticos se identifican por el modificador static. El formato general de la definición de un
método estático es como se muestra a continuación:
<visibilidad>
static <tipo> nombre_método(argumentos){ … }
|
Vea en la programación
de la clase java llamada ManejadoraFechas que se muestra en el código de la siguiente
aplicación.
Aplicación
1 Java
|
package aplicacion;
import java.io.*;
import java.util.*;
public class ManejadoraFechas {
public static
void main(String[] args) {
int año;
String
mensajeError="Fuera del calendario Gregoriano\n o del año actual";
try{
BufferedReader leerEntrada=new BufferedReader(new
InputStreamReader(System.in));
System.out.print("Digite año:
");
año=Integer.parseInt(leerEntrada.readLine());
if(!esValido(año)) throw new Exception(mensajeError);
if(esBisiesto(año))System.out.println(año+" es bisiesto");
else
System.out.println(año+" no es bisiesto");
}catch
(Exception e){
System.err.println(e.getMessage());
}
}
public static
boolean esBisiesto(int año){
return
(año%4==0)||((año%100!=0)&&(año%400==0));
}
public static
boolean esValido(int año){
Calendar
fechaHoy=Calendar.getInstance();
return
año>=1582 && año<=fechaHoy.get(Calendar.YEAR);
}
}
|
La clase ManejadoraFechas es la clase ejecutable de la aplicación y contiene tres métodos
estáticos, denominados:
1) El método main().
Es un método estático y que tiene como objetivos definir la entrada del sistema
a la aplicación para ejecutar los programas de la misma y un segundo objetivo
es definir el monitoreo o control de las ejecución de los programas que
componen la aplicación.
2) El método esPrimo(). Es un método estático y tiene como objetivo averiguar si el valor
entero que recibe como argumento corresponde a un año bisiesto. Un año es
bisiesto si divisible por cuatro excepto que sean divisibles por cien a menos
que sea divisible por cuatrocientos.
3) El método esValido(). Es un método estático y tiene como objetivo averiguar si el valor
entero entregado como argumento corresponde a un año del calendario gregoriano
hasta el año actual. El calendario gregoriano se introdujo en el año 1582 por
el papa Gregorio XIII antes de este regía el calendario juliano.
REGLAS
ü Regla
1. Los métodos estáticos no
pueden procesar valores de atributos de objetos.
ü Regla
2. Los métodos estáticos se
utilizan cuando los valores son comunes para todos los objetos de la clase.
ü Regla
3. En una aplicación sólo
puede existir un método estático main
ü Regla
4. Para llamar a su ejecución
un método estático se hace mediante el nombre de la clase, cuando este método
estático se define dentro de la clase ejecutable no se requiere el nombre de la
clase cuando se llama dentro del método main.
CASO DE ESTUDIO
Modelar en UML y
programar en java una aplicación para permitir a sus usuarios calcular el IMC
(índice de masa corporal). El IMC es un indicador medico que relaciona entre el
peso (kilogramos) y la estatura (metros) de una persona ideado por el
estadístico belga L. A. J. Quetelet. Este indicador se calcula según la
siguiente fórmula matemática:
Este modelo matemático
es válido para hombres y mujeres entre edades de 20 y 60 años. Es decir no
aplica para personas fuera de este rango de edades.
Tabla 1
|
|
Rangos IMC
|
Diagnostico
|
Por debajo de 18.5
|
Por debajo del peso
|
Entre 18.5 y 24.9
|
Saludable
|
Entre 25.0 y 29.9
|
Con sobrepeso
|
Entre 30.0 y 39.9
|
Obeso
|
Superior a 39.9
|
Obesidad extrema o de alto riesgo
|
La aplicación debe
permitirle a una persona (hombre o mujer) entre 20 y 60 años consultar su IMC
en un cuadro de diálogos que le solicita: la edad, peso (en kilogramos) y
estatura (en centímetro).
ESPECIFICACIÓN DE REQUERIMIENTOS
Figura
2.
Diagrama de casos de uso
|
El diagrama de casos
de uso especifica los requerimientos del usuario al sistema. El usuario espera
que el sistema le calcule el índice de masa corporal y le haga un diagnostico
de acuerdo a este valor del IMC.
DISEÑO CUADRO DE DIÁLOGO
La interacción del
usuario con el sistema software de la aplicación lo debe hacer con un cuadro de
diálogos como el que se muestra en la figura 3. Este cuadro de diálogos es de
tipo JFrame el cual contiene: cinco
objetos de tipo JTextField, siete
objetos de tipo JLabel y un objeto
de tipo JButton. El usuario digita
en cada cuadro de texto el dato correspondiente y para que el sistema lo acepte
pulsa la tecla ENTER. Es importante que el sistema valide los datos cada vez
que el usuario entra un carácter a los cuadros de texto. En el caso que pulse
una tecla que no corresponda a un carácter valido del formato del dato el
sistema borra lo digitado y sigue pidiendo los valores del dato. El dato para
la edad debe ser un entero positivo sin signo. Los datos para el peso, la
estatura deben ser numérico decimal (con cifras decimales o no) positivo sin
signo. El sistema debe validar el dato de la edad y en el caso que la edad no
esté entre 20 y 60 años el sistema debe informarle mediante un cuadro de
mensajes y no permitirle continuar introducir los datos del peso y la estatura.
El sistema se restaurara para que el usuario introduzca otro dato de edad.
Figura
3.
Cuadro de diálogo de aplicación para el cálculo del IMC
|
Desde el punto de
vista de la programación orientada a objetos, el cuadro de diálogos de la
figura 3 corresponde a la representación visual del objeto de una subclase de la clase JFrame.
DISEÑO ARQUITECTÓNICO DE LA APLICACIÓN
El diseño
arquitectónico proporciona la vista para el montaje del esqueleto del sistema.
En la figura 4 se muestra el esqueleto del sistema para calcular índice de masa
corporal de una persona hombre o mujer entre 20 y 60 años. El programador se da
cuenta al analizar esta vista que debe crear un nuevo proyecto llamado calculoimc al cual se le debe agregar
tres clases java llamadas CalculoIMC,
VentanaPrincipal y IndiceMasaCorporal.
Figura
4.
Vista arquitectónica
|
La clase CalculoIMC es la clase ejecutable la
cual tiene una dependencia de la clase VentanaPrincipal.
La clase VentanaPrincipal es una
subclase de la clase JFrame del
paquete javax.swing, es decir que
entre la subclase VentanaPrincipal y
la clase JFrame hay una relación de herencia
y adicionalmente la subclase VentanaPrincipal
y la clase IndiceMasaCorporal hay una
relación de dependencia.
Al existir una
relación de herencia entre la subclase VentanaPrincipal
y la clase JFrame es posible definir
una serie de objetos que constituyen al cuadro de diálogos de la figura 3 esto
debido que la subclase hereda todos los componentes definidos en la clase JFrame.
Figura
5.
Diagrama de clases de la clase CalculoIMC
|
package calculoimc;
public class
CalculoIMC {
public static void main(String[] args) {
VentanaPrincipal diag=new
VentanaPrincipal();
}
}
|
PROGRAMACIÓN DE LA CLASE VentanaPrincipal
Figura
6.
Diagrama de clases de la clase VentanaPrincipal
|
package
calculoimc;
import
javax.swing.*;
import
java.awt.event.*;
import
java.awt.*;
public class
VentanaPrincipal extends JFrame implements ActionListener,KeyListener{
JButton btnCancelar;
JTextField txtEdad,txtPeso,txtEstatura,txtIMC,txtDiagnostico;
JLabel
labEdad,labEdad1,labPeso,labPesoUnidades;
JLabel
labEstatura,labEstaturaUnidades,labIMC;
JPanel panel1,panel2;
Color colorFondo,colorTxt,colorFuente;
Font fuente;
static int edad;
public static int estado;
static float peso,estatura;
public VentanaPrincipal(){
this.setSize(410,280);
this.setLocationRelativeTo(null);
this.setTitle("Calculo IMC
(Válido para personas entre 20 y 60 años)");
this.setResizable(false);
this.setLayout(null);
colorFondo=new Color(110,155,155);
colorTxt=new Color(150,170,170);
colorFuente=new Color(255,255,0);
fuente= new
Font("serief",Font.BOLD,12);
this.getContentPane().setBackground(colorFondo);
inicializarComponentes();
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void inicializarComponentes(){
panel1=new JPanel();
panel1.setBounds(5,10,395,40);
panel1.setBorder(BorderFactory.createEtchedBorder());
panel1.setLayout(null);
labEdad=new JLabel("Digite su
Edad:");
labEdad.setBounds(10,10,100,20);
labEdad.setFont(fuente);
labEdad.setForeground(colorFuente);
panel1.add(labEdad);
txtEdad=new JTextField();
txtEdad.setBounds(110,10,40,20);
txtEdad.setHorizontalAlignment(JTextField.RIGHT);
txtEdad.setBorder(BorderFactory.createBevelBorder(1));
txtEdad.setBackground(colorTxt);
txtEdad.setForeground(colorFuente);
panel1.add(txtEdad);
labEdad1=new JLabel("(años
cumplidos)");
labEdad1.setBounds(160,10,120,20);
panel1.add(labEdad1);
panel1.setBackground(colorFondo);
labEdad1.setForeground(colorFuente);
this.add(panel1);
txtEdad.addKeyListener(this);
panel2=new JPanel();
panel2.setBounds(5,60,395,185);
panel2.setBorder(BorderFactory.createEtchedBorder());
panel2.setLayout(null);
labPeso=new JLabel("Peso:
");
labPeso.setBounds(50,10,60,20);
panel2.add(this.labPeso);
labPeso.setForeground(colorFuente);
txtPeso=new JTextField();
txtPeso.setBounds(120,10,60,20);
txtPeso.setHorizontalAlignment(JTextField.RIGHT);
txtPeso.setBorder(BorderFactory.createBevelBorder(1));
txtPeso.setBackground(colorTxt);
txtPeso.setEditable(false);
txtPeso.setForeground(colorFuente);
panel2.add(this.txtPeso);
labPesoUnidades=new
JLabel("Kilogramos");
labPesoUnidades.setBounds(190,10,80,20);
labPesoUnidades.setForeground(colorFuente);
panel2.add(this.labPesoUnidades);
labEstatura=new
JLabel("Estatura:");
labEstatura.setBounds(50,50,60,20);
labEstatura.setForeground(colorFuente);
panel2.add(this.labEstatura);
txtEstatura=new JTextField();
txtEstatura.setBounds(120,50,60,20);
txtEstatura.setHorizontalAlignment(JTextField.RIGHT);
txtEstatura.setBorder(BorderFactory.createBevelBorder(1));
txtEstatura.setBackground(colorTxt);
txtEstatura.setForeground(colorFuente);
txtEstatura.setEditable(false);
panel2.add(txtEstatura);
labEstaturaUnidades=new
JLabel("Centimetros");
labEstaturaUnidades.setBounds(190,50,80,20);
labEstaturaUnidades.setForeground(colorFuente);
panel2.add(this.labEstaturaUnidades);
labIMC=new JLabel("IMC:");
labIMC.setBounds(50,90,60,20);
labIMC.setForeground(colorFuente);
panel2.add(this.labIMC);
txtIMC=new JTextField();
txtIMC.setBounds(120,90,60,20);
txtIMC.setHorizontalAlignment(JTextField.RIGHT);
txtIMC.setBorder(BorderFactory.createBevelBorder(1));
txtIMC.setBackground(colorTxt);
txtIMC.setForeground(colorFuente);
txtIMC.setEditable(false);
panel2.add(txtIMC);
txtDiagnostico=new JTextField();
txtDiagnostico.setBounds(50,130,300,40);
txtDiagnostico.setHorizontalAlignment(JTextField.CENTER);
txtDiagnostico.setBorder(BorderFactory.createBevelBorder(1));
txtDiagnostico.setBackground(colorTxt);
txtDiagnostico.setEditable(false);
panel2.add(txtDiagnostico);
btnCancelar=new
JButton("Cancelar");
btnCancelar.setBounds(280,40,100,40);
btnCancelar.setBorder(BorderFactory.createBevelBorder(0));
btnCancelar.setBackground(colorTxt);
btnCancelar.setForeground(colorFuente);
panel2.add(this.btnCancelar);
panel2.setBackground(colorFondo);
this.add(panel2);
txtPeso.addKeyListener(this);
txtEstatura.addKeyListener(this);
btnCancelar.addActionListener(this);
}
// Programación modelo dinámico
public void actionPerformed(ActionEvent
ev){
if(ev.getSource()==btnCancelar)
cancelar();
}
public void keyPressed(KeyEvent ev){
if(ev.getSource()==txtPeso){
if((ev.getKeyChar()=='\n')&&(!txtPeso.getText().isEmpty())){
txtPeso.setEditable(false);
txtEstatura.setEditable(true);
txtEstatura.requestFocus();
}
}else if(ev.getSource()==txtEstatura){
if((ev.getKeyChar()=='\n')&&(!txtEstatura.getText().isEmpty())){
txtEstatura.setEditable(false);
txtIMC.setText(IndiceMasaCorporal.toStringIMC(peso, estatura));
txtDiagnostico.setText(IndiceMasaCorporal.obtenerDiagnostico(peso,estatura));
if(estado==1)txtDiagnostico.setForeground(new
Color(255,0,0));
else
txtDiagnostico.setForeground(colorFuente);
}
}
}
public void keyReleased(KeyEvent ev){
if(ev.getSource()==txtEdad){
try{
edad=Integer.parseInt(txtEdad.getText());
}catch (Exception e){
txtEdad.setText("");
}
} else if(ev.getSource()==txtPeso){
try{
peso=Float.parseFloat(txtPeso.getText());
}catch (Exception e){
txtPeso.setText("");
}
}else if(ev.getSource()==txtEstatura){
try{
estatura=(Float.parseFloat(txtEstatura.getText()))/100F;
}catch (Exception e){
txtEstatura.setText("");
}
}
}
public void keyTyped(KeyEvent ev){
String mensaje1="Fuera del rango
de edad\n(consulte el médico)";
if(ev.getSource()==txtEdad){
if(ev.getKeyChar()=='\n'
&& !txtEdad.getText().isEmpty()){
if(edad<20 || edad>60){
JOptionPane.showMessageDialog(this,mensaje1);
cancelar();
}else{
txtPeso.setEditable(true);
txtPeso.requestFocus();
}
}
}
}
private void cancelar(){
txtEdad.setText("");
txtEdad.setEditable(true);
txtPeso.setText(null);
txtPeso.setEditable(false);
txtEstatura.setText(null);
txtEstatura.setEditable(false);
txtIMC.setText(null);
txtDiagnostico.setText(null);
txtEdad.requestFocus();
}
}
|
PROGRAMACIÓN DE LA CLASE IndiceMasaCorporal
Figura
7.
Diagrama de clases de la clase IndiceMasaCorporal
|
package
calculoimc;
import
java.text.*;
public class
IndiceMasaCorporal {
static String
strDiagnosticos[]={"Por debajo del
peso","Saludable","Con sobrepeso",
"Obeso","Obesidad extrema
o de alto riesgo"};
public static String toStringIMC(float
peso,float estatura){
DecimalFormat dec=new
DecimalFormat("###.##");
return
(dec.format(peso/(estatura*estatura)));
}
public static String
obtenerDiagnostico(float peso, float estatura){
float imc=peso/(estatura*estatura);
int indice=4;
VentanaPrincipal.estado=1;
if(imc<18.5)indice=0;
else
if(imc<=24.9){indice=1;VentanaPrincipal.estado=0;}
else if(imc<=29.9)indice=2;
else if(imc<=39.9)indice=3;
return strDiagnosticos[indice];
}
}
|
LA DIFERENCIA ENTRE MÉTODOS ESTÁTICOS
Y NO ESTÁTICOS
Algunas de las
diferencias entre métodos estáticos y no estáticos son:
·
Los
métodos estáticos solo pueden acceder a miembros estáticos (datos y métodos) y
los métodos no estáticos pueden acceder tanto miembros estáticos como no
estáticos.
·
Los
métodos no estáticos solo pueden ser llamados por los objetos de la clase a la
pertenecen y los métodos estáticos pueden ser llamados tanto por la clase como
por los objetos.
·
Los métodos
estáticos se implementan cuando en un futuro no se le implementan miembros no
estáticos. Por ejemplo, cuando se quiere aplicar el modelo procedimental en
lenguajes orientados a objetos. Es una manera elegante de no utilizar las
ventajas de la programación orientada a objetos.
Aunque con algunas
excepciones, los métodos estáticos son pocos recomendables en sistemas
complejos. Yo diría que en curso de programación procedimental los métodos
estáticos son la solución para comprender el concepto de la programación
procedimental. Esta sería la solución para aprender la programación
procedimental con un lenguaje orientado a objetos puro, como el java.
DATOS ESTÁTICOS
De la misma manera
como existen métodos estáticos y no estáticos también existen los datos
estáticos y no estáticos. Los datos estáticos o datos de valor tienen como
característica fundamental que comparten el mismo espacio de memoria para todos
los objetos creados y a diferencia de los datos no estático o de instancia cada
objeto tiene su propio espacio de memoria para cada objeto creado. El formato
para definir un dato estático es como sigue:
<visibilidad> static
<tipo> nombre-variable {= valor inicial};
|
Ejemplo. Aplicación ejemplo uso datos estáticos.
Figura
8. Diagrama
de clases
|
|
Código fuente java de la clase EjemploEstaticos
|
package
ejemploestaticos;
public class
EjemploEstaticos {
public static void main(String[] args) {
Punto p,q,arrPuntos[]=new Punto[3];
p=new Punto();
q=new Punto(4.5F,5.0F);
for(int
i=0;i<arrPuntos.length;i++){
arrPuntos[i]=new Punto();
}
System.out.println("Numero de
puntos creado "+Punto.getNroPuntos());
System.out.println("p=
("+p.getX()+" , "+p.getY()+")");
System.out.println("q=
("+q.getX()+" , "+q.getY()+")");
for(int
i=0;i<arrPuntos.length;i++){
System.out.println("arrPuntos["+i+"]=
("+arrPuntos[i].getX()+" ,
"+arrPuntos[i].getY()+")");
}
}
}
|
Código fuente java de la clase Punto
|
package ejemploestaticos;
public class Punto {
private float
x,y;
private static
int nroPuntos=0;
public
Punto(float x, float y) {
this.x = x;
this.y = y;
nroPuntos++;
}
public Punto() {
this.x=this.y=0;
nroPuntos++;
}
public float
getX() {
return x;
}
public void
setX(float x) {
this.x = x;
}
public float
getY() {
return y;
}
public void
setY(float y) {
this.y = y;
}
public static
int getNroPuntos() {
return
nroPuntos;
}
}
|
Figura
9.
Almacenamientos de datos estáticos y no estáticos
|
|
Observen que el dato estático
nroPuntos ocupa un espacio de memoria
al cual todos los objetos al mismo espacio de memoria. Una modificación del valor
de esta variable estática por cualquier objeto es detectado por el resto de objetos.
No hay comentarios:
Publicar un comentario