Sun Microsystems, líder en servidores para Internet, unos de cuyos... tiempo es “the network is the computer” (la red es... PROGRAMACION CON VISUAL AGE FOR JAVA

Anuncio
PROGRAMACION CON VISUAL AGE FOR JAVA
Introducción al Lenguaje Java
Sun Microsystems, líder en servidores para Internet, unos de cuyos lemas desde hace mucho
tiempo es “the network is the computer” (la red es la computadora, quiere dar a entender que
el verdadero ordenador es la red en su conjunto y no cada máquina individual). Es quien ha
desarrollado el lenguaje Java, en un intento de resolver simultáneamente todos los problemas
que se plantean a los desarrolladores de software por la proliferación de arquitecturas
incompatibles, tanto entre las diferentes máquinas como entre los diversos sistemas operativos
de ventanas que funcionaban sobre una misma máquina, añadiendo la dificultad de crear
aplicaciones distribuidas en una red como Internet.
He podido leer más de cinco versiones distintas sobre el origen, concepción y desarrollo de
Java, desde la que dice que éste fue un proyecto que rebotó durante mucho tiempo por
distintos departamentos de Sun sin que nadie le prestara atención, hasta que finalmente
encontró su nicho de mercado en la aldea global que es Internet; hasta la más difundida, que
justifica a Java como lenguaje de pequeños electrodomésticos.
Hace algunos años, Sun Microsystems decidió intentar introducirse en el mercado de la
electrónica de consumo y desarrollar programas para pequeños dispositivos electrónicos. Tras
unos comienzos dudosos, Sun decidió crear una filial denominada FirstPerson Inc. Para dar
margen de maniobra al equipo responsable del proyecto.
El mercado inicialmente previsto para los programas de FirstPerson eran equipos domésticos:
microondas, tostadoras y fundamentalmente, televisión interactiva. Este mercado, dada la falta
de pericia de los usuarios para el manejo de estos dispositivos, requería unas interfaces mucho
más cómodas e intuitivas que los sistemas de ventanas que proliferaban en el momento.
Otros requisitos importantes a tener en cuenta era la fiabilidad del código y la facilidad de
desarrollo, James Gosgling, el miembro del equipo con más experiencia en lenguajes de
programación, decidió que las ventajas aportadas por la eficiencia de C++ no compensaban el
gran coste de pruebas y depuración. Gosgling había trabajado en su tiempo libre en un
lenguaje de programación que él había llamado Oak, el cual, aún partiendo de la sintaxis de
C++, intentaba remediar las deficiencias que iba observando.
Los lenguajes al uso, como C o C++, deben ser compilados para un chip, y si se cambia el
chip, todo el software debe compilarse de nuevo. Esto encarece mucho los desarrollos y el
problema es especialmente acusado en el campo de la electrónica de consumo.
La aparición de un chip más barato y generalmente más eficiente conduce inmediatamente a
los fabricantes a incluirlo en las nuevas series de sus cadenas de producción, por pequeña que
sea la diferencia en precio ya que, multiplicada por la tirada masiva de los aparatos, supone un
ahorro considerable. Por tanto, Gosgling decidió mejorar las características de Oak y
utilizarlo.
El primer proyecto en que se aplicó este lenguaje recibió el nombre de proyecto Green y
consistía en un sistema de control completo de los aparatos electrónicos y el entorno de un
1
hogar. Para ello se construyó un ordenador experimental denominado *7 (Star Seven). El
sistema presentaba una interfaz basada en la representación de la casa de forma animada y el
control se llevaba a cabo mediante una pantalla sensible al tacto. En el sistema aparecía Duke,
la actual mascota de Java. Posteriormente se aplicó a otro proyecto denominado VOD (Video
on Demand) en el que se empleaba como interfaz para la televisión interactiva. Ninguno de
estos proyectos se convirtió nunca en un sistema comercial, pero fueron desarrollados
enteramente en un Java primitivo y fueron como su bautismo de fuego.
Una vez que en Sun se dieron cuenta que a corto plazo la televisión interactiva no iba a ser un
gran éxito, urgieron a FirstPerson a desarrollar con rapidez nuevas estrategias que produjeran
beneficio. No lo consiguieron y FirstPerson cerró en la primavera en la primavera de 1994.
Pese a lo que parecía ya un olvido definitivo, Bill Joy, cofundador de Sun y uno de los
desarrolladores principales del Unix de Berkeley, juzgó que Internet podría llegar a ser el
campo de juego adecuado para disputar a Microsoft su primacía casi absoluta en el terreno del
software y vio en Oak el instrumento idóneo para llevar a cabo estos planes. Tras un cambio
de nombre y modificaciones de diseño, el lenguaje Java fue presentado en sociedad en Agosto
de 1995.
Lo mejor será hacer caso omiso de las historias que pretenden dar carta de naturaleza a la
clarividencia industrial de sus protagonistas; porque la cuestión es si independientemente de
su origen y entorno comercial, Java ofrece soluciones a nuestras expectativas. Porque vamos a
desechar la penicilina aunque haya sido su origen fruto de la casualidad.
Características de Java










Es simple.
Es Orientado a Objetos.
Es distribuido.
Es robusto.
Es de arquitectura neutral.
Es seguro.
Es portable.
Es interpretado.
Es multithreaded.
Es dinámico.
Es Simple:
Java reduce en un 50% los errores más comunes de programación:
- No presenta aritmética de punteros.
- No existen referencias.
- No se definen tipos (struct, unio, typedef)
- No se usan macros.
- No hay necesidad de liberar memoria.
Es Orientado a Objetos
Java implementa la tecnología de OOP de C++.
- Encapsulación.
- Herencia.
- Polimorfismo.
2
Es Distribuido
-
Java tiene capacidades de interconexión TCP/IP.
Tiene librerías para acceder e interactuar con los protocolos http y ftp.
Es Robusto
-
Comprobación de punteros.
Comprobación de límites de arrays.
Excepciones.
Verificación de byte-codes.
Es de Arquitectura Neutral
Para establecer como parte integral de la red, el compilador Java compila su código a un
fichero objeto de formato independiente de la arquitectura de la máquina en que se ejecutará.
Cualquier máquina que tenga el sistema de ejecución (run-time) puede ejecutar ese código
objeto, sin importar en modo alguno la máquina en que ha sido generado. Actualmente existen
sistemas run-time para Solares, SunOs, Windows 95, 98, Windows NT, Linux, Iris, Aix, Mac,
Apple y probablemente haya grupos de desarrollo trabajando en el porting a otras plataformas.
El código fuente Java se “compila” a un código de bytes de alto nivel independiente de la
máquina. Este código (byte-codes) está diseñado para ejecutarse en una máquina hipotética
que es implementada por un sistema run-time, que sí es dependiente de la máquina.
Además, habrá APIs de Java que también entren en contacto directo con el hardware y serán
dependientes de la máquina, como ejemplo de este tipo de APIs podemos citar:
- Java 2D: gráficos 2D y manipulación de imágenes.
- Java Media Framework: Elementos críticos en el tiempo: audio, video…
- Java Animation: Animación de objetos 2D
- Java Telephony: Integración con telefonía.
- Java Share: Interacción entre aplicaciones multiusuario.
- Java 3D: Gráficos 3D y su manipulación.
Es Seguro
Seguridad por parte del lenguaje:
- No se hace uso de punteros.
- Casting sólo para datos numéricos.
Seguridad por parte del compilador:
- Se genera archivo de byte-codes.
- Tipos de parámetros y argumentos conocidos.
- Acceso conocido: public, private o protected.
Es Portable
-
Tiene arquitectura independiente del sistema.
Usa enteros reales de 32 bits en complemento a 2.
Tiene un sistema abstracto de ventanas conocido como AWT (Abstract Window
Toolkit).
Es Interpretado
-
El archivo bytecodes es muy cercano a el lenguaje de máquina. Pero necesita de un
run-time para ser ejecutado.
3
-
Existe un run-time específico para cada sistema operativo.
Es Multithreaded
-
Java permite muchas actividades simultáneas en un programa.
Los Threads son pequeños procesos o piezas independientes de un proceso que se
ejecutan independientemente a al aplicación.
Es Dinámico
Java se beneficia todo lo posible de la tecnología orientada a objetos. Java no intenta conectar
todos los módulos que comprenden una aplicación hasta el tiempo de ejecución. Las librerías
nuevas o actualizadas no paralizarán las aplicaciones actuales (siempre que mantengan el API
anterior).
Java también simplifica el uso de protocolos nuevos o actualizados. Si su sistema ejecuta una
aplicación Java sobre la red y encuentra una pieza de la aplicación que no sabe manejar, tal
como se ha explicado en párrafos anteriores, Java es capaz de traer automáticamente
cualquiera de esas piezas que el sistema necesita para funcionar.
Java, para evitar que los módulos de byte-codes o los objetos o nuevas clases, haya que estar
trayéndolos de la red cada vez que se necesiten, implementa las opciones de persistencia, para
que no se eliminen cuando se la limpie la caché de la máquina.
4
CONCEPTOS Y SINTAXIS DE JAVA
Definición de una Clase
La primera línea en negrilla en el listado siguiente comienza un bloque de definición de clase
/**
* The HelloWorldApp class implements an application that
* simply displays "Hello World!" to the standard output.
*/
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display the string.
}
}
Una clase--el bloque de construcción básico de un lenguaje orientado a objetos tal como Java- es una plantilla que describe los datos y el comportamiento asociados con las instancias de
esa clase. Cuando se instancia una clase se crea un objeto que se parezca y luzca como otras
instancias de la misma clase. Los datos asociados con una claseo un objeto son almacenados
en variables; el comportamiento asociado con una clase u objeto es implemtado mediante
métodos. Los métodos son similares a las funciones o procedimientos en lenguajes
procedurales como C.
La receta de estofado de cordero de Julia es un ejemplo del mundo real de lo que es una clase.
Su interpretación del estofado de cordero es una instancia de la receta, y la mía es otra muy
distinta. (mientras ambos estofados de cordero podrian parecer lo mismo, me imagino que
ellos "huelen y saben" diferente.)
Un ejemplo más tradicional del mundo de la programación es una clase que representa un
rectángulo. Esta clase podría contener variables que representan los puntos de originen del
rectángulo, su ancho y altura. La clase podría también contener un método que calcule el área
del rectángulo. Una instancia del rectángulo podría contener la información para un rectángulo
específico, como las dimensiones del piso del salón de clases, o las dimensiones de esta
página.
En el lenguaje Java, la forma más simple de la definición de una clase es:
class Nombre {
...
}
La palabra clave class empieza la definición de la clase llamada nombre. Las variables y
métodos de la clase se incluyen dentro de llaves que empiezan justo al final de la definición de
la clase. La aplicación "Hello World" no tiene variables y tiene un método simple llamado
main.
El Método Main
La primera línea en negrilla en el listado siguiente comienza la definición del método main:
/**
* The HelloWorldApp class implements an application that
* simply displays "Hello World!" to the standard output.
*/
5
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display the string.
}
}
Toda aplicación Java debe contener un método main cuya estructura es como sigue:
public static void main(String[] args)
Esta estructura presenta los siguientes modificadores:



public indica que el método main puede ser llamado por cualquier objeto.
static indica que el método main es un método de clase.
void indica que el método main no retorna valor.
Cómo se invoca al Método main
Cuando el interprete de Java ejecuta una aplicación (siendo invocado por encima de la clase
de control de la aplicación), empieza invocando al método main de la clase. El método main a
su vez llama a todos los métodos requeridos para ejecutar una aplicación.
Si se trata de invocar el intérprete de Java en una clase que no contiene el método main, el
intérprete se niega a ejecutar el programa y muestra un mensaje similar al siguiente:
In class NoMain: void main(String argv[]) is not defined
Argumentos del método Main
Como se puede apreciar en el siguiente fragmento de código, el método main acepta un único
argumento: un arreglo de elementos del tipo String.
public static void main(String[] args)
Este array es el mecanismo por el cual el sistema en tiempo de ejecución pasa información a
una aplicación. Cada String en el arreglo se llama argumento de línea de comando. Los
argumentos de línea de comando permiten interferir la operación de una aplicación sin
necesidad de recompilar. Por ejemplo, un programa de ordenamiento podría permitir al
usuario especificar que la data a ordenarse en orden descendiente con la siguiente línea de
comando:
-descending
Uso de Clases y Objetos
La aplicación "Hello World" es el programa de Java más simple que realmente ‘haga algo’.
Ya que es un programa tan simple, no necesita definir otra clase más que HelloWorldApp. Sin
embargo, la mayoría de programas que escribirá serán más complejos y será necesario escribir
otras clases y código de Java de soporte.
La "Hello World" application does use another class--the System class--that is part of the API
(application programming interface) provided with the Java environment. The System class
provides system-independent access to system-dependent functionality.
6
El código en negrita en el siguiente listado ilustra el empleo de una variable de clase de la
clase System, y un método instanciado.
/**
* The HelloWorldApp class implements an application that
* simply displays "Hello World!" to the standard output.
*/
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display the string.
}
}
La Anatomía de un Applet de Java
Veamos como funciona un applet de Java.
import java.applet.Applet;
import java.awt.Graphics;
public class HelloWorld extends Applet {
public void paint(Graphics g) {
g.drawString("Hello world!", 50, 25);
}
}
Definición de una Subclase de Applet
La primera línea en negrita del siguiente listado inicia un bloque que define la clase
HelloWorld.
import java.applet.Applet;
import java.awt.Graphics;
public class HelloWorld extends Applet {
public void paint(Graphics g) {
g.drawString("Hello world!", 50, 25);
}
}
La palabra clave extends indica que HelloWorld es una subclase de la clase Applet.
Desde la clase Applet, los applets heredan una gran cantidad de funcionalidad. Quizás lo más
importante es la habilidad de responder a los requerimientos del browser. Por ejemplo, cuando
un browser que soporta Java carga una página que contiene un applet, el browser envía un
requerimiento al applet, le indica al applet que se inicialice y que empiece a ejecutarse.
Un applet no está restringido para definir solo una clase. Detrás de la subclase necesaria del
Applet, un applet puede definir otras clases propias. Cuando un applet intenta hacer uso de
una clase, la aplicación que está ejecutando el applet primero busca la clase en forma local. Si
la clase no se encuentra disponible localmente, se descarga desde la ubicación desde donde la
subclase del Applet se originó.
7
Implementación de los Métodos de un Applet
import java.applet.Applet;
import java.awt.Graphics;
public class HelloWorld extends Applet {
public void paint(Graphics g) {
g.drawString("Hello world!", 50, 25);
}
}
Todo applet debe implementar uno o más de los métodos init, start, o paint.
Lección: Conceptos de Programación Orientada a Objetos
¿Qué es un Objeto?
Los objetos son clave para entender la tecnología orientada a objetos. Si ves a tu alrededor
verás varios ejemplos de objetos del mundo real: tu perro, tu escritorio, tu juego de televisión,
tu bicicleta, etc...
Todos estos objetos comparten dos características: Todos ellos presentan un estado y
comportamiento. Por ejemplo, los perros presentan un estado (nombre, color, raza, hambre) y
comportamiento (ladrar, traer cosas, y perseguir su cola). La bicicletas tienen estado
(velocidad actual, cadena del pedal actual, dos ruedas, número de cambios) y comportamiento
(frenar, acelerar, bajar la velocidad, hacer cambios).
Los objetos de software se modelan como objetos del mundo real en el sentido de que también
presentan estado y comportamiento. Un objeto de software mantiene su estado en una o más
variables. una variable es un elemento de dato llamado por un identificador. Un objeto de
software implementa su comportamiento a través de los métodos. Un método es una función,
una sub-rutina, asociada con un objeto.
Definición: Un objeto es un ‘manojo’ de software de variables y de métodos relacionados.
Se puede representar los objetos del mundo real mediante objetos de software. Se puede
representar perros del mundo real como objetos de software en programas de animación o una
bicicleta del mundo real como un objeto de software en un programa que controle una
bicicleta de ejercicios eléctricos. También se puede usar objetos de software para modelar
conceptos abstractos. Por ejemplo, un evento es un objeto usado en sistemas de ventanas GUI
para representar la acción de un usuario presionando el botón del mouse o una tecla.
La siguiente ilustración es una representación visual común de un objeto de software:
Todo aquello que el objeto de software conozca (estado) y pueda hacer (comportamiento) es
expresado mediante variables y métodos dentro de un objeto. Un objeto de software que
8
modele una bicicleta del mundo real podrían tener variables que indiquen el estado actual de
la bicicleta: su velocidad es 10 m/h, su ritmo de pedaleo es 90 r/m, y su cambio actual es el
quinto. Estas variables formalmente se conocen como variables de instancia porque contienen
el estado para un objeto de la bicicleta en particular, y en la terminología orientada a objetos,
un objeto en particular se llama instancia.
La siguiente figura ilustra una bicicleta como un objeto de software.
Además de sus variables, la bicicleta de software podría también tener métodos de frenado,
cambiar el ritmo del pedal, y mover los cambios. (La bicicleta no tendría un método para
cambiar la velocidad de la bicicleta, ya que la velocidad de la bicicleta es tan solo un efecto
secundario del manejo de los cambios, que tan rápido pedalee el ciclista, si están puestos los
frenos, y que tan inclinada esté la pista.) Estos métodos se conocen formalmente como
métodos de instancia porque inspeccionan o cambian el estado de una instancia de bicicleta en
particular. Los diagramas de objetos muestran que las variables de objetos conforman el
centro, o el núcleo, del objeto. Los métodos se encuentran alrededor y ocultan el núcleo del
objeto de otros objetos del programa. Empaquetar las variables del objeto dentro de la
custodia protectiva de sus métodos se llama encapsulación. Esta imagen conceptual de un
objeto-un núcleo de variables empaquetadas dentro de una membrana protectora de métodos
es una representación ideal de un objeto y es el ideal que los diseñadores de sistemas
orientados a objetos buscan. Sin embargo, esto no es todo. Frecuentemente, por razones
prácticas, un objeto podría desear exponer alguna de sus variables u ocultar alguno de sus
métodos. En el lenguaje de programación Java, un objeto puede especificar uno de los cuatro
niveles de acceso para cada una de sus variables y métodos. El nivel de acceso determina que
otros objetos y clases pueden acceder a determinada variable o método. Las variables y
métodos relacionados a la encapsulación en un software ordenado es una idea poderosa que
provee dos beneficios principales a los desarrolladores de software:
•Modularidad: El código fuente para un objeto se puede escribir y mantener
independientemente del código fuente para otros objetos. Además, un objeto puede ser pasado
fácilmente alrededor del sistema. Le puedes dar tu bicicleta a otra persona, y ésta aún
funcionará.
•Ocultar Información: Un objeto tiene una interfase pública que otros objetos pueden usar
para comunicarse. El objeto puede mantener información privada y los métodos se pueden
cambiar en cualquier momento sin afectar los otros objetos que dependen de él. No necesitas
comprender el mecanismo del los engranajes de tu bicicleta para usarla.
Qué es un Mensaje?
Un solo objeto generalmente no es muy útil. Por el contrario, un objeto usualmente aparece
como componente de un programa más grande o una aplicación que contiene muchos otros
objetos. Mediante la interacción de estos objetos, los programadores alcanzan una gran
funcionalidad y un comportamiento más complejo. Tú bicicleta estacionada en un garaje es
tan solo una aleación de titanio y caucho; por si misma, la bicicleta es incapaz de realizar una
actividad. La bicicleta es útil solo cuando otro objeto (tú) interactúa con ésta (pedal).
9
Los objetos de software interactúan y se comunican entre ellos enviándose mensajes el uno al
otro. Cuando un objeto A desea que un objeto B ejecute uno de los métodos de B, el objeto A
le envía un mensaje a B.
Algunas veces, el objeto receptor necesita más información de tal forma que sepa qué hacer
exactamente; por ejemplo, cuando deseas mover los cambios en tu bicicleta, necesitas indicar
que cambio deseas mover. Esta información es pasada con el mensaje en forma de parámetro.
La siguiente figura muestra los tres componentes que comprenden un mensaje:
1. El objeto al cual se dirige el mensaje (YourBicycle) (TuBicicleta)
2. El nombre del método a ejecutarse (changeGears) (moverCambios)
3. Cualquier parámetro que necesite el método (lowerGear) (cambioMenor)
Estos tres componentes son información suficiente para el objeto receptor para ejecutar el
método deseado. Ninguna otra información o contexto es requerido.
Los mensajes proveen dos beneficios importantes.
•El comportamiento de un objeto se expresa a través de sus métodos, de tal forma (fuera del
acceso a variables directamente) el pasado de mensajes soporta todas las interacciones
posibles entre objetos.
•Los objetos no necesitan estar en el mismo proceso o inclusive en la misma máquina para
enviar y recibir mensajes de ida y vuelta entre ellos.
¿Qué es una Clase?
En el mundo real, frecuentemente te encontrarás objetos del mismo tipo. Por ejemplo, tu
bicicleta es tan una sólo una de las tantas bicicletas que existen en el mundo. Usando la
tecnología orientada a objetos, decimos que su bicicleta es una instancia de una clase de
objetos conocida como bicicletas. Las bicicletas tiene estado (cambio actual, ritmo actual, dos
ruedas) y comportamiento (mover los cambios, frenar) en común. Sin embargo, cada estado
de la bicicleta es independiente y puede ser diferente de otras bicicletas.
Cuando se construyen las bicicletas, los fabricantes aprovechan el hecho de que las bicicletas
compartan características, al construir varias bicicletas a partir del mismo diseño. Sería muy
ineficiente producir un nuevo diseño para cada bicicleta producida individualmente.
En el software orientado a objetos, también es posible tener objetos del mismo tipo que
comparten características: rectángulos, empleados registros, video clips, etc. Como los
productores de bicicleta, usted puede aprovechar el hecho de que los objetos del mismo tipo
10
son similares y puede crear plantillas para dichos objetos. Una plantilla de software para
objetos se denomina clase.
Definición: Una clase es una plantilla, o prototipo, que define las variables y métodos
comunes a todos los objetos de un cierto tipo.
La clase para el ejemplo de la bicicleta declara las variables de clase necesarias para contener
la velocidad actual, el ritmo actual, etc. Para cada objeto de bicicleta. La clase también declara
y provee implementaciones para los métodos de instancia que permiten al ciclista mover los
cambios, frenar, y cambiar el ritmo del pedal, como se muestra en la siguiente figura.
currentSpeed=velocidadActual
currentCadence=ritmoActualGear
Implementation=implementación de
cambio
currentGear=cambio actual
Después de creada la clase bicicleta, se puede crear cualquier cantidad de objetos bicicleta a
partir de la clase. Cuando crea una instancia de la clase, el sistema asigna el espacio en
memoria para el objeto y todas sus variables de instancia. Cada instancia obtiene su propia
copia de todas las variables de instancia definidas en la clase.
Mi bicicleta
Tu bicicleta
Además de las variables de instancia, las clases pueden definir variables de clase. Una
variable de clase contiene información que es compartida por todas las instancias de clase. Por
ejemplo, supongamos que todas las bicicletas tienen su número de cambios. En este caso, la
defición de una variable de instancia para contener el número de cambios es ineficiente; cada
instancia tiene su propia instancia de variable, pero el valor será el mismo para cada instancia.
En tales situaciones, se define una variable de clase que contiene el número de cambios. Todas
las instancias comparten esta variable. Si un objeto cambia la variable, los cambios repercuten
en todos los objetos del mismo tipo. Una clase también puede declarar métodos de clases. Se
puede invocar un método de clase directamente de la clase, por el contrario se debe invocar
métodos de instancia en una instancia en particular.
11
Clase
Instancia de una Clase
¿Qué es una interfase?
En castellano, una interfaz es un dispositivo de un sistema el cual es usado por entidades no
relacionadas para poder interactuar entre ellas. De acuerdo a esta definición, un control remoto
es una interfaz entre una persona y un televisor, el idioma castellano es una interfaz entre dos
personas, y el protocolo de comportamiento impuesto a los militares es la interfaz entre las
personas del mismo rango. En el lenguaje de programación Java, una interfaz es un
dispositivo que los objetos sin relación usan para interactuar entre ellos. El concepto de
interfaz en Java es probablemente más parecido a la definición de un protocolo (un acuerdo de
comportamiento). En realidad, otros lenguajes orientados a objetos manejan la funcionalidad
de las interfaces, pero llaman a sus interfaces protocolos.
La clase bicicleta y su jerarquía de clase definen lo que puede o no puede hacer una bicicleta
en términos de su "biciclitedad." Pero las bicicletas interactúan con el mundo en otros
términos. Por ejemplo, una bicicleta en un almacén podría ser administrada por un programa
de inventarios. A un programa de inventarios no le importa que tipo de elementos administre
mientras cada elemento le provea de cierta información, como el precio y el número de serie.
En vez de forzar relaciones de clases entre elementos sin relación, el programa de inventario
establece un protocolo de comunicación. Este protocolo se presenta en la forma de un
conjunto de métodos definidos y constantes contenidas dentro de la interfaz. La interfaz de
inventario define, pero no implementa, métodos que establecen y obtienen el precio para el
consumidor, asignar un número de serie, etc...
Para que la bicicleta funcione en el programa de inventario, debe estar de acuerdo a un
protocolo mediante la implementación de una interfaz. Cuando una clase implementa una
interfaz, la clase acepta implementar todos los métodos definidos en la interfaz. Por lo tanto,
la clase bicicleta proveerá las implementaciones para los métodos que establecen y obtienen el
precio para el consumidor, asignar un código de barra, etc...
Una interfaz se usa para definir un protocolo de comportamiento que puede ser implementado
por cualquier clase en cualquier parte de la jerarquía de la clase. Las Interfaces son útiles
porque permite:



Capturar las similitudes entre las clases no relacionadas sin forzar de forma
artificial una relación entre clases.
Declarar métodos que una o más clases suponen implementar.
Revelar una interfaz de programación de un objeto sin revelar su clase.
Variables
Un objeto almacena su estado en variables.
12
Definición: Una variable es un elemento de datos llamados por un identificador.
public class MaxVariablesDemo {
public static void main(String args[]) {
// enteros
byte largestByte =
short largestShort
int largestInteger
long largestLong =
Byte.MAX_VALUE;
= Short.MAX_VALUE;
= Integer.MAX_VALUE;
Long.MAX_VALUE;
// números reales
float largestFloat = Float.MAX_VALUE;
double largestDouble = Double.MAX_VALUE;
// other primitive types
char aChar = 'S';
boolean aBoolean = true;
// mostrar en consola
System.out.println("Máximo
" + largestByte);
System.out.println("Máximo
largestShort);
System.out.println("Máximo
largestInteger);
System.out.println("Máximo
largestLong);
valor de byte es 127
valor de short es " +
valor de integer es " +
valor de long es " +
System.out.println("Máximo valor de float es " +
largestFloat);
System.out.println("Máximo valor de double es " +
largestDouble);
if (Character.isUpperCase(aChar)) {
System.out.println("El carácter " + aChar + " está en
mayúscula.");
} else {
System.out.println("El carácter " + aChar + " está
en minúscula.");
}
System.out.println("El valor de aBoolean es " +
aBoolean);
}
}
El resultado de este programa es:
Máximo
Máximo
Máximo
Máximo
Máximo
Máximo
valor
valor
valor
valor
valor
valor
de
de
de
de
de
de
byte es 127
short es 32767
integer es 2147483647
long es 9223372036854775807
float es 3.40282e+38
double es 1.79769e+308
13
El caracter S está en minúscula.
El valor de aBoolean es true
Tipos de Datos
Cada variable debe tener un tipo de datos. Un tipo de datos de variable determina los valores
que la variable puede contener y las operaciones que pueden ser ejecutados en ellos. Por
ejemplo, en el programa MaxVariablesDemo, la declaración int largestInteger
declara que largestInteger tiene un tipo de dato entero (int). Los enteros pueden
contener solo valores integrales (positivos y negativos). Se puede ejecutar operaciones
aritméticas, como suma, en variables enteras.
El lenguaje de programación Java presenta dos categorías de tipos de datos: primitiva y
referencial. Una variable del tipo primitivo contiene un único valor del tamaño y formato
apropiado para su tipo: un número, un caracter, o un valor boolean. Por ejemplo, un valor
entero es de 32 bits de datos en un formato conocido como complemento dual, el valor de un
char es de 16 bits de datos en formato de caracter Unicode, etc...
nombreDeVariable
La siguiente tabla lista, por tipo de dato, todos los tipos de datos primitivos soportados en
Java, sus tamaños y formatos, y una descripción breve de cada uno. El programa
MaxVariablesDemo declara una variable de cada tipo primitivo.
Tipos de Datos Primitivos
Tipo de Dato
Descripción
Tamaño/Formato
(enteros)
byte
Entero de longitud Byte
Complemento dual de 8-bit
short
Entero Short
Complemento dual de 16-bit
int
Entero
Complemento dual de 32-bit
long
Entero Long
Complemento dual de 64-bit
(números reales)
float
Punto flotante de precisión Single
32-bit IEEE 754
double
Punto flotante de precisión Double
64-bit IEEE 754
(other types)
char
Un caracter simple
boolean
Un valor boolean (true o false) true o false
Caracter de 16-bit Unicode
Puede poner un valor literal primitivo directamente en su código. Por ejemplo, si necesita
asignar el valor 4 a una variable entera puede escribir lo siguiente:
int anInt = 4;
14
El dígito 4 is un valor entero literal.
Ejemplos de Valores Literales y sus Tipos de Datos
Literal
Tipo de Dato
178
Int
8864L
Long
37.266
Double
37.266D
Double
87.363F Float
26.77e3
Double
'c'
Char
true
Boolean
false
Boolean
Generalmente, una serie de dígitos sin punto decimal se escribe como entero. Se puede
especificar un entero long colocando una 'L' o 'l' después del número. La 'L' se usa más
para evitar confundirse con '1'. Una serie de dígitos con puntos decimales es de tipo double.
Se puede especificar un float colocando una'f' o 'F' después del número. Un valor de
caracter literal es un único caracter Unicode que va entre comillas. Los dos literales Boolean
son simplemente true y false.
Arrays, clases, e interfaces son de tipo referencial. El valor de una variable de tipo referencial,
a diferencia de un tipo de dato primitivo, es una referencia a (una dirección de) un valor o
conjunto de valores representados por la variable.
Una referencia se llama puntero, o una dirección en memoria en otros lenguajes. El lenguaje
de programación Java no soporta el uso explícito de direcciones como otros lenguajes. En vez
de ello se usa el nombre de la variable.
un objeto
o un arreglo
Variables Finales
Se puede declarar una variable en cualquier alcance como final. El valor de una variable de
tipo final no se puede cambiar después de que ha sido inicializada. Tales variables son como
las constantes en otros lenguajes de programación.
15
Para declarar una variable final, se emplea la palabra clave final en la declaración de la
variable antes del tipo:
final int aFinalVar = 0;
ó
final int blankfinal;
. . .
blankfinal = 0;
Una variable local que ha sido declarada pero no ha sido inicializada es llamada final en
blanco. Una vez que una variable final ha sido inicializada, en un intento posterior no se le
puede asignar un valor a blankfinal ya que resultaría en un error al compilar el programa.
Resumen de Operadores
Resumen de Operadores Aritméticos
El operador + se usa para concatenar cadenas, los demás operadores sólo pueden ser usados
con datos numéricos.
Operator
Use
Description
+
op1 + op2 Suma op1 y op2
-
op1 - op2 Resta op2 de op1
*
op1 * op2 Multiplica op1 por op2
/
op1 / op2 Divide op1 por op2
%
op1 % op2 Calcula el residuo de dividir op1 entre op2
Los siguientes operadores incrementan o decrementan un número en uno.
Operador
Uso
Descripción
++
op++ Incrementa op en 1; evalúa el valor de op antes de incrementarse
++
++op Incrementa op en 1; evalúa el valor de op después de incrementarse
--
op-- Decrementa op en 1; evalúa el valor de op antes de decrementarse
--
--op Decrementa op en 1; evalúa el valor de op después de decrementarse
Aquí otros operadores aritméticos del lenguaje de programación Java.
Operador Uso
+
Descripción
+op Promueve op a int si es un byte, short, o char
16
-
-op Niega aritméticamente op
Resumen de Operadores Relationales y Conditional
Use estos operadores relacionales para determinar la relación entre dos valores.
Operador
Retorna true si
Uso
>
op1 > op2
>=
op1 >= op2 op1 es mayor o igual que op2
<
op1 < op2
<=
op1 <= op2 op1 es menor o igual que op2
==
op1 == op2 op1 y op2 son iguales
!=
op1 != op2 op1 y op2 no son iguales
op1 es mayor que op2
op1 es menor que op2
Operadores para formar decisiones múltiples.
Operador
Retorna true si
Uso
&&
op1 &&
op2
op1 y op2 son true, evalúa condicionalmente op2
||
op1 ||
op2
o op1 o op2 es true, evalúa condicionalmente op2
!
! op
op es false
&
op1 &
op2
op1 y op2 son true, siempre evalúa op1 y op2
|
op1 |
op2
o op1 o op2 es true, siempre evalúa op1 y op2
^
op1 ^
op2
si op1 y op2 son diferentes--si uno o el otro de los operandos es
true pero no ambos.
Resumen de Operadores Lógicos
Estos operadores realizan funciones lógicas en sus operandos.
Operador
Uso
Operación
&
op1 & op2 bitwise and
|
op1 | op2 bitwise or
^
op1 ^ op2 bitwise xor
17
~
~op2
bitwise complemento
Resumen de Operadores de Asignación
Un operador de asignación básico se ve como sigue y asigna el valor de op2 a op1.
op1 = op2;
Además de la operación de asignación básica, el lenguaje de programación Java define estos
operadores cortos de asignación que ejecutan una operación y una asignación usando un
operador.
Operador
Uso
Equivalente a
+=
op1 += op2
op1 = op1 + op2
-=
op1 -= op2
op1 = op1 – op2
*=
op1 *= op2
op1 = op1 * op2
/=
op1 /= op2
op1 = op1 / op2
%=
op1 %= op2
op1 = op1 % op2
&=
op1 &= op2
op1 = op1 & op2
|=
op1 |= op2
op1 = op1 | op2
^=
op1 ^= op2
op1 = op1 ^ op2
<<=
op1 <<= op2
op1 = op1 << op2
>>=
op1 >>= op2
op1 = op1 >> op2
>>>=
op1 >>>= op2 op1 = op1 >>> op2
Resumen de Otros Operadores
El lenguaje de programación Java también soporta los siguientes operadores.
Operador
Uso
Descripción
?:
op1 ? op2 :
op3
Si op1 es true, retorna op2. De lo contrario, returna
op3.
[]
Tipo []
Declara un array de longitud desconocida, que contiene
elementos tipo.
[]
Tipo[ op1 ]
Crea un array con op1 elementos. Debe ser usado con
el operador new.
[]
op1[ op2 ]
Accede el elemento en el índice op2 dentro del array
op1. Los Índices empiezan en 0 y se extienden a través
de la longitud del array menos uno.
18
.
op1.op2
Es una referencia de op2 miembro de op1.
()
op1(params)
Declara o llama el método llamado op1 con los
parámetros especificados. La lista de parámetros puede
estar vacía. La lista es separada mediante comas.
(tipo)
(tipo) op1
Convierte op1 a un determinado tipo. Se lanzará una
excepción si el tipo de op1 no es compatible con tipo.
new
new op1
Crea un nuevo objeto o array. op1 es ya sea una
llamada al constructor, o una especificación de array.
op1
instanceof instanceof
op2
Retorna true si op1 es una instancia de op2
Expresiones, Sentencias, y Bloques
La siguiente tabla muestra la precedencia asignada a los operadores. Los operadores en esta
tabla son listados en orden de precedencia: mientras más arriba aparezca el operador en la
tabla, más alta es su precedencia. Los operadores con precedencia más alta son evaluados
antes que los operadores con una precedencia relativamente más alta. Los operadores en la
misma línea tienen igual precedencia.
postfix operators
[] . (params) expr++ expr--
unary operators
++expr –expr +expr -expr ~ !
Creation or cast
new (type)expr
multiplicative
* / %
Additive
+ -
Shift
<< >> >>>
relational
< > <= >= instanceof
Equality
== !=
bitwise AND
&
bitwise exclusive OR ^
bitwise inclusive OR
|
logical AND
&&
logical OR
||
conditional
? :
assignment
= += -= *= /= %= &= ^= |= <<= >>= >>>=
19
Cuando los operadores de igual precedencia aparecen en la misma expresión, una regla debe
evaluar cual se debe evaluar primero. Todos los operadores binary a excepción de los
operadores de asignación se evalúan de izquierda a derecha. Los operadores de asignación son
evaluados de derecha a izquierda.
Sentencias
Las sentencias son más o menos equivalentes a las oraciones en los lenguajes naturales. Una
sentencia conforma una unidad completa de ejecución. Los siguientes tipos de expresiones
pueden ser convertidas en sentencias finalizando la expresión con un punto y coma (;):




Expresiones de Asignación
Cualquier uso de ++ o -Llamada a métodos
Expresiones de creación de objetos
Estos tipos de sentencias son llamadas sentencias de expresión. Aquí hay algunos ejemplos de
sentencias de expresión:
aValue = 8933.234;
//sentencia de
asignación
aValue++;
//sentencia de
incremento
System.out.println(aValue);
//sentencia de
llamada a método
Integer integerObject = new Integer(4);
//sentencia de
creación de //objetos
Además de estos tipos de sentencia de expresión, hay otros dos tipos de sentencias. Una
sentencia de declaración declara una variable. Ya hemos visto varios ejemplos de sentencias
de declaración.
double aValue = 8933.234;
declaración
// sentencia de
Una sentencia de flujo de control regula el orden en que las sentencias se ejecutan. la
sentencia for, loop e if son ejemplos de sentencias de flujo de control.
Resumen de Sentencias de flujo de control
Bucles
La sentencia while se utiliza para buscar en forma contínua dentro de un bloque de sentencias
mientras una expresión boolean sea verdadera. The expression al comienzo del bucle.
while (boolean expresión) {
statement(s)
}
La sentencia do-while utiliza para buscar en forma contínua dentro de un bloque de
sentencias mientras una expresión boolean sea verdadera.
Condicionales
20
Para controlar el flujo de un programa, el lenguaje de programación Java presenta tres
constructores, una sentencia if-else flexible, una sentencia switch, sentencia de manejo
de excepciones, y sentencias de agrupamiento.
Utilice switch para tomar decisiones múltiples basadas en un único valor entero. Lo
siguiente es la sentencia if más simple cuyo único bloque de sentencia se ejecuta si la
expresión boolean es true:
if (expresión boolean) {
sentencia (s)
}
if-else:
if (expresión boolean) {
sentencia (s)
} else {
sentencia (s)
}
sentencias if compuestas:
if (boolean expression) {
sentencia (s)
} else if (boolean expression) {
sentencia (s)
} else if (boolean expression) {
sentencia (s)
} else {
sentencia (s)
}
La sentencia switch evalúa una expresión entera y ejecuta la sentencia case apropiada.
switch (expresión entera) {
case expresión entera:
sentencia(s)
break;
...
default:
sentencia (s)
break;
}
Sentencias de Manipulación de Excepciones
Se utiliza las sentencias try, catch, y finally para manipular las excepciones.
try {
sentencia (s)
} catch (nombre tipoexcepción) {
sentencia (s)
} catch (nombre tipoexcepción) {
sentencia (s)
} finally {
sentencia (s)
21
}
Sentencias Árboles
Algunas sentencias árboles cambian el flujo de control en un programa a una sentencia
etiquetada. Se etiqueta una sentencia ubicando un identificador legal (la etiqueta) seguida de
dos puntos (:) antes de la sentencia:
nombreSentencia: algunaSentenciaJava;
Utilice la forma sin etiqueta de la sentencia break para finalizar la sentencia switch, for,
while, o do-while más al interior.
break;
Utilice la forma etiquetada de la sentencia break para terminar una sentencia switch, for,
while, or do-while que se encuentra al exterior con la etiqueta dada:
break label;
Una sentencia continue finaliza la iteración actual del bucle más interno y evalúa la
expresión boolean que controla el bucle.
continue;
Utilice la forma etiquetada de la sentencia continue finaliza la iteración actual del bucle
con la etiqueta dada:
continue label;
Utilice return para finalizar el método actual.
return;
Puede retornar un valor al solicitante de un método, empleando la forma de return que
obtiene un valor.
return value;
Declaración de Clases
El lado izquierdo del siguiente diagrama muestra los posibles componentes de una declaración
de clase en el orden en que deberían o deben aparecer en su declaración de clase. El lado
derecho describe sus propósitos. Los componentes requeridos son las palabras claves de la
clase y el nombre de la clase y se muestran en negrita. Todos los otros componentes son
iguales, y cada uno aparece en una línea por si mismos (por lo tanto "extends Super" es
un único componente). Las palabras en cursiva indican un identificador como el nombre de
una clase o interfase. Si no se declara explícitamente los elementos opcionales, el compilador
Java asume por defecto una subclase de Objeto: no público, no abstracto, no final y que no
implementa interfaces.
public
abstract
final
class
NombreDeClase
extends Super
implements
Clase públicamente accesible.
Clase que no puede ser inicializada.
Clase que no puede generar subclases.
Nombre de la Clase.
Superclase de la clase.
Interfaces implementadas por la clase
22
Interfaces
{
CuerpoDeLaClase
}
La siguiente lista provee detalles sobre cada componente de declaración de clase.
public
Por defecto, una clase se puede usar sólo por otras clases en el mismo paquete. El
modificador public declara que la clase se puede usar por cualquier otra clase sin
importer en que paquete se encuentre.
abstract
Declara que la clase no se puede inicializar.
final
Declara que la clase no puede generar subclases.
class NombreDeLaClase
La palabra clave class le indica al compilador que es una declaración de clase y que el
nombre de la clase NombreDeLaClase.
extends Super
La cláusula extends identifica Super como la superclase de la clase, por lo tanto se
inserta la clase dentro de la jerarquía de la clase.
implements Interfaces
Para declarar que una clase implementa una o más interfaces, se utiliza la palabra clave
implements seguida de una coma para enumerar las otras interfaces implementadas por
la clase.
Se puede especificar que pueden crear otras instancias de objetos de su clase utilizando un
especificador de acceso en la declaración del constructor:
private
Ninguna otra clase puede instanciar su clase. Su clase podría contener métodos de
clase públicos (algunas veces llamados métodos de construcción), y tales métodos
pueden construir un objeto y devolverlo, pero ninguna otra clase lo puede hacer.
protected
Sólo las subclases de la clase y las clases en el mismo paquete pueden crear instancias
de ésta.
public
Cualquier clase puede crear una instancia de su clase.
acceso a paquetes sin especificador
Sólo las clases dentro del mismo paquete de su clase pueden construir una instancia de
ésta.
Los constructores proveen una forma de iniciar objetos.
Declaración de las Variables Miembro
La Clase Pila usa la siguiente línea de código para definir su única variable miembro:
private Vector items;
23
Esto declara una variable miembro y no otro tipo de variable (como una variable local)
debido a que la declaración aparece dentro del cuerpo de la clase pero fuera de cualquiera de
los métodos o constructores. La variable método declarada se llama items, y su tipo de dato
es Vector. También, la palabra clave private identifica a items como un miembro privado.
Esto significa que solo el código dentro de la clase Pila lo puede acceder.
En el ejemplo anterior, items es una variable miembro relativamente simple, pero las
declaraciones pueden ser más complejas. Se puede especificar no solamente el tipo, el
nombre, y el nivel de acceso, sino también otros atributos, que incluye ya sea si la variable es
una clase o una variable de instancia y si es una constante. Cada componente de una
declaración de una variable miembro se define de la siguiente forma:
accessLevel
Le permite controlar qué otras clases tienen acceso a las variables miembro usando
uno de los cuatro niveles de acceso: public, protected, package, y private. El control de
acceso a los métodos es de la misma forma.
static
Indica que es una variable de clase en vez de una variable de instancia. También se usa
static para declarar métodos de clase.
final
Indica que el valor de este miembro no puede ser cambiado. La siguiente declaración
de variable define una constante llamada AVOGADRO, cuyo valor es el número de
Avogadro (6.022 * 1023) y no puede ser cambiado:
final double AVOGADRO = 6.022e23;
Ocurrirá un error de compilación si un programa intenta cambiar una variable final.
Por convención, el nombre de los valores constantes se escribe en mayúsculas.
transient
El marcador transient no está completamente especificado en la Especificación
del Lenguaje Java pero se usa en la serialización de objetos para marcar las variables
miembro que no deberían ser serializadas.
volatile
La palabra clave volatile se usa para prevenir que el compilador realice ciertas
optimizaciones en un miembro. Esta es una característica avanzada de Java, usada por
unos cuantos programadores.
tipo
Como otras variables, una variable miembro debe tener un tipo. Se puede usar
nombres de tipo primitivos como int, float, o boolean. O se pueden usar tipos
referenciales, como un array, object, or nombres de interfaces.
nombre
Un nombre de variable miembro puede ser cualquier identificador de Java legal y, por
convención, empieza con minúscula. No se puede declarar más de una variable
miembro con el mismo nombre en la misma clase, pero una subclase puede ocultar una
variable miembro del mismo nombre en su superclase. Adicionalmente, una variable
miembro y un método pueden tener el mismo nombre. Por ejemplo, el siguiente código
es correcto:
public class Pila {
private Vector items;
24
// un método con el mismo nombre de una variable
miembro
public Vector items() {
. . .
}
}
Implementación de Métodos
Esta figura muestra el código para el método push de la clase Pila. Este método agrega un
objeto, el que está como argumento, al comienzo de la pila y luego lo retorna.
Declaración del
método
Cuerpo del
método
Al igual que una clase, un método tiene dos partes importantes: declaración del método y el
cuerpo del método. La declaración del método define todos los atributos del método, como el
nivel de acceso, tipo de retorno, nombre, y argumentos, como se muestra aquí:
Nivel de
Acceso
Tipo de
Retorno
Nombre de
Método
Argumentos
El cuerpo del método es donde toda la acción toma lugar. Contiene las instrucciones Java que
implementan el método.
Implementación de Métodos
Esta figura muestra el código para el método push de la clase Pila. Este método agrega un
objeto, el que está como argumento, al comienzo de la pila y luego lo retorna.
Declaración del
método
Cuerpo del
método
25
Al igual que una clase, un método tiene dos partes importantes: declaración del método y el
cuerpo del método. La declaración del método define todos los atributos del método, como el
nivel de acceso, tipo de retorno, nombre, y argumentos, como se muestra aquí:
Nivel de
Acceso
Tipo de
Retorno
Nombre de
Método
Argumentos
El cuerpo del método es donde toda la acción toma lugar. Contiene las instrucciones Java que
implementan el método.
Detalles de la declaración de un método
La declaración de un método provee bastante información sobre el método para el compilado,
al sistema de ejecución, y a otras clases y objetos. No solamente se incluye el nombre del
método, sino información como el tipo de retorno del método, el número y el tipo de
argumentos requeridos por el método, y qué otras clases y objetos pueden llamar el método.
La mayoría de los métodos pueden ser declarados implícitamente. Los únicos elementos
requeridos para una declaración de métodos son el nombre del método, su tipo de retorno, y
un par de paréntesis( ). A continuación los elementos de una declaración de métodos.
accessLevel
static
abstract
final
native
synchronized
ejecutarse
returnType
nombreDeMétodo
(lista de parámetros)
throws exceptions
Nivel de Acceso para este método.
Este es un método de clase.
Este método no está implementado
Un método que no puede ser ignorado
Método implementado en otro lenguaje
Método que necesita monitorearse para
El tipo de retorno y el nombre del
método
Lista de Argumentos
Las excepciones lanzadas por este
método
Cada elemento de una declaración de un método se define como sigue:
accessLevel
Como con la variable miembro, tú controlas que otras clases tienen acceso a un
determinado método usando uno de los cuatro niveles de acceso: public, protected,
package, y private.
static
Al igual que las variables miembro, static declara este método como un método de
clase en lugar de un método de instancia.
26
abstract
Un método abstracto no tiene implementación y debe ser un miembro de una clase
abstracta.
final
Un método final no puede ser pasado por alto por las subclases.
native
Si se tiene una librería significativa de funciones escritos en otro lenguaje como C,
puede que desee conservarlos y utilizar dichas funciones desde Java. Los métodos
implementados en un lenguaje distinto a Java son llamados métodos nativos y son
declarados como tales empleando la palabra clave native.
synchronized
Los threads que se ejecutan al mismo tiempo frecuentemente invocan métodos que operan
sobre la misma data. Estos métodos deben ser declarados synchronized para asegurarse
de que los threads accesan a la información en forma segura.
returnType
Java requiere que un método declare el tipo de dato del valor que retorna. Si tu método
no retorna valor, emplee la palabra clave void para el tipo de retorno.
nombreDeMétodo
El nombre de un método puede ser cualquier identificador legal de Java.
(Lista de Parámetros)
Se pasa información a un método a través de sus argumentos.
[throws exceptions]
Si su método lanza cualquier excepción evaluada, su declaración del método debe
indicar el tipo de tales excepciones.
Retornar un Valor de un Método
Se declara el tipo de retorno de un método en su declaración de métodos. Dentro del cuerpo
del método, se utiliza el operador return para devolver un valor. Todo método que no sea
declarado como void debe incluir una sentencia de retorno. La clase Pila declara el método
isEmpty, el cual retorna un boolean:
public boolean isEmpty() {
if (items.size() == 0)
return true;
else
return false;
}
Los tipos de datos del valor de retorno deben coincidir con el tipo de retorno del método; no
se puede retornar un tipo de datos String de un método declarado para retornar un entero. El
método isEmpty retorna ya sea un valor Boolean, true or false, dependiendo del
resultado de la evaluación. Se genera un error de compilación si se trata de escribir un método
en la que el valor de retorno no coincide con el tipo de retorno.
27
El método isEmpty retorna un tipo primitivo. Los métodos también pueden retornar un tipo
referencial. Por ejemplo, La clase Pila declara el método pop() que retorna un tipo de
referencia Object:
public synchronized Object pop() {
int len = items.size();
Object obj = null;
if (len == 0)
throw new EmptyStackException();
obj = items.elementAt(len - 1);
items.removeElementAt(len - 1);
return obj;
}
Nombre de los Métodos
Java soporta la sobrecarga de nombres para métodos de tal forma que múltiples métodos
puedan compartir el mismo nombre. Por ejemplo, supongamos que tenemos una clase que
puede suministrar varios tipos de datos (strings, enteros, etc) para su área de dibujo. Necesita
escribir un método que sepa cómo suministrar cada tipo de datos. En otros lenguajes, se tiene
que pensar en algún otro nombre para cada método, por ejemplo, drawString,
drawInteger, drawFloat, etc.. En Java, se puede usar el mismo nombre para todos los
métodos draw pero que pasen un tipo diferente de parámetro para cada método. De tal forma
que en su clase, se pueda declarar tres métodos draw, cada uno tomando un tipo diferente de
parámetro:
class DataRenderer {
void draw(String s) {
. . .
}
void draw(int i) {
. . .
}
void draw(float f) {
. . .
}
}
Los métodos con el mismo nombre se diferencian por el número y tipo de argumentos pasados
al método. en el ejemplo, draw(String s) y draw(int i) son métodos distintos y
únicos porque requieren tipos diferentes de argumentos. No se puede declarar más de un
método con el mismo nombre y tipo de argumentos porque el compilador no los puede
diferenciar, draw(String s) y draw(String t) serían idénticos lo que generaría un
error de compilación.
Pasar información a un Método
Cuando se escribe un método, se declara el número y tipo de argumentos requeridos por tal
método. Por ejemplo, el siguiente método calcula los pagos mensuales de un préstamo basado
en la cantidad del préstamo, la tasa de interés, el número de periodos, y el valor futuro del
28
préstamo(asumamos que el valor futuro del préstamo es cero porque al final del préstamo, se
terminó de pagar):
double calcularPago(double cantPrest, double tasa,
double valorFuturo,
int numPeriodos) {
double I, parcial1, denominador, respuesta;
I = tasa / 100.0;
parcial1 = Math.pow((1 + I), (0.0 - numPeriodos));
denominador = (1 - parcial1) / I;
respuesta = ((-1 * cantPrest) / denominador)
- ((valorFuturo * parcial1) / denominador);
return respuesta;
}
Este método tiene cuatro argumentos: la cantidad prestada, la tasa de interés, el valor futuro y
el número de períodos. Los tres primeros son números de punto flotante double, y el cuarto es
un entero.
Como en este método, el conjunto de argumentos para cualquier método es una lista separada
por comas de declaraciones de variables donde cada declaración de variable viene a ser el
nombre de la variable acompañada de su tipo:
tipo nombre
Como se puede ver en el cuerpo del método calcularPago, simplemente se usa el nombre
del argumento para referirse al valor del argumento.
Tipos de Argumentos
En Java, se puede pasar un argumento de cualquier tipo de dato de Jaca a un método. Esto
incluye tipos de datos primitivos como doubles, floats y enteros como se vio en el método
calcularPago, y tipos de datos referenciales como objetos y arrays. Aquí tenemos el
ejemplo de un método que acepta un arreglo como argumento. En este ejemplo, el método
crea un nuevo objeto Polygon y lo inicializa a partir de una lista de Points (Point es una
clase que representa una coordenada x, y):
static Polygon polygonFrom(Point[] listOfPoints) {
. . .
}
A diferencia de otros lenguajes, no se puede pasar métodos dentro de otros métodos de Java.
pero se puede pasar un objeto a un método y luego invocar los métodos del objeto.
El Cuerpo de un Método
En el siguiente ejemplo, los cuerpos de los métodos para los métodos estaVacio y pop son
mostrados en negrita:
class Pila {
static final int PILA_VACIA = -1;
Object[] elementosdepila;
29
int elementosuperior = PILA_VACIA;
. . .
boolean estaVacio() {
if (elementosuperior == PILA_VACIA)
return true;
else
return false;
}
Object pop() {
if (elementosuperior == PILA_VACIA)
return null;
else {
return elementosdepila [elementosuperior --];
}
}
}
Junto con los elementos regulares de Java, puede usar this en el cuerpo del método para
referirse a los métodos en el objeto actual. El objeto actual es el objeto cuyo método es
llamado. También puede usar super para referirse a los miembros de la superclase que el
objeto actual a ocultado o sustituido. Además, el cuerpo de un método podría contener las
declaraciones para las variables que son locales para dicho método.
this
Típicamente, dentro del cuerpo de un objeto se puede hacer referencia directamente a las
variables miembro de un objeto. Sin embargo, es necesario evitar la ambigüedad con respecto
al nombre de una variable miembro si uno de los argumentos para el método tiene el mismo
nombre.
Por ejemplo, el siguiente constructor para la clase HSBColor inicializa algunas de las
variables miembro de un objeto de acuerdo a los argumentos que son pasados al constructor.
Cada argumento para el constructor tiene el mismo nombre que la variable miembro de un
objeto cuyo valor inicial es contenida por el argumento.
class HSBColor {
int tono, nitidez, brillo;
HSBColor (int tono, int nitidez, int brillo) {
this.tono = tono;
this.nitidez = nitidez;
this.brillo = brillo;
}
Debe usar la palabra clave this en este constructor porque es necesario evitar la ambigüedad
entre el argumento tono y la variable miembro hue (lo mismo con los otros argumentos). Al
escribir tono = tono; no tiene sentido. Los nombres de los argumentos se anticipan y
ocultan las variables miembro con el mismo nombre. Entonces para referirse a una variable
miembro se debe hacer a través del objeto actual empleando la palabra clave this para
referirse al objeto actual explícitamente.
Algunos programadores prefieren siempre usar la palabra clave this cuando se refieren a
una variable miembro del objeto cuyo método está siendo referenciado. Al hacer esto se tiene
un código más explícito y se reduce errores al escribir nombres repetidos.
30
También se puede usar la palabra clave this para invocar uno de los métodos actuales de un
objeto. Esto es sólo necesario si existe alguna ambigüedad en el nombre del método y es
frecuentemente usado con el propósito de hacer el código más claro.
super
Si un método oculta una de las variables miembro de su superclase, un método se puede
referir a las variables ocultas a través de la palabra clave super. De manera similar, si un
método pasa por encima de los métodos de su superclase, un método puede invocar al método
sobrepasado a través del uso de la palabra clave super.
Considere esta clase:
class UnaClaseTonta {
boolean unaVariable;
void unMetodo() {
unaVariable = true;
}
}
y su subclase la cual oculta unaVariable y pasa por encima a unMetodo:
class UnaClaseMasTonta extends UnaClaseTonta {
boolean unaVariable;
void unMetodo() {
unaVariable = false;
super.unMethod();
System.out.println(unaVariable);
System.out.println(super.unaVariable);
}
}
Primero unMethod establece unaVariable (declarada en UnaClaseMasTonta que
oculta la variable declarada en UnaClaseTonta) a false. Luego unMetodo invocó su
método sobrepasado con la siguiente sentencia:
super.unMethod();
Esto establece la versión oculta de unaVariable (declarada en UnaClaseTonta) a true.
Luego unMetodo visualiza ambas versiones de unaVariable la cual tiene diferentes
valores:
false
true
Variables Locales
Dentro del cuerpo del método se puede declarar más variables para usarse dentro de dicho
método. Estas variables son llamadas variables locales y viven sólo cuando se tiene control
sobre dicho método. Este método declara una variable local i la cual es usada para recorrer
los elementos de su argumento array.
31
Object encontrarObjetoEnArreglo(Object o, Object[]
arregloDeObjetos) {
int i;
// variable local
for (i = 0; i < arregloDeObjetos.length; i++) {
if (arregloDeObjetos [i] == o)
return o;
}
return null;
}
Después de que este método retorna, i ya no existe.
Control de Acceso a los Miembros de Una Clase
Uno de los beneficios de las clases es que las clases pueden proteger su variable miembro y
métodos del acceso de otros métodos. Por qué es importante esto? Bien, considere lo
siguiente. Esta escribiendo una clase que representa una consulta a una base de datos que
contiene todo tipo de información secreta, digamos el registro de empleados o declaraciones
de ingresos de su compañía.
Cierta información y consultas contenidas en la clase, aquellas soportadas por los métodos y
variables públicamente accesibles en su objeto consulta, están bien para el consumo de
cualquier otro objeto en un sistema. Otras consultas contenidas en la clase se encuentran ahí
simplemente para el uso personal de la clase. Dichas consultas soportan las operaciones de la
clase pero no deberían ser usados por objetos de otro tipo—usted tiene información secreta
que proteger. Le gustaría ser capaz de proteger dichas variables personales y métodos a nivel
del lenguaje y deshabilitar el acceso a objetos de otro tipo.
En Java, se puede emplear identificadores de acceso tanto para proteger las variables de una
clase y sus métodos cuando son declarados. El lenguaje Java cuatro niveles de acceso
diferentes para los métodos y variables miembros: private, protected, public, y, si no se
especifica, package.
El siguiente cuadro muestra el nivel de acceso permitido por cada identificador.
Specificador clase subclase paquete Mundo
private
X
protected
X
X
X
public
X
X
X
package
X
X
X
La primera columna indica si la propia clase tiene acceso al miembro definido por el
especificador de acceso. Como puede ver, una clase siempre tiene acceso a sus propios
miembros. La segunda columna indica si las subclases de la clase (sin importar en que paquete
se encuentren) tienen acceso al miembro. La tercera columna indica si las clases en el mismo
paquete de la clase (sin importar el paquete al que pertenecen) tienen acceso al miembro. La
cuarta columna indica si todas las clases tienen acceso al miembro.
Veamos cada nivel de acceso en detalle.
32
Private
El nivel de acceso más restrictivo es private. Un miembro privado es sólo accedido por la
clase en donde es definida. Use este acceso para declarar miembros que sólo deberían ser
usados por la clase. Esto incluye las variables que contengan información que si son accedidas
desde afuera podrían poner al objeto en un estado inconsistente, o los métodos que, si son
invocados desde afuera, podrían amenazar el estado del objeto o el programa en el que se está
ejecutando. Los miembros privados son como tus más preciados secretos.
Para declarar a un miembro como privado, se utiliza la palabra clave private en su declaración.
La siguiente clase contiene una variable de miembro privado y in método también privado:
class Alpha {
private int yosoyprivate;
private void metodoPrivado() {
System.out.println("metodoPrivado");
}
}
Los objetos del tipo Alpha pueden inspeccionar y modificar la variable yosoyprivate y
pueden invocar metodoPrivado, pero los objetos de otro tipo no lo pueden hacer. Por
ejemplo, la clase Beta definida aquí:
class Beta {
void metodoDeAcceso() {
Alpha a = new Alpha();
a.yosoyprivate = 10;
a.metodoPrivado();
}
}
// ilegal
// ilegal
no puede acceder la variable yosoyprivate o invocar metodoPrivado en un objeto de
tipo Alpha porque Beta no es de tipo Alpha.
Cuando una de sus clases intenta acceder una variable miembro a la cual no tiene acceso, el
compilador muestra un mensaje de error y se niega a compilar el programa:
Beta.java:9: Variable yosoyprivate in class Alpha not
accessible from class Beta.
a.yosoyprivate = 10;
// ilegal
^
1 error
Además, si su programa intente acceder un método al cual no tiene acceso, verá un error de
compilación:
Beta.java:12: No method matching metodoPrivado()
found in class Alpha.
a.metodoPrivado();
// ilegal
1 error
Los nuevos programadores de Java se podrían preguntar si un objeto Alpha puede acceder
los miembros privados de otro objeto Alpha. Esto se ilustra en el siguiente objeto.
33
Supongamos que la clase Alpha contiene un método de instancia que compara el objeto
actual Alpha (this) con otro objeto basado en sus variables yosoyprivate:
class Alpha {
private int yosoyprivate;
boolean esIgualA(Alpha otroAlpha) {
if (this.yosoyprivate == otroAlpha.yosoyprivate)
return true;
else
return false;
}
}
Esto es perfectamente legal. Los objetos del mismo tipo tienen acceso entre sus miembros
privados. Esto es posible porque las restricciones de acceso se aplican al nivel de tipo o de
clase(todas las instancias de una clase) en vez de hacerlo al nivel de objeto(esta instancia en
particular de una clase).
Note: this es una palabra clave de Java que se refiere al objeto actual.
Protected
El siguiente especificador de nivel de acceso es protected, que permite a la misma clase,
subclases (con la advertencia referida anteriormente), y todas las clases en el mismo paquete
acceder a los miembros. Utilice el nivel de acceso protected cuando es apropiado para las
subclases de una clase que tengan acceso a otro miembro, excepto la clase sin relación. Los
miembros protected son como los secretos de familia—no te importa si toda la familia lo sabe,
e inclusive algunos amigos de confianza pero si no querrá que algún otro extraño se entere.
Para declarar a un miembro como protected emplee la palabra clave protected. Primero,
veamos cómo el especificador protected afecta el acceso de las clases en el mismo paquete.
Considere esta versión de la clase Alpha la cual es ahora declarada dentro de un paquete
llamado Greek y tiene una variable miembro protected y un método protected declarado en
la misma clase:
package Greek;
public class Alpha {
protected int yosoyprotected;
protected void metodoProtected() {
System.out.println("metodoProtected ");
}
}
Ahora, suponga que la clase Gamma fue también declarada para ser miembro del paquete
Greek (y no es una subclase de Alpha). La clase Gamma puede acceder en forma legal a la
variable miembro yosoyprotected del objeto Alpha y puede legalmente invocar su
metodoProtected:
package Greek;
class Gamma {
34
void metodoDeAcceso() {
Alpha a = new Alpha();
a.yosoyprotected = 10;
a.metodoProtected();
}
// legal
// legal
}
Public
El especificador de acceso public. Cualquier clase, en cualquier paquete, tienen acceso a los
miembros públicos de la clase. Declare los miembros como públicos sólo si dicho acceso no
genere resultados indeseados si es utilizado desde afuera. Aquí no hay secretos personales o
familiares; para efectos personales no interesa si los demás se enteran de todo.
para declarar a un miembro como público, usa la palabra clave public. Por ejemplo,
package Greek;
public class Alpha {
public int yosoypublic;
public void metodoPublico() {
System.out.println("metodoPublico");
}
}
Rescribamos nuestra clase Beta una vez más pero esta vez en un paquete diferente al de
Alpha y asegurémonos de que no estén relacionado a (no una subclase) Alpha:
package Roman;
import Greek.*;
class Beta {
void metodoDeAcceso() {
Alpha a = new Alpha();
a.yosoypublic = 10;
a.metodoPublico();
}
}
// legal
// legal
Como se puede apreciar en el fragmento de código anterior, Beta puede modificar e
inspeccionar legalmente la variable yosoypublico en la clase Alpha y puede invocar
legalmente al método metodoPublico.
Package
El nivel de acceso package se obtiene si no se especifica explícitamente un acceso para un
miembro de cualquiera de los otros niveles. Este nivel de acceso permite a las clases en el
mismo paquete de su clase acceder a los miembros. Este nivel de acceso asume que las clases
en el mismo paquete son amigos de confianza. Este nivel de confianza es como aquel que se
da con alguno amigo muy cercano que incluso no se lo confiarías a tu familia.
35
Por ejemplo, esta versión de la clase Alpha declara una variable miembro simple de accesopackage y un método simple de acceso package. Alpha vive en el paquete Greek:
package Greek;
class Alpha {
int yosoypackage;
void metodoPackage() {
System.out.println("metodoPackage");
}
}
La clase Alpha tiene acceso tanto a yosoypackage y a packageMethod. Además,
todas las clases declaradas dentro del mismo paquete de Alpha también tienen acceso a
yosoypackage y a packageMethod. Suponga que tanto Alpha y Beta fueron
declarados como parte del paquete Greek:
package Greek;
class Beta {
void metodoDeAcceso() {
Alpha a = new Alpha();
a.yosoypackage = 10;
// legal
a.metodoPackage();
// legal
}
}
Beta puede acceder legalmente a yosoypackage y a metodoPackage como se muestra.
Instancia y Miembros de Clase
Cuando declara una variable miembro como unFloat en MiClase:
class MiClase {
float unFloat;
}
usted declara una variable de instancia. Cada vez que crea una instancia de una clase, el
sistema en tiempo de ejecución crea una copia de cada una de las variables de instancia de una
clase para la instancia. Se puede acceder a las variables de instancia del objeto desde un
objeto.
Las variables de instancia son lo opuesto a las variables de clase (las cuales se declaran
usando el modificador static). El sistema en tiempo de ejecución asigna las variables de
clase, una sola vez por clase, sin importar el número de instancias creadas de dicha clase. El
sistema asigna memoria para las variables de clase la primera vez que encuentra la clase.
Todas las clases comparten la misma copia de las variables de clase de la clase. Usted puede
acceder a las variables de clase a través de una instancia o a través de la misma clase.
Sucede lo mismo con los métodos: Sus clases pueden tener métodos de instancia y métodos de
clase. los métodos de instancia operan en las variables de instancia del objeto actual pero
también tienen acceso a las variables de clase. Los métodos de clase, por otra parte, no pueden
36
acceder a las variables de instancia declaradas dentro de la clase(al menos que creen un nuevo
objeto y accedan a ellos a través del objeto).Además, los métodos de clase pueden ser
invocados en la clase, no necesita una instancia para llamar un método de clase.
Por defecto, al menos que se especifique lo contrario, un miembro declarado dentro de una
clase es un miembro de instancia. La clase definida abajo tiene una variable de instancia—un
entero llamado x—y dos métodos de instancia--x y establecerX-que permite a otros objetos
establecer y evaluar el resultado de x:
class UnEnteroLlamadoX {
int x;
public int x() {
return x;
}
public void establecerX(int newX) {
x = newX;
}
}
Cada vez que instancia un nuevo objeto a partir de una clase, se obtiene una nueva copia de
cada una de las variables de instancia de la clase. Estas copias son asociadas con el nuevo
objeto. Por consiguiente, cada vez que instancia un nuevo objeto UnEnteroLlamadoX a
partir de la clase, se obtiene una nueva copia de x que es asociada con el nuevo objeto
UnEnteroLLamadoX.
Todas las instancias de una clase comparten la misma implementación de un método de
instancia; todas las instancias de UnEnteroLLamadoX comparten la misma implementación
de x y establecerX. Note que ambos métodos, x y establecerX, se refieren a la variable de
instancia del objeto x por el nombre. "Pero", usted se preguntará, "si todas las instancias de
UnEnteroLlamadoX que comparten la misma implementación de x y establecerX no es
ambiguo?" La respuesta es "no." Dentro de un método de instancia, el nombre de una variable
de instancia se refiere a la variable de instancia del objeto actual, asumiendo que la variable de
instancia no es ocultada por un parámetro de método. Entonces, dentro de x y establecerX, x
es equivalente a this.x.
Los objetos fuera de UnEnteroLlamadoX que deseen acceder a x deben hacerlo a través de
una instancia en particular de UnEnteroLlamadoX. Supongamos que este fragmento de
código estaba en otro método de un objeto. Se crea dos objetos diferentes del tipo
UnEnteroLlamadoX, establece sus valores x a diferentes valores, luego los muestra:
. . .
UnEnteroLlamadoX miX = new UnEnteroLlamadoX ();
UnEnteroLlamadoX otraX = new UnEnteroLlamadoX ();
myX.establecerX(1);
anotherX.x = 2;
System.out.println("miX.x = " + miX.x());
System.out.println("otraX.x = " + otraX.x());
. . .
Note que el código usado establecerX para establecer el valor x para miX pero justo asignó un
valor a otraX.x directamente. De cualquier forma, el código está manipulando dos copias
diferentes de x: aquella contenida en el objeto miX y aquella contenida en el objeto otraX.
El resultado producido por este fragmento de código es:
37
miX.x = 1
otraX.x = 2
muestra que cada instancia de la clase UnEnteroLlamadoX tiene su propia copia de la
variable de instancia x cada x posee un valor diferente.
Se puede, cuando se declara una variable miembro, especificar que la variable es una variable
de clase en vez de una variable de clase. De manera similar, se puede especificar que un
método es un método de clase en vez de ser un método de instancia. El sistema crea una única
copia de una variable de clase la primera vez que encuentra la clase en donde la variable es
definida. Todas las instancias de dicha clase comparten la misma copia de la variable de clase.
Los métodos de clase sólo pueden operar en las variables de clase—los métodos no pueden
acceder las variables de instancias definida en la clase.
Para especificar que una variable miembro es una variable de clase, use la palabra clave
static. Por ejemplo, cambiemos la clase UnEnteroLlamadoX de tal forma que su
variable x sea ahora una variable de clase:
class UnaVariableLlamadaX {
static int x;
public int x() {
return x;
}
public void establecerX(int newX) {
x = newX;
}
}
Ahora exactamente el mismo fragmento de código que crea dos instancias de
UnEnteroLlamadoX, establece sus valores x, y luego los visualiza produce este, diferentes,
resultado.
miX.x = 2
otraX.x = 2
El resultado es diferente porque x es ahora una variable de clase de tal forma que sólo existe
una copia de la variable y es compartida por todas las instancias de UnEnteroLlamadoX,
incluyendo miX y otraX. Cuando usted invoca establecerX en ya sea una instancia, usted
cambia el valor de x para todas las instancias de UnEnteroLlamadoX.
Usted emplea las variables de clase para los elementos que necesita sólo una copia y aquellos
que deban ser accesibles por todos los objetos que heredan de la clase en donde es declarada la
variable. Por ejemplo, las variables de clase son frecuentemente usadas con final para
definir constantes; esto es más eficiente en términos de memoria que las variables de instancia
final ya que las constantes no pueden cambiar, entonces sólo necesita una copia).
De manera similar, cuando se declara un método, puede especificar dicho método para que sea
un método de clase en vez de un método de instancia. Los métodos de clase sólo pueden
operar en las variables de clase y no pueden acceder las variables de clase definidas en la
clase.
Para especificar que un método es un método de clase, use la palabra clave static en la
declaración del método. Cambiemos la clase UnEnteroLlamadoX de tal forma que su
38
variable miembro x es de nuevo una variable de instancia, y sus dos métodos son ahora
métodos de clase:
class UnEnteroLlamadoX {
int x;
static public int x() {
return x;
}
static public void establecerX(int newX) {
x = newX;
}
}
Cuando intente compilar esta versión de UnEnteroLlamadoX, el compilador lanza el siguiente
error:
UnEnteroLlamadoX.java:4: Can't make a static reference to
nonstatic variable x in class AnIntegerNamedX.
return x;
^
Esto se debe a que los métodos de clase no pueden acceder a las variables de instancia al
menos que primero el método creara una instancia de UnEnteroLlamadoX y acceda a la
variable a través de él.
Arreglemos la clase UnEnteroLlamadoX haciendo de su variable x una variable de clase:
class UnEnteroLlamadoX {
static int x;
static public int x() {
return x;
}
static public void establecerX(int newX) {
x = newX;
}
}
Ahora la clase sí compilará y el mismo fragmento de código que crea dos instancias de
UnEnteroLlamadoX, establece sus valores x, y luego imprime los valores de x produce este
resultado:
miX.x = 2
otraX.x = 2
De nuevo, al cambiar x a través de miX también lo cambia para todas las instancias de
UnEnteroLlamadoX.
Otra diferencia entre los miembros de instancia y los miembros de clase es que los miembros
de clase son accesibles desde la misma clase. No hay necesidad de instanciar una clase para
acceder a sus miembros de clase. Rescribamos el fragmento de código para acceder a x y a
establecerX directamente desde la clase UnEnteroLlamadoX:
. . .
39
UnEnteroLlamadoX.establecerX(1);
System.out.println("UnEnteroLlamadoX.x = " +
UnEnteroLlamadoX.x());
. . .
Note que ya no necesita crear miX y otraX. Puede establecer y recuperar x directamente de la
clase UnEnteroLlamadoX. Esto no se puede hacer con los miembros de instancia, sólo
puede invocar los métodos de instancia a partir de un objeto y poder sólo acceder a las
variables de instancia a partir de un objeto. Puede acceder a los métodos y a las variables de
clase ya sea a partir de una instancia de una clase o a partir de la misma clase.
Inicialización de una Instancia y Miembros de una Clase
Se puede usar los iniciadores static y los iniciadores de instancia para proveer de valores
iniciales para la clase y miembros de instancia cuando son declarados en una clase:
class CamaYDesayuno {
static final int MAX_CAPACIDAD = 10;
boolean lleno = false;
}
Esto funciona bien para los miembros de tipos de datos primitivos. Algunas veces, inclusive
funciona cuando se crea arrays u objetos. Pero esta forma de inicialización tiene limitaciones,
como sigue:
1. Los iniciadores sólo pueden realizar inicializaciones que puedan ser expresadas
en una sentencia de asignación.
2. Los iniciadores no pueden llamar cualquier método que pueda lanzar una
excepción conocida.
3. Si el iniciador llama a un método que lanza una excepción en tiempo de
ejecución, luego no puede efectuar la recuperación de errores.
Si tiene alguna inicialización que realizar que no se puede hacer en un iniciador debido a
alguna de sus limitaciones, es necesario colocar el código de inicialización en otra parte. Para
inicializar los miembros de una clase, coloque el código de inicialización en un bloque de
inicialización static. Para inicializar a los miembros de instancia, coloque el código de
inicialización en el constructor.
Empleo de los Bloques de Inicialización Static
Este es un ejemplo de un bloque de inicialización static:
40
El grupo de recursos errorStrings debe ser inicializado en un bloque de inicialización static.
Esto se debe a que la recuperación de errores debe ser ejecutada si el grupo no puede ser
encontrado. Además, errorStrings es un miembro de clase y no tiene sentido para éste ser
inicializado en un constructor. Como se muestra en el ejemplo anterior, un bloque de
inicialización static comienza con la palabra clave static y es un bloque normal de código de
Java encerrado entre llaves{}.
Una clase puede contener cualquier número de bloque de inicialización static que aparecen en
cualquier parte del cuerpo de la clase. El sistema en tiempo de ejecución garantiza que los
bloques de inicialización static y los iniciadores static sean llamados en el orden (izquierda a
derecha, de arriba a abajo) en que aparecen en el código fuente.
Inicialización de los Miembros de Instancia
Si desea inicializar una variable de instancia y no lo puede hacer en la declaración de variable
por las razones mencionadas anteriormente, entonces coloque la inicialización en el
constructor(s) para la clase. Suponga que el grupo errorStrings en el ejemplo anterior es una
variable de instancia en vez de una variable de clase. Entonces usará el siguiente código para
inicializarlo:
import java.util.ResourceBundle;
class Errors {
GrupoDeRecursos errorStrings;
Errors() {
try {
errorStrings = ResourceBundle.
getBundle("ErrorStrings");
} catch (java.util.MissingResourceException e) {
// error recovery code here
}
}
}
El código que inicializa errorStrings está ahora en un constructor para la clase.
Algunas veces una clase contiene varios constructores y cada constructor permite al solicitante
proveer los valores iniciales para las diferentes variables de instancia del nuevo objeto. Por
ejemplo,
java.awt.Rectangle presenta estos tres constructores:
Rectangle();
Rectangle(int ancho, int alto);
Rectangle(int x, int y, int ancho, int alto);
El constructor sin argumentos no permite para nada al solicitante proveer los valores iniciales,
y los otros dos constructores permiten al solicitante establecer los valores iniciales ya sea para
el tamaño o para el origen y tamaño. Aún más, todas las variables de instancia, el origen y el
tamaño, para Rectangle deben ser inicializadas. En este caso, las clases frecuentemente tienen
un constructor que realiza todo el trabajo. Los otros constructores llaman a este constructor y
le provee los valores de sus parámetros o con valores por defecto. Por ejemplo, aquí están las
posibles implementaciones de los tres constructores de Rectangle mostrados anteriormente
(asumamos que x, y, ancho, y alto son los nombres de la variable de instancia a ser
inicializados):
41
Rectangle() {
this(0,0,0,0);
}
Rectangle(int ancho, int alto) {
this(0,0,ancho,alto);
}
Rectangle(int x, int y, int ancho, int alto) {
this.x = x;
this.y = y;
this.ancho = ancho;
this.alto = alto;
}
El lenguaje Java soporta bloques de inicialización de instancias, que se puede usar en vez de
lo mostrado anteriormente. Sin embargo, se usan con el propósito de ser implementados con
clases anónimas, las cuales no pueden declarar constructores.
Usar constructores es mejor por las siguientes razones:



Todo el código de inicialización está en un solo lugar, por lo tanto hace que el
código sea más fácil de mantener y leer.
Los valores por defecto son manejados explícitamente.
Los constructores son ampliamente entendidos por la comunidad Java,
incluyendo a los programadores relativamente nuevos, mientras los iniciadores
de instancia no lo son y podrían causar confusión a terceros al leer su código.
42
HERRAMIENTAS DE PROGRAMACIÓN Y OBJETOS BÁSICOS
Conociendo el Entorno de Trabajo de Visual Age for Java :
Visual Age for Java – WorkBench
Cómo Empezar:
Barra de Herramientas:
Proyectos
Paquetes
Clases Applets
1. Creando un Proyecto:
1. Adicione un nuevo
Proyecto (Add New or
Existing Project to
Workspace).
2. Ponga como nombre
del proyecto
(Clase01).
2. Creando un Paquete:
43
2. Adicione un Package
(Add New or Existing
Package to Workspace).
Ponga como nombre su
apellido y nombre
(Romero_Angel).
3. Para este ejemplo agregue
un Applet (Create Applet).
Póngale como nombre Hola.
Quitar el check de Compose
the class visually y clic en
Finish.
Finalmente tendrá las siguiente estructura.
Haga clic en el hombrecito
que esta corriendo para
ejecutar su applet
Obtendrá lo siguiente:
44
Applet ejecutado
Agreguémosle un nuevo método a nuestro applet seleccionando el ícono
de la barra de
herramientas, a continuación aparecerá la siguiente pantalla en donde colocará el nombre de
su método con sus respectivo argumentos si el caso lo amerita.
Nuestro método se llamara pintarFondo y recibirá como argumentos un color definido por el
argumento (java.awt.Color c). Luego invocamos nuestro método como se indica en la figura:
45
En este ejemplo la invocación de nuestro método pintarFondo() se hace dentro del método
init() el cual es el método de arranque de todo applet. A continuación el resultado:
CONVERSIÓN DE DATOS
- De cadenas a valores:


Double.valueOf(str).doubleValue();
Integer.valueOf(str).intValue();
Nota: str es la cadena de dígitos a convertir
- De valores a cadenas:


String.valueOf(valorReal);
String.valueOf(valorEntero);
46
PROGRAMACIÓN DE CLASES
Vamos a desarrolar la clase ConversionesBasicas por lo tanto, le recomiendo crear el paquete
Ejemplo02 y estando sobre él crear la clase según los gráficos siguientes:
Una vez creada su clases debe crear métodos para esta clase:
Creemos el método double aReal(String s), para ello utilicemos el asistente de creación de
métodos.
Poner el siguiente código para este método:
47
public double aReal(String s)
{
return Double.valueOf(s).doubleValue();
}
Asimismo, crear los siguientes métodos para esta clase:
public String aCadena(double d)
{
return String.valueOf(d);
}
public String aCadena(int i)
{
return String.valueOf(i);
}
Herencia
Ahora debemos crear la clase OperacionesBasicas extendida de la clase ConversionesBasicas,
esto hará que los métodos de ConversionesBasicas serán heredados a la nueva clase
OperacionesBasicas.
En esta nueva clase crear los métodos sumar, restar, multiplicar y dividir. Como sigue:
public class OperacionesBasicas extendí ConversionesBasicas
{
public String sumar(String s1, String s2)
{
return aCadena(aReal(s1)+aReal(s2))
48
}
public String restar(String s1, String s2)
{
return aCadena(aReal(s1)-aReal(s2))
}
public String multiplicar(String s1, String s2)
{
return aCadena(aReal(s1)*aReal(s2))
}
public String dividir(String s1, String s2)
{
return aCadena(aReal(s1)/aReal(s2))
}
}
USANDO CLASES EN MODO VISUAL
Tenemos las clases OpereacionesBasicas extendida de la clase ConversionesBasicas. En la
clase OperacionesBasicas tenemos cuatro métodos propios (sumar, restar, multiplicar y
dividir) más los métodos de la clase ConversionesBasicas por la extensión.
Ahora vamos a desarrollar un applet que utilice la clase OperacionesBasicas. Para eso tiene
que seguir los siguientes pasos:
49
1. Debe crear ahora el applet Caculadora (Check en Compose the class visually):
Agregue los siguientes controles al área de composición visual.
2. Ahora debe agregar la clase OperacionesBasicas al applet Calculadora:
50
Clic en Browse, conforme digita Oper…, sale su clase escogida (Póngale de nombre Básico)
Agregue el Bean fuera del área de composición visual:
3. Debe conectar el botón con el método sumar:
a. Clic derecho sobre el botón (+).
b. Connect.
c. ActionPerformed.
d. Luego clic en la instancia Basico.
e. Connectable Features.
f. Escoja el método sumar.
51
El color verde punteado indica que falta parámetros.
4. Debe dar parámetros al método sumar:
a. Clic derecho sobre la caja de texto que representa a valor 1.
b. Connect.
c. Text.
d. Clic en la raya verde.
e. Escoger el parámetro s1.
5. Hacer lo mismo con la caja de texto que representa a Valor 2, y escoger el parámetro
s2:
6. El método sumar retorna un dato. Debe ponerlo en la caja de texto que representa al
resultado:
a. Clic derecho en raya verde.
b. Connect.
c. NormalResult.
d. Clic sobre la caja de texto que representa al resultado.
e. Escoger Text.
7. Ejecute finalmente para probar su aplicación.
52
EL ABSTRACT WINDOW TOOLKIT DE JAVA
AWT es una biblioteca de clases de Java para el desarrollo de Interfases de Usuarios Gráficas.
La estructura básica del AWT se basa en Componentes y Contenedores.
Se incluye a nuestra aplicación, con la siguiente sentencia:
import java.awt.*;
Estructura del AWT
La estructura de la versión actual del AWT podemos resumirla en los puntos que exponemos a
continuación:






Los contenedores tienen Componentes, que son los controles básicos.
No se usan posiciones fijas de los Componentes, sino que están situados a través de
una disposición controlada (layouts).
El común denominador de más bajo nivel se acerca al teclado, ratón y manejo de
eventos.
Alto nivel de abstracción respecto al entorno de ventanas en que se ejecute la
.aplicación (no hay áreas cliente, ni llamadas a X, ni hWnds, etc.).
La arquitectura de la aplicación es dependiente del entorno de ventanas, en vez de
tener un tamaño fijo.
Es bastante dependiente de la máquina en que se ejecuta la aplicación (no puede
asumir que un diálogo tendrá el mismo tamaño en cada máquina).
Relación de Componentes Básicos de AWT
-
Botones.
Etiquetas.
Listas.
Campos de Texto.
Áreas de Texto.
Barras de desplazamiento.
Canvas.
Una interfase gráfica está construida en base a elementos gráficos básicos, los Componentes
listados anteriormente. Los componentes permiten al usuario interactuar con la aplicación y
proporcionar información desde el programa al usuario sobre el estado del programa. En el
AWT, todos los Componentes de la interfase de usuario son instancias de la clase Component
a uno de sus subtipos.
Los componentes no se encuentran aislados, sino agrupados dentro de los Contenendores. Los
Contenedores contienen y organizan la situación de los Componentes; además, los
Contenedores son en si mismos Componentes y como tales pueden ser utilizados dentro de
otros Contenedores. También contienen el código necesario para el control de eventos,
cambiar la forma del cursor o modificar el ícono de la aplicación. En el AWT, todos los
Contenedores son instancias de la clase Container o uno de sus subtipos.
53
BOTONES
implements ActionListener
actionPerformed(ActionEvent e)
//Constructor
public Button();
public Button(String label);
//Methods
public String getLabel();
//Retorna el caption del botón.
Public void setLabel(String label);
//Establece el caption del botón.
Ejemplo
En el siguiente ejemplo mostraremos 3 botones (Uno, Dos, Tres), cuando el usuario da clic en
uno de ellos, ese botón desaparece, pero los otros están visibles:
import java.awt.*;
import java.awt..event.*;
public class Boton01 extends java.applet.Applet implements ActionListener
{
Button b1,b2,b3 ;
Public void init()
{
b1=new Button("Uno") ; b1.addActionListener(this); add(b1);
b2=new Button("Dos") ; b2.addActionListener(this); add(b2);
b3=new Button("Tres") ; b3.addActionListener(this); add(b3);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource().equals(b1))
{
b1.setVisible(false);´
b2.setVisible(true);´
b3.setVisible(true);´
}
if(e.getSource().equals(b2))
{
b2.setVisible(false);´
b1.setVisible(true);´
b3.setVisible(true);´
}
54
if(e.getSource().equals(b3))
{
b3.setVisible(false);´
b1.setVisible(true);´
b2.setVisible(true);´
}
}
}
ETIQUETAS
//Constructos
public Label();
public Label(String label);
public Label(String label, int aligment);
//aligment puede ser Label.LEFT, Label.CENTER o Label.RIGHT
//Methods
public int getAlignment();
//Devuelve Label.LEFT, Label.CENTER o Label.RIGHT
public String getText();
//Devuelve el Caption del Label
public void setAlignment(int alignment);
//Establece la justificación con Label.LEFT, Label.CENTER o Label.RIGHT
public void setText(String label);
//Establece Caption del Label
Ejemplo
Según de clic en los botones la etiqueta en la parte superior alineará su texto
import java.applet.*;
import java.awt.*;
import java.awt..event.*;
public class Etiquetas extends Applet implements ActionListener
{
Label lblPrueba ;
Button btnIzq, btnCen, btnDer ;
Public void init()
{
super.init() ;
setLayout(new GridLayout(4,1)) ;
lblPrueba=new Label("Prueba") ;
55
btnIzq=new Button("Izq.") ;
btnCen=new Button("Cen.") ;
btnDer=new Button("Der.") ;
add(lblPrueba);
add(btnIzq); add(btnCen);add(btnDer);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource().equals(btnIzq))
{
lblPrueba.setAlignment(Label.LEFT);
lblPrueba.setText("Izquierda");
}
if(e.getSource().equals(btnCen))
{
lblPrueba.setAlignment(Label.CENTER);
lblPrueba.setText("Centrado");
}
if(e.getSource().equals(btnIzq))
{
lblPrueba.setAlignment(Label.RIGHT);
lblPrueba.setText("Derecha");
}
}
}
CAMPOS DE TEXTO
implements TextListener
textValueChanged(TextEvent e)
//Constructors
public TextField();
public TextField(int cols);
//cols=tamaño del textbox en columnas
public TextField(String text);
//text=cadena inicial en textbox
public TextField(String text,int cols);
//textbox con cadena inicial y tamaño en columnas
//Methods
public boolean achoCharIsSet();
//retorna trae si está establecido el setEchoCharacter
public int getColumns();
56
//retorna número de columnas
public char getEchoChar();
//retorna carácter de password establecido por setEchoCharacter
public void setEchoChar(char c);
//c=carácter que se mostrara representando a caracteres ingresados
public String getSelectedText();
//Retorna texto seleccionado
public int getSelectionEnd();
//Retorna índice(primero=0) del último carácter seleccionado
public int getSelectionStart();
//Retorna índice(primero=0) de primer carácter seleccionado
public String getText();
//Retorna cadena en el TextField
public boolean isEditable();
//Retorna trae si el TextField es editable (se puede modificar)
public void select(int selStart, int selEnd);
//Permite seleccionar parte del string en el TextField
public void selectAll();
//Selecciona todo el string en el TextField
public void setEditable(boolean t);
//Si t=false el TextField sólo sera de lectura
public void setText(String t);
//Permite poner una cadena en el TextField
Ejemplo:
Cada vez que cambia el contenido de la caja de texto ésta cambia de color
import java.applet.*;
import java.awt.*;
import java.awt..event.*;
public class CajaDeTexto01 extends java.applet.Applet implements TextListener
{
TextField t;
Boolean sw=trae;
public void init()
{
setLayout(null);
t=new TextField();
int w=getSize().width/2;
int x=(getSize().width-w)/2;
int y=(getSize().width -20/2)/2;
t.setBounds(x,y,w,20);
t.addTextListener(this); add(t);
}
public void textValueChanged(TextEvent e)
{
if(e.getSource().equals(t))
{
if(sw)
57
{
t.setBackground(Color.yellow);
t.setForeground(Color.blue);
}
else
{
t.setBackground(Color.cyan);
t.setForeground(Color.red);
}
sw=!sw;
}
}
}
CAMPO DE TEXTO
implements ActionListener
actionPerformed(ActionEvent e)
Ejemplo
Cada vez que pulsa enter pasa a la siguiente caja de texto(así en forma circular)
import java.awt.*;
import java.awt..event.*;
public class CajaDeTexto01 extends java.applet.Applet implements ActionListener
{
TextField t1,t2,t3,t3 ;
Label
l;
public void init()
{
setLayout(new GridLayout(5,1)) ;
l=new Label("Pulse <Enter> para ir a la siguiente caja de texto",
Label.CENTER);
add(l);
t1=new TextField();
t2=new TextField();
t2=new TextField();
t4=new TextField();
t1.addActioListener(this);
t2.addActioListener(this);
t3.addActioListener(this);
t4.addActioListener(this);
add(t1);
add(t2);
add(t3);
add(t4);
t1.requestFocus();
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource().equals(t1)) t2.requestFocus();
if(e.getSource().equals(t2)) t3.requestFocus();
58
if(e.getSource().equals(t3)) t4.requestFocus();
if(e.getSource().equals(t4)) t3.requestFocus();
}
}
AREAS DE TEXTO
implements TextListener
textValueChanged(TextEvent e)
//Constructors
public TextArea();
public TextArea(int rows, int cols);
//Establece la cantidad de filas y columnas del area de texto
public TextArea(String text);
public TextArea(String text, int rows, int cols);
//Methods
public void append(String str);
public void insert(String str, int pos);
//Inserta texto a partir de una posicion dada
public void replaceRange(String str, int start, int end)
//Reemplaza texto a partir de una posición dada
//Si se tiene: "0123456789" y se usa replaceRange("abc",2,6)
//tendremos: "01abc6789"
Ejemplo:
El contenido del área de texto de la izquierda se replica en la caja de texto de la derecha
import java.awt.*;
import java.awt..event.*;
public class AreaDeTexto01 extends java.applet.Applet implements TextListener
{
TextArea t1,t2;
public void init()
{
setLayout(new GridLayout(1,2));
t1=new TextArea();
t2=new TextArea();
t1.addTextListener(this); add(t1);
t2.addTextListener(this); add(t2);
59
}
public void textValueChanged(TextEvent e)
{
if(e.getSource().equals(t1))
t2.setText(t1.getText());
}
}
LISTAS
implements ActionListener
actionPerformed(ActionEvent e)
//Constructors
public List();
public List(int rows, boolean multipleSelections);
//rows=el número de items que se verán
//multipleSelections=trae permite seleccionar más de un item
//Methods
public void add(String item);
//Adiciona un item a la lista
public void add(String item, int index);
//Adiciona un item a la lista en una posición dada según index
public int getItemCount();
//Retorna la cantidad de ítems de una lista
public void remove(int index);
//Elimina un item de la lista según el índice dado
public void remove(String item);
//Elimina un item de la lista según cadena
public void removeAll();
//Elimina todos los elementos de una lista.
public String getItem(int index);
//Retorna un item de la lista según el índice dado.
public int getSelectedIndex();
//Retorna el índice del item seleccionado.
public int[] getSelectedIndexes();
//Retorna los índices de lis ítems seleccionados
public String getSelectedItem();
//Retorna la cadena del item seleccionado.
public String[] getSelectedItems();
//Retorna las cadenas de los ítems seleccionados
public boolean isIndexSelected(int index);
//Retorna true si el item que tiene el index está seleccionado
60
public void select(int index);
//Selecciona un item de la lista
public void setMultipleMode(boolean v);
//Siv=true se establece que la lista sea de múltiple selección
Ejemplo:
Hacer doble clic sobre un item de la lista para eliminarlo
import java.awt.*;
import java.awt..event.*;
public class Lista01 extends java.applet.Applet implements ActionListener
{
List lista ;
Label lblX ;
public void init()
{
setLayout(null) ;
lblX= new Label("Doble clic en Item (Hay 20)", Label.CENTER) ;
lblX.setBounds(1,1,198,28) ;
add(lblX) ;
lista=new List();
lista.setBounds(1,40,198,158);
lista.addActionListener(this); add(lista);
for(int i=1;i<=20;++i)
lista.add(String.valueOf(i));
}
//Se produce cuando se da doble clic sobre algún item de la lista.
public void actionPerformed(ActionEvent e)
{
if(e.getSource().equals(lista))
{
lista.remove(lista.getSelectedIndex());
lblX.setText("Quedan " + String.valueOf(lista.getItemCount()));
}
}
}
implements ItemListener
itenStateChanged(ItemEvent e)
Ejemplo:
Cada vez que se da clic en un item de la lista de la izquierda, éste pasa a la lista de la derecha:
import java.awt.*;
import java.awt..event.*;
public class Lista01 extends java.applet.Applet implements ItemListener
{
List lista1, lista2 ;
61
public void init()
{
setLayout(new GridLayout(1,2)) ;
lista1=new List();
lista2=new List();
for(int i=1 ; i<=20 ;++i)
lista.add(String.valueOf(i)) ;
lista1.addItemListener(this); add(lista1);
lista2.addItemListener(this); add(lista2);
}
//Se produce cuando se selecciona un item de la lista
public void itemStateChanged(ItemEvent e);
{
if(e.getSource().equals(lista1))
{
lista2.add(lista1.getSelectedItem());
lista1.remove(lista1.getSelectedIndex());
}
if(e.getSource().equals(lista2))
{
lista1.add(lista2.getSelectedItem());
lista2.remove(lista2.getSelectedIndex());
}
}
}
CHOICE
implements ItemListener
itemStateChanged(ItemEvent e)
//Constructors
public Choice();
//Methods
public void add(String item);
//Adiciona un item a la lista.
public int getItemsCount();
//Retorna la cantidad de ítems
public String getItem(int index);
//Retorna un item según el índice dado (index empieza en 0)
public int getSelectedIndex();
//Retorna el índice del item seleccionado
public String getSelectedItem();
//Retorna el item seleccionado
public void select(int Index);
//Establece que item sera el visible al inicio según el índice dado
62
public void select(String str)
//Establece qué item será el visible según el string dado
//el string dado tiene que coincidir con un existente.
Ejemplo:
Para cambiar el color del applet
import java.awt.*;
import java.awt..event.*;
public class Combo01 extends java.applet.Applet implements ItemListener
{
Choice c ;
public void init()
{
c=new Choice() ;
c.addItem("Rojo") ; c.addItem("Verde") ; c.addItem("Azul") ;
c.addItemListener(this); add(c);
setBackground(Color.red);
}
public void itemStateChanged(ItemEvent e)
{
if(e.getSource().equals(c))
{
String s=c.getSelectedItem();
if(s= ="Rojo") setBackground(Color.red);
if(s= ="Verde") setBackground(Color.green);
if(s= ="Azul") setBackground(Color.blue);
}
}
}
CHECKBOX
implements ItemListener
itemStateChanged(ItemEvent e)
//Constructors
public CheckBox();
public CheckBox(String label);
public CheckBox(String label, CheckboxGroup group, boolean state);
//CheckboxGroup para crear un grupo de botones de opción.
public CheckBox(String label, boolean state, CheckboxGroup group);
63
//Methods
public String getLabel();
//Retorna el caption
public boolean getState();
//Retorna el estado (true=check; false=nocheck)
public void setLabel(String label);
//Estable el label
public void setState(boolean state);
//Establece el estado (true=check; false=nocheck)
Ejemplo:
Conforme se marque el botón de chequeo, el mensaje en la parte inferior lo indicará
import java.awt.*;
import java.awt..event.*;
public class Chequeo01 extends java.applet.Applet implements ItemListener
{
Checkbox c1,c2,c3 ;
Label Prueba ;
public void init()
{
setLayout(new GridLayout(4,1)) ;
setBackground(Color.white) ;
c1=new Checkbox("Checkbox 1") ;
c2=new Checkbox("Checkbox 2") ;
c3=new Checkbox("Checkbox 3") ;
c1.addItemListener(this); add(c1);
c2.addItemListener(this); add(c2);
c3.addItemListener(this); add(c3);
Prueba=new Label(); add(Prueba);
}
public void itemStateChanged(ItemEvent e)
{
if(e.getSource() instanceof Checkbox)
{
String s= "Check en:";
if(c1.getState()) s+=c1.getLabel() + ",";
if(c2.getState()) s+=c2.getLabel() + ",";
if(c3.getState()) s+=c3.getLabel() + ",";
Prueba.setText(s);
}
}
}
implements ItemListener
64
itemStateChanged(ItemEvent e)
Ejemplo:
Cuando se marque el botón de opción, el mensaje en la parte inferior lo indicará.
import java.awt.*;
import java.awt..event.*;
public class Opciones01 extends java.applet.Applet implements ItemListener
{
CheckboxGroup Grupo;
Checkbox o1,o2,o3;
Label Prueba ;
public void init()
{
setLayout(new GridLayout(4,1)) ;
setBackground(Color.white) ;
Grupo=new CheckboxGroup() ;
o1=new Checkbox("Opción 1",Grupo,true) ;
o2=new Checkbox("Opción 2",Grupo,false) ;
o3=new Checkbox("Opción 3",Grupo,false) ;
o1.addItemListener(this); add(o1);
o2.addItemListener(this); add(o2);
o3.addItemListener(this); add(o3);
Prueba=new Label(); add(Prueba);
Prueba.setAlignment(Label.CENTER);
}
public void itemStateChanged(ItemEvent e)
{
if(e.getSource() instanceof Checkbox)
{
if(o1.getState()) Prueba.setText("Escogió " + o1.getLabel());
if(o2.getState()) Prueba.setText("Escogió " + o2.getLabel());
if(o3.getState()) Prueba.setText("Escogió " + o3.getLabel());
}
}
}
MENUS
import java.awt.*;
import java.awt..event.*;
class MiFrame extends Frame implements WindowListener, ActionListener
{
Button botonDeApplet;
MenuBar miMenu;
Menu mArchivo;
Menu mFont;
65
MenuItem mArchivoPrueba;
MenuItem mArchivoSalir;
MenuItem mFontEstilo;
MenuItem mFontColor;
MenuItem mFontTamano;
Panel pCentro;
Label lMensaje;
public MiFrame(String s, Button bA)
{
super(s); botonDeApplet=bA;
miMenu=new MenuBar();
mArchivo=new Menu("Archivo");
mFont=new Menu("Font");
mArchivoSalir=new MenuItem("Salir");
mFontEstilo= new MenuItem("Estilo");
mFontColor=new MenuItem("Color");
mFontTamano=new MenuItem("Tamaño");
}
this.setMenuBar(miMenu);
miMenu.add(mArchivo);
mArchivo.add(mArchivoPrueba);
mArchivo.addSeparator();
mArchivo.add(mArchivoSalir);
miMenu.add(mFont);
mFont.add(mFontEstilo);
mFont.addSeparator();
mFont.add(mFontColor);
mFont.addSeparator();
mFont.add(mFontTamano);
init(); show();
public void init()
{
addWindowListener(this);
mArchivoSalir.addActionListener(this);
mArchivoPrueba.addActionListener(this);
int wS=getToolkit().getScreenSize.width;
int hS=getToolkit().getScreenSize.height;
setSize(wS/2,hS/2); setLocation((wS-wS/2)/2,(hS-hS/2)/2);
setLayout(new BorderLayout());
pCentro=new Panel();
pCentro.setLayout(new GridLayout(3,1));
lMensaje= new Label("",Label.CENTER);
pCentro.add(new Label());
pCentro.add(lMensaje);
pCentro.add(new Label());
add("Center",pCentro);
66
}
public void windowClosing(WindowEvent e)
{
botonDeApplet.setEnabled(true); dispose();
}
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
}
67
Descargar