martes, 15 de mayo de 2012

Ejemplo Completo de Java Ejemplo


Este ejemplo contiene algunas de las características más importantes de Java: clases, herencia, interfaces, gráficos, polimorfismo, etc. Las sentencias se numeran en cada fichero, de modo que resulta más fácil hacer referencia a ellas en los comentarios. La ejecución de este programa imprime algunas líneas en la consola MS-DOS y conduce a crear la ventana mostrada en la Figura.
Clase Ejemplo
A continuación se muestra el programa principal, contenido en el fichero Ejemplo1.java. En realidad, este programa principal lo único que hace es utilizar la clase Geometría y sus clases derivadas. Es pues un programa puramente “usuario”, a pesar de lo cual hay que definirlo dentro de una clase, como todos los programas en Java.
1. // fichero Ejemplo1.java
2. import java.util.ArrayList;
3. import java.awt.*;
4. class Ejemplo1 {
5. public static void main(String arg[]) throws InterruptedException
6. {
7. System.out.println("Comienza main()...");
8. Circulo c = new Circulo(2.0, 2.0, 4.0);
9. System.out.println("Radio = " + c.r + " unidades.");
10. System.out.println("Centro = (" + c.x + "," + c.y + ") unidades.");
11. Circulo c1 = new Circulo(1.0, 1.0, 2.0);
12. Circulo c2 = new Circulo(0.0, 0.0, 3.0);
13. c = c1.elMayor(c2);
14. System.out.println("El mayor radio es " + c.r + ".");
15. c = new Circulo(); // c.r = 0.0;
16. c = Circulo.elMayor(c1, c2);
17. System.out.println("El mayor radio es " + c.r + ".");
18. VentanaCerrable ventana =
19. new VentanaCerrable("Ventana abierta al mundo...");
20. ArrayList v = new ArrayList();
21. CirculoGrafico cg1 = new CirculoGrafico(200, 200, 100, Color.red);
22. CirculoGrafico cg2 = new CirculoGrafico(300, 200, 100, Color.blue);
23. RectanguloGrafico rg = new
24. RectanguloGrafico(50, 50, 450, 350, Color.green);
25. v.add(cg1);
26. v.add(cg2);
27. v.add(rg);
28. PanelDibujo mipanel = new PanelDibujo(v);
29. ventana.add(mipanel);
30. ventana.setSize(500, 400);
31. ventana.setVisible(true);
32. System.out.println("Termina main()...");
33. } // fin de main()
34. } // fin de class Ejemplo1
La sentencia 1 es simplemente un comentario que contiene el nombre del fichero. El compilador de Java ignora todo lo que va desde los caracteres // hasta el final de la línea.
Las sentencias 2 y 3 “importan” clases de los packages de Java, esto es, hacen posible acceder a dichas clases utilizando nombres cortos. Por ejemplo, se puede acceder a la clase ArrayList simplemente con el nombre ArrayList en lugar de con el nombre completo java.util.ArrayList, por haber introducido la sentencia import de la línea 2. Un package es una agrupación de clases que tienen una finalidad relacionada. Existe una jerarquía de packages que se refleja en nombres compuestos, separados por un punto (.). Es habitual nombrar los packages con letras minúsculas (como java.util o java.awt), mientras que los nombres de las clases suelen empezar siempre por una letra mayúscula (como ArrayList).
El asterisco (*) de la sentencia 3 indica que se importan todas las clases del package. Hay un package, llamado java.lang, que se importa siempre automáticamente. Las clases de java.lang se pueden utilizar directamente, sin importar el package.
La sentencia 4 indica que se comienza a definir la clase Ejemplo1. La definición de dicha clase va entre llaves {}. Como también hay otras construcciones que van entre llaves, es habitual indentar o sangrar el código, de forma que quede claro donde empieza (línea 4) y donde termina (línea 34) la definición de la clase. En Java todo son clases: no se puede definir una variable o una función que no pertenezca a una clase. En este caso, la clase Ejemplo1 tiene como única finalidad acoger al método main(), que es el programa principal del ejemplo. Las clases utilizadas por main() son mucho más importantes que la propia clase Ejemplo1. Se puede adelantar ya que una clase es una agrupación de variables miembro (datos) y funciones miembro (métodos) que operan sobre dichos datos y permiten comunicarse con otras clases. Las clases son verdaderos tipos de variables o datos, creados por el usuario. Un objeto (en ocasiones también llamado instancia) es una variable concreta de una clase, con su propia copia de las variables miembro.
Las líneas 5-33 contienen la definición del programa principal de la aplicación, que en Java siempre se llama main(). La ejecución siempre comienza por el programa o método main(). La palabra public indica que esta función puede ser utilizada por cualquier clase; la palabra static indica que es un método de clase, es decir, un método que puede ser utilizado aunque no se haya creado ningún objeto de la clase Ejemplo1 (que de hecho, no se han creado); la palabra void indica que este método no tiene valor de retorno. A continuación del nombre aparecen, entre paréntesis, los argumentos del método. En el caso de main() el argumento es siempre un vector o array (se sabe por la presencia de los corchetes []), en este caso llamado arg, de cadenas de caracteres (objetos de la clase String). Estos argumentos suelen ser parámetros que se pasan al programa en el momento de comenzar la ejecución (por ejemplo, el nombre del fichero donde están los datos). El cuerpo (body) del método main(), definido en las líneas 6-33, va también encerrado entre llaves {...}. A un conjunto de sentencias encerrado entre llaves se le suele llamar bloque. Es conveniente indentar para saber dónde empieza y dónde terminan los bloques del método main() y de la clase Ejemplo1. Los bloques nunca pueden estar entrecruzados; un bloque puede contener a otro, pero nunca se puede cerrar el bloque exterior antes de haber cerrado el interior.
La sentencia 7 (System.out.println("Comienza main()...");) imprime una cadena de caracteres o String en la salida estándar del sistema, que normalmente será una ventana de MSDOS o una ventana especial del entorno de programación que se utilice (por ejemplo Visual J++, de Microsoft). Para ello se utiliza el método println(), que está asociado con una variable static llamada out, perteneciente a la clase System (en el package por defecto, java.lang). Una variable miembro static, también llamada variable de clase, es una variable miembro que es única para toda la clase y que existe aunque no se haya creado ningún objeto de la clase. La variable out es una variable static de la clase System. La sentencia 7, al igual que las que siguen, termina con el carácter punto y coma (;).
La sentencia 8 (Circulo c = new Circulo(2.0, 2.0, 4.0);) es muy propia de Java. En ella se crea un objeto de la clase Circulo, que se define en los próximos capítulos. Esta sentencia es equivalente a las dos sentencias siguientes:
Circulo c;
c = new Circulo(2.0, 2.0, 4.0);
que quizás son más fáciles de explicar. En primer lugar se crea una referencia llamada c a un objeto de la clase Circulo. Crear una referencia es como crear un “nombre” válido para referirse a un objeto de la clase Circulo. A continuación, con el operador new se crea el objeto propiamente dicho. Puede verse que el nombre de la clase va seguido por tres argumentos entre paréntesis. Estos argumentos se le pasan al constructor de la clase como datos concretos para crear el objeto (en este caso los argumentos son las dos coordenadas del centro y el radio). Interesa ahora insistir un poco más en la diferencia entre clase y objeto. La clase Circulo es lo genérico: es el patrón o modelo para crear círculos concretos. El objeto c es un círculo concreto, con su centro y su radio. De la clase Circulo se pueden crear tantos objetos como se desee; la clase dice
que cada objeto necesita tres datos (las dos coordenadas del centro y el radio) que son las variables miembro de la clase. Cada objeto tiene sus propias copias de las variables miembro, con sus propios valores, distintos de los demás objetos de la clase.

La sentencia 9 (System.out.println("Radio = " + c.r + " unidades.");) imprime por la salida estándar una cadena de texto que contiene el valor del radio. Esta cadena de texto se compone de tres sub-cadenas, unidas mediante el operador de concatenación (+). Obsérvese cómo se accede al radio del objeto c: el nombre del objeto seguido del nombre de la variable miembro r, unidos por el operador punto (c.r). El valor numérico del radio se convierte automáticamente en cadena de caracteres.
La sentencia 10 es similar a la 9, imprimiendo las coordenadas del centro del círculo.
Las sentencias 11 y 12 crean dos nuevos objetos de la clase Circulo, llamados c1 y c2.
La sentencia 13 (c = c1.elMayor(c2);) utiliza el método elMayor() de la clase Circulo. Este método compara los radios de dos círculos y devuelve como valor de retorno una referencia al círculo que tenga mayor radio. Esa referencia se almacena en la referencia previamente creada c. Un punto importante es que todos los métodos de Java (excepto los métodos de clase o static) se aplican a un objeto de la clase por medio del operador punto (por ejemplo, c1.elMayor()). El otro objeto (c2) se pasa como argumento entre paréntesis. Obsérvese la forma “asimétrica” en la que se pasan los dos argumentos al método elMayor(). De ordinario se llama argumento implícito a c1, mientras que c2 sería el argumento explícito del método.
La sentencia 14 imprime el resultado de la comparación anterior y la sentencia 15 crea un nuevo objeto de la clase Circulo guardándolo en la referencia c. En este caso no se pasan argumentos al constructor de la clase. Eso quiere decir que deberá utilizar algunos valores “por defecto” para el centro y el radio. Esta sentencia anula o borra el resultado de la primera comparación de radios, de modo que se pueda comprobar el resultado de la segunda comparación.
La sentencia 16 (c = Circulo.elMayor(c1, c2);) vuelve a utilizar un método llamado elMayor() para comparar dos círculos: ¿Se trata del mismo método de la sentencia 13, utilizado de otra forma? No. Se trata de un método diferente, aunque tenga el mismo nombre. A las funciones o métodos que son diferentes porque tienen distinto código, aunque tengan el mismo nombre, se les llama funciones sobrecargadas (overloaded). Las funciones sobrecargadas se diferencian por el numero y tipo de sus argumentos.
El método de la sentencia 13 tiene un único argumento, mientras que el de la sentencia 16 tiene dos (en todos los casos objetos de la clase Circulo). En realidad, el método de la sentencia 16 es un método static (o método de clase), esto es, un método que no necesita ningún objeto como argumento implícito. Los métodos static suelen ir precedidos por el nombre de la clase y el operador punto (Java también permite que vayan precedidos por el nombre de cualquier objeto, pero es considerada una nomenclatura más confusa.). La sentencia 16 es absolutamente equivalente a la sentencia 13, pero el método static de la sentencia 16 es más “simétrico”.
Las sentencias 17 y 18 no requieren ya comentarios especiales.
Las sentencias 18-31 tienen que ver con la parte gráfica del ejemplo. En las líneas 18-19 (VentanaCerrable ventana = new VentanaCerrable("Ventana abierta al mundo...");) se crea una ventana para dibujar sobre ella. Una ventana es un objeto de la clase Frame, del package java.awt. La clase VentanaCerrable, explicada en el Apartado 1.3.9 en la página 17, añade a la clase Frame la capacidad de responder a los eventos que provocan el cierre de una ventana. La cadena que se le pasa como argumento es el título que aparecerá en la ventana. En la sentencia 20 (ArrayList v = new ArrayList();) se crea un objeto de la clase ArrayList (contenida o definida en el package java.util). La clase ArrayList permite almacenar referencias a objetos de distintas clases. En este caso se utilizará para almacenar referencias a varias figuras geométricas diferentes.
Las siguientes sentencias 21-27 crean elementos gráficos y los incluyen en la lista v para ser dibujados más tarde en el objeto de la clase PanelDibujo. Los objetos de la clase Circulo creados anteriormente no eran objetos aptos para ser dibujados, pues sólo tenían información del centro y el radio, y no del color de línea. Las clases RectanguloGrafico y CirculoGrafico, definidas en los Apartados 1.3.6 y 1.3.7, derivan respectivamente de las clases Rectangulo (Apartado 1.3.3) y Circulo (Apartado 1.3.4), heredando de dichas clases sus variables miembro y métodos, añadiendo la información y los métodos necesarios para poder dibujarlos en la pantalla. En las sentencias 21- 22 se definen dos objetos de la clase CirculoGrafico; a las coordenadas del centro y al radio se une el color de la línea. En la sentencia 23-24 se define un objeto de la clase RectanguloGrafico, especificando asimismo un color, además de las coordenadas del vértice superior izquierdo, y del vértice inferior derecho. En las sentencias 25-27 los objetos gráficos creados se añaden al objeto v de la clase ArrayList, utilizando el método add() de la propia clase ArrayList.
En la sentencia 28 (PanelDibujo mipanel = new PanelDibujo(v);) se crea un objeto de la
clase PanelDibujo, definida en el Apartado 1.3.8. Por decirlo de alguna manera, los objetos de dicha clase son paneles, esto es superficies en las que se puede dibujar. Al constructor de PanelDibujo se le pasa como argumento el vector v con las referencias a los objetos a dibujar. La sentencia 29 (ventana.add(mipanel);) añade o incluye el panel (la superficie de dibujo) en la ventana; la sentencia 30 (ventana.setSize(500, 400);) establece el tamaño de la ventana en pixels; finalmente, la sentencia 31 (ventana.setVisible(true);) hace visible la ventana creada. ¿Cómo se consigue que se dibuje todo esto? La clave está en la serie de órdenes que se han ido dando al computador. La clase PanelDibujo deriva de la clase Container a través de Panel, y redefine el método paint() de Container. En este método, explicado en el Apartado 1.3.8, se realiza el dibujo de los objetos gráficos creados. El usuario no tiene que preocuparse de llamar al método paint(), pues se llama de modo automático cada vez que el sistema operativo tiene alguna razón para ello (por ejemplo cuando se crea la ventana, cuando se mueve, cuando se minimiza o maximiza, cuando aparece después de haber estado oculta, etc.). La Figura muestra la ventana resultante de la ejecución del programa main() de la clase Ejemplo1. Para entender más a fondo este resultado es necesario considerar detenidamente las clases definidas en los apartados que siguen.

Fuente: WordXy

No hay comentarios:

Publicar un comentario