Programar en java es entender el concepto de clase

Anuncio
Para desarrollar aplicaciones en java
Desarrollar aplicaciones computacionales utilizando el lenguaje java es modelar y
codificar clases que resuelven un problema de la vida real. Por tanto entender el
concepto de “clase” es fundamental para ser productivo utilizando a la herramienta
java.
Es tentador iniciar el estudio de java estudiando y utilizando sus instrucciones, su
sintaxis y sus palabras reservadas propias del lenguaje. La mayoría de los textos
que le abordan así lo enfocan; es más, fue de esa manera como muchos
desarrolladores de software aprendieron a utilizar este tipo de herramientas para
concebir aplicaciones computacionales, sean estas al ambiente local, cliente
servidor o aplicaciones orientadas al web. Pero, la experiencia indica, que,
además de tentador, es bastante ineficiente y bastante improductivo para
enfrentar problemas de la vida real. Por tanto se tiene el criterio que, una vez que
el lector haga suyo el concepto de clase, se está en capacidad de iniciar y finalizar
aplicaciones computacionales altamente en tiempos relativamente cortos.
Pero se tiene un gran problema: el concepto de clase no es nada intuitivo ni fácil
de entender. Es un concepto abstracto, que, por definición apela a la imaginación,
a la creatividad y a otro gran tema de estudio que se podría denominar modelaje.
(Y cuando se cita la palabra modelaje se debe tener en perspectiva que la
expresión “arte” está a la vuelta de la esquina).
A pesar de que el concepto clase es complejo de adoptar y adaptar, y a pesar de la
dificultad que implica aprender a trabajar con algo que no se entiende a cabalidad,
sí se tiene el convencimiento que, en el muy corto plazo, los réditos son muy, pero
muy gratificantes.
El concepto de clase
Como cada autor tiene su propio concepto de clase, en muchos en los cuales se
coincide y muy pocos no, se puede decir que, dada cualquier abstracción de
cualquier naturaleza, es decir cualquier idea, algoritmo, metodología, entre otros,
los cuales dispongan de características similares, se entendería como “clase” a la
plantilla, patrón, estructura o modelo que represente esa abstracción.
Una clase, perfectamente, puede ser la expresión matemática utilizada en el
cálculo del área de un triángulo, por ejemplo. O la manera intuitiva de calcular
áreas bajo un curva imaginando pequeñísimos rectángulos, calcularles su área y
luego sumarlos para esperar que sea muy parecida al operador matemático
denominado “integral” que, cualquier profesional emplearía. O, el conjunto de
propiedades y actividades que implican la idea “persona humana”, “árbol”, “mapa”,
“pintor”, “emisión de cheques”, “cajero automático”, y demás.
Similarmente, una clase puede ser desarrollada utilizando otra clase que otra
persona acabó y la expuso al conocimiento al público, pero, en aras de resolver un
problema en particular, se hace necesario agregarle algún concepto, componente
o idea que, la clase primera, es decir, la ancestral, no disponía.
En java es muy común la idea esbozada en el párrafo anterior: dada una clase el
analista la “incorpora” para resolver “el” problema que tiene en mente. Inclusive,
se puede afirmar que trabajar bajo el contexto de otra clase ya elaborada es la
norma del desarrollo de aplicaciones en java. La relación jerárquica de superclase y
subclase es crucial entenderla para evitar descubrir el agua tibia cada vez que se
aborda algún problema en particular.
¿Una clase que calcula áreas de triángulos?
Teniendo por referencia la posible dificultad de asociar la idea de abstracción de
una clase como la idea de “la clase que calcularía las áreas de triángulos”, se debe
discriminar las expresiones “las áreas de los triángulos” con la expresión “un área
de un triángulo” en particular.
Cuando una clase sigue paso a paso las instrucciones que conducen al cálculo de
un triángulo “en abstracto”, es decir, dadas una altura y una base definidas en un
espacio determinado, se dice que se hace necesario hacer una instancia de una
clase ya elaborada (ya codificada en java) para “estar en capacidad de conocer” el
área.
Nótese como paulatinamente lenguajes como java se empiezan a diferenciar de
otros lenguajes, como el Pascal, por ejemplo. En java se construyen clases con el
fin de implementarlas para la solución de un conjunto de problemas “con
características similares”. En Pascal, se construyen archivos “ejecutables” a los
cuales se les alimenta parámetros para resolver “problemas similares”.
Instanciando una clase conduce a otro concepto medular en el lenguaje java: al
concepto de objeto. La relación entre clase y objeto, y entre objeto y clase, ha
abierto todo un nuevo paradigma computacional en el arte del desarrollo de
aplicaciones: la programación orientada al objeto, OOP.
Una clase que “calcula áreas de triángulos” es un patrón que implica la
implementación del algoritmo propio del área de los triángulos, el producto de la
base por la altura y dividiendo el resultado entre dos. Pero ese patrón de cálculo
no necesita ser codificado pensando en un triángulo en particular, sino, y esta es
la clave, pensando en cualquier triángulo del universo.
La clase que calcula áreas de triángulos no necesita conocer cómo se obtuvo el
valor de la base, ni si la altura tiene dimensiones de centímetros o metros, o, si el
triangulo representa un terreno de construcción de una casa o, la configuración
natural de tres estrellas en el firmamento. Este hecho tan interesante que obliga a
los desarrolladores de software a pensar en abstracciones y no en problemas
puntuales, ha hecho posible la resolución de planteamientos que, en otros
tiempos, requería mucho esfuerzo para la resolución de problemas.
De la clase a las propiedades y a los métodos
La abstracción de clases es la misma idea de la abstracción de sistemas. Por lo
tanto, pensar sistémicamente es requisito sine qua non para modelar clases.
Así como los sistemas tienen estados y conductas, las clases tienen propiedades y
métodos. Las propiedades son estados de las clases. Una propiedad puede ese el
color, la cual, al instanciarlo, genera el color de un determinado objeto, esto es,
combina las cantidades de “pigmentos” rojo, azul y verdes. El peso, el valor de las
dimensiones, el volumen, el área, el tamaño, entre muchos otros “valores”
naturales de un objeto, son ejemplos típicos de las propiedades que los objetos
adquieren al ser instanciadas desde una clase.
Por otra parte, los métodos reflejan las conductas de las clases. Conductas en el
sentido de “qué hacer”, “cómo actuar”, “qué actividad ejecutar”, “qué evento
disparar” cuando alguna instrucción, línea de código o el propio usuario al
movimiento de un click del ratón, activa al método en cuestión.
Por tanto es imperativo empezar a diseñar métodos. Y aprendiendo a construir
métodos se aprende a ensamblar el código java.
Los métodos
En la Sección anterior se introdujo el verbo “ensamblar”. Y se hizo a propósito en
este punto porque, construir clases y aplicaciones con java –como en cualquier
otro lenguaje orientado al objeto- es, ni más ni menos, ensamblar continuamente
partes ya terminadas de código. A cada una de estas partes de código se
denominan métodos.
Métodos son, por tanto, trozos de software que se pueden usar desde cualquier
clase. Así como los juegos de piezas estándares y fijas que el jugador junta, arma,
ensambla, en función de creatividad, (o desemsambla, desarma y separa) los
métodos son líneas de código, por lo general pequeñas cantidades de líneas, que,
una vez que se tiene la certeza que no tienen errores y son “multiuso”, el
desarrollador de aplicaciones usa y descarta con la misma facilidad de que, con
piezas estándares de un juego “de armar”, construye y destruye castillos
sofisticados por mero placer.
La primera clase
Supóngase que se tiene necesita de resolver el problema del cálculo de volumen
de un cilindro, de radio “r” y de altura “h”. Para ello se desarrolla una clase,
denominada “CalculoDelVolumenDeUnCilindroSolido” la cual hace uso de algún
método bastante genérico que genera el “CalculoDelAreaDeUnCirculo”, porque,
conociendo el área de un círculo, es decir, de la base del cilindro, simplemente se
multiplica esta área por la altura del cilindro y se tendría el volumen. Así,
1
2
3
public class CalculolDelVolumenDeUnCilindro{
public CalculolDelVolumenDeUnCilindro (double RadioDelCilindro, double AlturaDelCilindro;){
double AreaDeLaBaseDeUnCilindro;
4
double VolumenDeUnCilindro;
5
AreaDeLaBaseDeUnCilindro = CalculoDelAreaDeUnCirculo(RadioDelCilindro);
6
VolumenDeUnCilindro = AreaDeLaBaseDeUnCilindro * AlturaDelCilindro;
7
System.out.print("Volumen del cilindro: " + VolumenDeUnCilindro);
8
}
9
public double CalculoDelAreaDeUnCirculo (double Radio){
10
double Area;
11
Area = 3.141521 * Radio * Radio;
12
return Area;
13
14
}
}
Por ser esta la primera clase que se presenta muchos elementos pudieran ser
desconcertantes pero, una vez comprendidos, tienen su lógica y fundamento.
Lo primero que resalta es la especificación de cualquier clase en la línea 1. Todas
las clases en java inician con un “{”y cierran con “}”. Esta clase en particular tiene
un método: “CalculoDelVolumenDeUnCilindroSolido”.
La clase tiene un metodo, “CalculoDelAreaDeUnCirculo”, y otra estructura muy
parecida al método con un nombre igual al de la clase. Al segundo método se le
denomina “constructor”.
El método “CalculoDelAreaDeUnCirculo” inicia con una “{” y termina con otro “}” ,
líneas 9 y 13. Lo que el método encierra entre los paréntesis redondos, (), se
denominan “parámetros” del método. Los métodos pueden tener uno o más
parámetros, ó, puede no tener parámetros del todo.
Los parámetros son valores que “se transportan” (que se “comunican”) desde
cualquier lugar donde se utiliza el método. Por ejemplo, dado cualquier valor de la
variable denominada “radio”, el método “CalculoDelAreaDeUnCirculo” devuelve, a
la línea de código que activó el método, es decir, el valor del “Area”, sin interesar
para qué se utilizará, posteriormente, el valor del área.
Ahora es importante mirar con detalle las líneas de código.
En primer lugar la forma como se hacen “copias”, -es decir instancias-, de las
clases. Por lo general, se tienen el formato:
UnaClase UnaInstancia;
Por ejemplo, dentro del paquete java existen clases primitivas, como la clase
“double”, que define al conjunto de números reales desde un ámbito de valores
muy grandes, como un poco más adelante se verá.
Las instancias de las clases primitivas, como la clase “double” se formarían así:
double AreaDeLaBaseDeUnCilindro;
double VolumenDeUnCilindro;
En otras palabras, se han generado lo que se podrían denominar “otra instancia” o
“variables” cuya vigencia o vida útil estaría desde la línea donde se coloca el “{”
hasta la línea donde se cierra la estructura, i.e., “}”.
A pesar que el término variable es muy utilizando en buenos textos de java, no es
de nuestro agrado porque tiende a equipar con otros conceptos que no son ciertos
para java; por tanto, el término variable se tratará de no utilizarlo; se prefiere el
término de instancia de clase.
“Instancia” debe entenderse como sinónimo de “clon”, como “copia al carbón” de
algo previamente establecido. De una misma clase perfectamente se pueden hacer
muchas instancias para utilizarse dentro de cualquier estructura, esto es, dentro de
cualquier aplicación que eventualmente nace de la clase. Dicho lo anterior, las dos
líneas del código java antes reproducidas, perfectamente pudo especificarse como:
double AreaDeLaBaseDeUnCilindro, VolumenDeUnCilindro;
con idénticos resultados.
Desde luego que java no solamente es capaz de generar instancias para números
reales. También existen clases para números enteros muy grandes, para números
reales pequeños, para caracteres alfanuméricos, etc. Una pequeña lista de estas
clases primitivas, se comenta un poco adelante.
Parámetros
Lo próximo a comentar es el concepto de parámetros. Parámetros entre métodos,
más concretamente, porque existen parámetros “entre clases” y parámetros “entre
aplicaciones”.
Los métodos –y los constructores- pueden recibir parámetros. Los métodos –y los
constructores- son capaces de devolver resultados, pero, dentro del contexto de
los constructores, es mejor concebir a la clase como a la entidad que devuelve
resultados (no olvidar que la clase y el constructor siempre tienen el mismo
nombre). “Pasar” parámetros entre constructores es sinónimo a “pasar”
parámetros entre clases.
Los parámetros, si existieran, se ubican en los “()” de los métodos y de los
constructores. Si no existen parámetros, los “()” quedan vacíos.
Cuando un método devuelve un resultado debe especificarse la clase con que se
devuelve el valor; ello se conoce con el nombre de “la clase del método”. Nótese
que, en alguna parte del método existe la instrucción “return” cuando algún valor
(o alguna clase) se regresa.
Pero pudiera darse el caso de un método que no tiene clase, que no devuelve
valores para decirlo en sencillo. Cuando un método no se asocia a ninguna clase se
dice que la clase del método es “de clase” “void” y, por supuesto, un método de
“clase void” no puede tener la instrucción “return”.
Si permanece alguna dificultad en entender “métodos que no devuelven valores”,
debe retomarse lo antes comentado en torno a la “conducta” de un sistema. Las
conductas no necesariamente generan datos o valores concretos, pueden generar
acciones como activar algún otro evento, generar un aviso, poner a trabajar otro
método, entre otros.
Los constructores no pueden tener clases asociadas a él ni mucho menos la
expresión “return”. Los constructores no están pensados para ser usados por la
misma clase: están pensados para que otros constructores de otras clases lo
accedan, sin menoscabo que cualquier clase pudiera acceder a cualquier método
de alguna clase instanciada. Este punto es crucial en java y vale la pena reflexionar
en torno a las diferencias entres método y constructor.
A manera de resumen se puede afirmar que los métodos son funciones definidas programadas- dentro de las clases los cuales pueden tener o no insumos y pueden
regresar o no información a otros métodos. Se reitera que cuando los métodos no
tienen insumos los paréntesis redondos de los métodos están vacíos. Cuando un
método no regresa valores, se dice que el método es de clase void.
Las estructura de clases y métodos
Por lo pronto, la estructura de una clase es:
public class NombreDeLaClase{
}
y la estructura de un metodo es:
public clase_del_método NombreDelMetodo(ParametrosDeEntrada){
}
Ejemplos de estructuras
La expresión “System.out.print()” y “System.out.println()” son dos llamadas típicas
de las clases. La idea es bien intuitiva: dentro de la clase “System” existe otra
clase –una subclase por así decirlo- denominada “out” y, dentro de la clase “out”
se tienen métodos (que también se pueden concebir como clases), dos de los
cuales se denominan “print()” y “println()”.
La resultante de una llamada a cualesquiera estos dos métodos es imprimir en la
ventana de comando, o, salida al monitor como se decía en años pasados. Lo que
eventualmente se escribe en la ventana es lo que se encierra entre los paréntesis
redondos.
La diferencia entre “print” y “println” es que la primera imprime sin crear filas
nuevas cada vez que se acceda al método, es decir, sin generar el “carriagereturn” (el “enter”) cada vez que se imprime lo solicitado. Por otra parte, cada vez
que se llama al método “println” éste siempre inicia en la primera columna de la
ventana de salida.
La estructura en la llamada del método “print” es muy frecuente cuando se trabaja
con java. Por ejemplo, si se tiene:
java.awt.Button UnBoton;
se está expresando que se desea una copia, una instancia, que se almacenaría en
una variable bajo el nombre de “UnBoton”, de la clase “Button”, la cual, a su vez,
tiene por superclase a “awt” y ésta, a ”java”.
Clases y archivos físicos
Todas las clases del lenguaje java se almacenan en archivos físicos pero con una
gran condición, estos archivos físicos han de tener el mismo nombre –y la misma
secuencia de letras mayúsculas y minúsculas- que se le asigna a la clase y, han de
tener la extensión .java
Por ejemplo, cuando se tiene una clase denominada “MiClase”, se debe tener un
archivo de texto denominado “MiClase.java”, el cual, una vez compilado, generaría
el archivo “MiClase.class"
Superclases y subclases
Construída una clase, esta puede generar otras clases. Y pudiera ser que estas
segundas clases sirvan para generar otras clases y así sucesivamente. O que de la
primera y segunda clase, se conjuguen y formen otra nueva clase.
Java, en realidad es un conjunto de clases a su disposición para que Ud. diseñe y
desarrolle sus propias clases de forma tal que el arte de programar en java, y por
ende el arte de la programación OOP, es tener habilidad de adaptar clases sin
pretender nunca descubrir el agua tibia.
A la clase "ancestral" se le denomina “superclase”. A las clases hijas del una
superclase se les denominan “subclases”.
Java tiene infinidad de clases a su disposición contenidas en un paquete
antiguamente denominado JDK1, -ahora denominado J2SDK2-, un kit para el
desarrollo de aplicaciones en java. Obviamente, este conjunto de clases
economizan tiempo de desarrollo porque sencillamente ya están construídas.
Todas las clases contenidas en el JDK tienen una clase ancestral denominada
Object.
La clase “java.awt.Frame”, contenida en el JDK, en la clase que “le economiza” al
desarrollador rescribir el código relacionado a la lógica para producir una ventana
del tipo Windows, tan popular entre los usuarios. La clase “java.awt.Button”
construye botones, la clase ”java.awt.applet.Applet” construye aplicaciones
denominados “applets” muy útiles para generar productos para ser utilizados
exclusivamente en la web. La clase “javax.swing.JLabel” y la clase “java.awt.Label”
1
JDK son las iniciales de Java Development Kit.
2
J2SDK son las iniciales de Java 2 Standard Development Kit.
ambas contenidas en el JDK construyen etiquetas con algunas diferencias
significativas, y así sucesivamente.
De la clase al objeto
La gran pregunta es cómo obtener el “producto” de una clase, es decir, cómo se
ejecuta una clase, cómo se obtiene un objeto. La respuesta ya se ha comentado
pero, dada la importancia de la pregunta se enfatizará: los productos de una clase
se obtienen instanciando la clase.
Para ejecutar una clase se necesita otra clase que amarre la clase de referencia y
la despliegue directamente al monitor o -indirectamente- a cualquier navegador del
web. Clases que hacen interface al monitor se les denomina en el argot de java
“como clases” “main”; clases que hacen interface -indirecta- a los navegadores, se
les denomina “applet”.
Clases primitivas y referenciadas
Pero el comentario anterior lleva a otro punto muy importante. Es fundamental en
java hacer la discriminación entre clases primitivas y clases no-primitivas. Se ha
visto que, la estructura de instancia de una clase primitiva es:
clase instancia;
Mientras que, para una clase no-primitiva, o clase referenciada, la estructura de
instancia a la clase es,
clase instancia = new clase();
Por ejemplo, las instancias siguientes están correctamente estructuradas:
boolean RespuestaDeArranque;
int MiNumeroEntero;
OrdenamientoDeMatriz MiInstancia = new OrdenamientoDeMatriz();
ClaseDelWeb A = new ClaseDelWeb(int TamanoDelMonitor);
Clases referenciales
Por supuesto, las clase que el desarrollador de aplicaciones diseña y la mayoría de
las disponibles en las bibliotecas de java, son las clases denominadas noprimitivas. La instancias a estas clases tiene un mismo patrón, a saber:
ClaseNoPrimitiva instancia = new ClaseNoPrimitiva();
Donde los “()” envían al constructor respectivo los parámetros del caso.
Un punto importante en este punto: las clases pueden o no tener constructores.
Tres observaciones son de rigor.
En primer lugar, se puede hablar de clases que no contienen constructores, i.e.,
clases que sólo contienen métodos que pudiesen llamarse desde cualquier punto
de cualquier clase. “Bibliotecas” sería un nombre oportuno a este tipo de clases.
En segundo lugar, pueden existir clases con solo un constructor. Este constructor
ha de mirarse como “el método” que condude la lógica de la clase. Algo así como
el “conductor” de un carro: “el carro” es la clase pero quien decide qué conducta
utilizar o que propiedad cambiar, es el constructor de la clase, o, la persona que
tiene los controles del carro.
En tercer lugar, pueden existir clases que tengan más de un constructor. A pesar
de que todos los constructores se denominan con igual nombre de la clase, cada
uno de estos constructores difieren en la cantidad, en la naturaleza de la clase y
en el orden de los parámetros. ¿Y para qué sirve esto?, podría preguntarse el
lector. Pues sencillamente para implementar una característica muy importante de
los objetos denominada el polimorfismo; pero este tema se debe comentar con
tiempo en otra oportunidad.
Estructura del main
La idea de la clase que eventualmente amarra a otra clase, el “main” es muy
sencilla: esta clase es un medio para ejecutar directamente la clase que se tienen
en mente o , la clase para alimentar de valores a las clases –si es que se tuviese el
caso de constructores con parámetros- y presentarla al monitor. La estructura
típica del “main” se presenta a continuación:
public class EjecutaAlgunaClase{
public static void main( String args[] ){
LaClaseAEjecutar F = new LaClaseAEjecutar();
}
public boolean handleEvent (java.awt.Event e){
if (e.id == java.awt.Event.WINDOW_DESTROY){
System.exit(0);
return true;
}
return false;
}
}
Todos los main tienen que ser públicos, de carácter estático y de clase void, -de
“tipo” void, en al argot popular-. Además, la clase main ha de tener un “arreglo”
de parámetros de clase String. Nótese la similitud entre esta estructura y la
estructura de un método.
Estructura del applet
La estrategia de diseño de la clase para instanciar a un applet sigue a
continuación: se busca una clase estándar clase que directamente incrusta la clase
tipo applet e inmediatamente la envía a cualquier navegador de la Internet.
Se adjunta la estructura para, posteriormente, comentarla.
public class EjecutaUnApplet extends java.applet.Applet{
public java.awt.Button BotonPrincipal = new java.awt.Button("Inicio del Applet");
public void init(){
setBackground(new java.awt.Color(255,255,255));
add(BotonPrincipal);
}
public boolean action(java.awt.Event e, Object o){
if(e.target == BotonPrincipal){
}
LaClaseAEjecutar F = new LaClaseAEjecutar();
return true;
}
return false;
}
El objetivo de utilizar a la clase “java.awt.applet.Applet” como superclase –
haciendo uso de la instrucción “extends” en la primera linea- es únicamente, como
medio para introducir la clase que se desea ejecutar, en el web.
La clase “EjecutaUnApplet” únicamente despliega en pantalla un botón. Nótese
que el botón es una instancia de la clase “java.awt.Button” la cual, al interpretarse
por el compilador java, despliega un botón con un encabezado igual a “Inicio del
Applet”. Al dar un click a este botón, se ejecuta la línea crítica de la clase: se hace
la instancia de la clase que se desea ejecutar. Y eso es todo.
Se ha reiterado que la clase applet es una forma indirecta de ejecutarla utilizando
cualquier navegador del web. Se dice “indirecta” porque los navegadores –por lo
pronto- no interpretan directamente a los applets: los navegadores requieren que
los applets estén incrustados en archivos planos, con extensión “.html”. Los
archivos html sí pueden interpretarse por los motores de los navegadores.
A continuación se presenta un archivo html, típico para servir de interface, de
puente, entre el applet y el navegador de Internet.
<html>
<body>
<applet codebase="." applet code="EjecutaUnApplet.class" width=500 height=120>
</applet>
</body>
</html>
Nótese que la estructura del “main” es, fundamentalmente, la de un constructor.
Clases main vrs. aplicaciones
Es importante tomar nota de lo comentado hasta la Sección anterior: la estrategia
del desarrollo de aplicaciones es básicamente la idea de desarrollar clases que
satisfagan los requerimientos de los clientes, desde luego, pero, sin distraerse en
el “problema” relacionado hacia la ejecución de la clase, es decir, sin distraerse en
la decisión de orientar la salida hacia un “main” o hacia un “applet”.
La orientación estratégica es, por tanto, desarrolle clases y, posteriormente,
pregunte cómo se desea ejecutar la clase. Nótese que esta estrategia de desarrollo
es concebir a las clases “main” y “applet” como representaciones abstractas de los
objetos.
Modelando clases
Se tiene la fuerte convicción que la mejor metodología para el desarrollo de clases
han de seguir fielmente los postulados que, desde el año 1536, escribiera Rene
Descartes, en su célebre obra denominada “Discurso del método”. Sin pretender
discutir su contribución desde el punto de vista filosófico o científico, se desea
resaltar cuatro pasos fundamentales para abordar problemas que escribiera en el
Capítulo 2:
Zzz
Se tiene el criterio que, si se desea desarrollar aplicaciones bajo el paradigna OOP
los postulados cartecianos tienen una vigencia increíble.
Bibliotecas y paquetes
Se conocen con el nombre de “bibliotecas” a cualquier conjunto de clases,
mientras que, con el nombre de “paquete”, a aquel conjunto de clases -y/o
bibliotecas- que tienen una residencia (y un fin) definido.
Los escuchadores
El tema de “los escuchadores” es muy amplio en el lenguaje java, y, quizás, uno
de los temas donde la programación orientada al objeto toma su importancia.
Dado que el concepto de escuchador está fuertemente asociado al concepto de
interface, se ha de recordar que una “interface” es un medio que existe entre dos
entidades totalmente diferentes.
Unos ejemplos ayudan a aclarar el concepto de interface. Entre el aparato de
televisión y una persona, el “control remoto” es un excelente ejemplo de interface.
Entre dos secciones de una geografía separados por un río, el puente puede
interpretarse como una inteface para dos posibles secciones de una carretera.
Entre el cerebro humano y una imagen foránea a su sistema, los ojos constituyen
un perfecto ejemplo de interface que faculta el sentido de la vista.
En otro orden de cosas, y antes de iniciar el tema de los escuchadores, es
oportuno tener en mente la siguiente imagen que de seguro fortalecerá el
concepto que se busca.
Supóngase que Ud. asiste a una conferencia de carácter internacional y, su
conferenciante dicta su ponencia en idioma japonés. Partiendo del hecho que Ud.
no entiende japonés, deberá recurrir a audífonos para la traducción simultánea del
japonés al español, su idioma natal. Otras personas que si entienden el idioma
japonés, de hecho, no requieren los servicios ni de los audífonos ni del traductor.
Junto a Ud. sus compañeros de fila son, digamos, personas de origen alemán,
inglés y francés, cada uno de los cuales necesitan los servicios de las traducciones
simultáneas respectivas, si, desde luego, no entendieran al idioma del
conferenciante.
Esta imagen de un ambiente multilenguas, donde todos los participantes necesitan
entender, encaja perfectamente en el tema de los escuchadores de java. Con
diferente nomenclatura, desde luego. Analícese el siguiente cuadro.
Simbología en el ambiente social
Simbología en el ambiente del
lenguaje java
El conferencista
Una persona quien merece atención
Un usuario quien debe ser satisfecho
El auditorio
Conjunto de personas que atienden la
conferencia, los audífonos y las cabinas
de traducción simultánea
Una clase
Los miembros del auditorio
Personas
Objetos
Miembros del auditorio que no
entienden el idioma del conferencista
Personas con audífonos
Objetos con capacidad de escuchar
Sección de traducción simultánea de un
idioma a otro
Una cabina de traducción
Una “interface”
Conexión entre los audífonos de las
personas y el micrófono del traductor
Un trozo de cable
La palabra reservada “implements”
Personas que entienden japonés
Personas que no necesitan audífonos
Objetos que, para escuchar, no
necesitan ninguna interface
Personas que no les interesa ni
escuchar ni entender al conferencista
Personas desinteresadas
Objetos sin ninguna capacidad de
escuchar
Ejemplo de cabina de traducción
Cabina de traducción del idioma
japonés al español
La interface “java.awt.ActionListener”
Otro ejemplo de cabina de traducción
Cabina de traducción del idioma
japonés al francés
La interface “java.awt.MouseListener”
Dispositivo que usan las personas para
escuchar al traductor
Los audífonos
Los métodos abstractos de las
interfaces
Ejemplo de un dispositivo utilizado para
escuchar al traductor
Una persona que utiliza un audífono
marca A
Si se usa la interface
“java.awt.ActionListener”, el método
“ActionPerformed()” discrimina al objeto
Otro ejemplo de un dispositivo utilizado
para escuchar al traductor
Una persona que utiliza un audífono
marca B
Si se usa la interface
“java.awt.MouseListener”, el método
“mouseClicked()” debe discriminar al
objeto
Ejemplo de un dispositivo utilizado para
escuchar al traductor, pero con la
particularidad de que, el mismo
dispositivo sirve para muchos idiomas
Una persona que utiliza un audífono
marca C
Si se usa la interface
“java.awt.ActionListener” sobre un
objeto que tiene muchos items, el
método “ActionPerformed()” debe
discriminar al objeto y luego al item.
Con estas similitudes en mente, a continuación se presenta cinco clases que
incorporan la habilidad de escuchar.
Cuadro zzzzzzz
Nótese lo siguiente:

Se accede a la o las interfaces mediante la palabra reservada “implements”

Si la interface utilizada fuese la “java.awt.ActionListener”, entonces
cualquier objeto tiene la capacidad de escuchar si dispone de la instrucción
“objeto.addActionListener”.

Existen “eventos” que pueden ser escuchados sin necesidad de interfaces,
como los eventos “action” y los eventos “”handleEvents”, entre otros.
super vrs. this
Estando en una clase producida a partir de otra clase, es decir estando en una
subclase producida partir de una superclase, muchas veces se necesita hacer
referencia a objetos tanto de la superclase como de la subclase. Para esto se usan
las palabras reservadas “super” y “this”.
El “super” hace referencia a la superclase. El “this” hace referencia a la subclase.
Un par de ejemplos son de rigor.
Acceso a las clases
public
Private
protected
Clases “final”
Zzz
Clases “abstract”
Zzzzz
Instrucciones básicas en java
Conocido y comprendido el concepto de clase, es de rigor introducir instrucciones
del lenguaje. Al introducir instrucciones irremediablemente arriban conceptos de
sintaxis que se abordarían en el acto.
Sintáxix básica

Java es totalmente sensible a las letras mayúsculas y minúsculas. Para java
el nombre “Hola” es totalmente distinto a “hola” y a “hoLa”.

Todas las sentencias de java terminan con el separador “;”. Es
perfectamente viable generar una sentencia de más de un renglón siempre
y cuando el último símbolo de cada sentencia finalice con un “;”.

Los comentarios en java se indican con un “//”. Si un grupo de renglones
pertenece a comentarios, entonces el primer renglón ha de llevar los
símbolos “/*” y el último renglón con el símbolo “*/”.

Se recomienda utilizar nombres de instancias haciendo uso de letras
mayúsculas y letras minúsculas, y, desde luego, que los nombres sean
autodomentados. No se permiten nombres que incluyan el espacio en
blanco.

Todas las estructura en java inician con “{” y terminan con “}”.

El uso de “()” es muy distinto al uso de los “[]”. Por lo general con los “()”
se indica que, dentro de ellos, se ubica una lista de parámetros, mientras
que los “[]” se indica que, lo instanciado, se comporta bajo el concepto de
arreglo.

Por defecto, todas las clases de java tienen a su disposición a las clases
contenidas en la biblioteca “java.lang”.


Haciendo reminicencia del lenguaje “C”, java permite operadociones
aritméticas sobre la misma instancia –“variable” es mejor palabra en este
punto- de la siguiente manera;
C += 7;
es exactamente lo mismo a escribir C = C + 7;
C -= 7;
es exactamente lo mismo a escribir C = C - 7;
C *= 7;
es exactamente lo mismo a escribir C = C * 7;
C /= 7;
es exactamente lo mismo a escribir C = C / 7;
C % = 7;
es exactamente lo mismo a escribir C = C mod 7;
k++
significa que, a la varible k se le suma una unidad para
la siguiente oportunidad en que k se utilice. (Este tipo
de llamada se le denomina “de postincremento”).
k--
significa que, a la varible k se le resta una unidad para
la siguiente oportunidad en que k se utilice.
++k
significa que, a la varible k se le suma una unidad para
la segunda oportunidad en que se le utilice. (Este tipo
de llamada se le denomina “de preincremento”).
--k
significa que, a la varible k se le resta una unidad para
la segunda oportunidad en que se le utilice.
dddddd
Clase primitivas
Las clases primitivas, aquellas que se encuentran en la bibioteca “java.lang” son
instanciadas mediante la sintaxis:
ClasePrimitiva instancia;
donde, “ClasePrimitiva” puede ser cualesquiera de las siguientes clase:

“byte”. Si se desea una instancia de un número entero de tamaño de
8 bits. Ello significa que, el ámbito de una clase “byte” sería desde 128 hasta +128.

“short”. Si se desea una instancia de un número entero de tamaño de
16 bits. Ello significa que, el ámbito de una clase “short” sería desde
–32,768 hasta +32,767.

“int”. Si se desea una instancia de un número entero de tamaño de
32 bits. Ello significa que, el ámbito de una clase “int” sería desde
–2,174,483,648 hasta +2,174,483,647.

“long”. Si se desea una instancia de un número entero de tamaño de
64 bits. Ello significa que, el ámbito de una clase “long” sería desde
–9,223,372,036,854,775,808 hasta +9,223,372,036,854,775,807.

“float”. Si se desea una instancia de un número real de tamaño de 32
bits. Ello significa que, el ámbito de una clase “float” sería desde
–3.40292347 E+38 hasta +3.40292347 E+38.

“double”. Si se desea una instancia de un número entero de tamaño
de 64 bits. Ello significa que, el ámbito de una clase “double” sería
desde –1.797693... E +308 hasta +1.797693... E+308

“char”. Si se desea una instancia de un carácter de tamaño de 16
bits, por supuesto. Ello significa que, el ámbito de una clase “char”
sería desde “0000” hasta “FFFF”, en hexadecimal, por supuesto.

“boolean”. Si se desea una instancia de un valor boleano de tamaño
de 8 bits. Ello significa que los únicos valores posibles de una clase
“boolean” serian “”true” y “false”.
Sentencias de control
El “if”
La instrucción “if” es quizás la instrucción que le dio dirección y sentido a la
programación de las computadoras. Y por ninguna razón esta instrucción debe
quedar fuera de java.
El “if” es bastante intuitivo:
if ( UnaCondicion) {
......
}
else {
......
}
es decir, cuando la condición del “if” es verdadera se ejecutan todas las lineas de
código contenidas dentro del primer conjunto “{}”. Si por otra parte, la condición
es falsa, se ejecutan las líneas de código contendias en el trozo “else{}”
El “swicth”
El “switch” es una sentencia de control mucho más amplia que la sentencia “if”. Su
estructura es la siguiente:
switch variable {
case PosibleValor1 :
.....
....
break;
case PosibleValor2 :
.....
....
break;
case PosibleValorN :
.....
....
break;
default {
.....
}
}
Sentencias de flujo
El for
El “for” es la instrucción que prácticamente nació con los lenguajes de
programación. Tiene la siguiente sintaxix.
for (DeclaracionContador = InicioContador; Condicion; IncrementoContador) {
.......
}
la cual se recorre una y otra vez hasta que la condición sea falsa. Por ejemplo,
for (int k = 1; k zzzzz 10; k = k + 1){
…..
}
genera la siguiente actividad: habiéndose creado un contador denominado “k”,
éste se inicia en “1” y cada vez que el ciclo se cumpla, el contador se incrementa
en una unidad. El ciclo se repite ad perpetum hasta que la condición se haga
“false”, es decir, cuando k sea menor a 10.
El “while”
La sentencia “do-while” es muy parecida a la del “for”, a saber,
while (Condicion){
.....
}
El ciclo se repite ad perpetum hasta que la condición se haga “false”,
El “do-while”
La sentencia “do-while” es muy parecida a la del “for”, a saber,
do {
.....
} (Condicion);
El ciclo se repite ad perpetum hasta que la condición se haga “false”,
Sentencias de paso
Se puede considera al “return” como una instrucción de paso, pero, dada la
inegable utilidad de ella en todos los métodos “de clase void”, su explicación ya se
llevó a cabo.
Una instrucción “break” quiebra una secuencia de código repetitivos para retomar
el control justo después de la terminación del ciclo, es decir, posterior a un “}”. Por
lo general el uso del “break” es muy útil dentro de una instrucción “for”, “while” ó
“do-while”.
Como se comparte el criterio que las siguientes instrucciones de control debieran
de evitarse, únicamente se citan para no promocionar su uso: se refiere a las
instrucciones “continue” y el “label”. El lector interesado puede consultar cualquier
texto de java para su respectiva explicación.
Sentencias de manejo de errores
El “try-catch-finally”
El “throw”
Los arreglos
Los arreglos son estructuras de datos que, bajo un solo nombre de instancia, tiene
la capacidad de almacenar muchos valores –muchos atributos, se diría en el argot
del paradigma orientado al objeto-.
El uso, la comodidad y el potencial de los arreglos son muy amplios, porque, con
solo una instancia, se generan tantos objetos como el usuario desee.
Los arreglos pueden ser de una, dos, o muchas dimensiones. A pesar de que un
arreglo puede interpretarse como un vector matemático, una matriz, un cubo, o un
arreglo abstracto de “n” dimensiones en el espacio Euclidiano de tamaño “n”, el
lenguaje java opta por la notación de arreglo de arreglos: una matriz para java es
un arreglo de una dimensión dentro de otro arreglo de una dimensión y así
sucesivamente.
Java reconoce los arreglos mediante los símbolos “[” y “]” y tantos pares de esos
dos símbolos como dimensiones se deseen. Por ejemplo, al especificar,
int A[];
A.length = 10;
Se ha definido en memoria un arreglo de una dimensión denominado “A” que tiene
diez celdas, cada una de ellas numeradas mediante 0,1,2,...9.
Otra manera de especificar el tamaño es:
a) Especificando los valores:
int A[] = {31, 42, 13, 34, 75, 6, 7, 8, 9, 10};
b) Haciendo la instancia formal:
int A[] = new int[10];
Por otra parte, al especificar,
int B[][];
Se ha definido en memoria un arreglo de dos dimensiones denominado “B”. El
tamaño de las “matrices” son muy interesantes, pues java no actúa bajo el
concepto de “columna” facilitando en demasía los conceptos. Una matriz 3x4
puede declararse con cualesquiera de las siguientes maneras:
int B[][] = new int [3][4];
int B[][] = {{1,2,3,4}, {11,12,13,14}, {21,22,23,24}};
pero, perfectamente, -y esto es una tremenda ventaja de java-, los arreglos no
necesariamente tienen que ser del mismo tamaño, por ejemplo,
int C[][];
C = new int [2][];
C[0] = new int[5];
C[1] = new int[3];
C[2] = new int[8];
simplemente es una matriz con tres filas con cantidades de columnas variables: la
primera fila tiene 5 columnas, la segunda 3 y la tercera fila 8 columnas. Se tiene el
criterio que es mucho mejor entender el tamaño y las dimensiones de los arreglos
asociando siempre el concepto de fila; en el ejemplo anterior, es mejor pensar que
cada una de las tres filas de “B” tiene a su vez, cada una de las filas, cuatro filas.
Una nota importante en torno a arreglos: el tamaño de los arreglos,
indistintamente de la manera de cómo se declaran, son de clase “final”, i.e., una
vez declarados no pueden alterarse.
Administrando los paneles
Las cadenas
Entendiendo por cadena a la clase capaz de representar simbolos alfanuméricos,
letras, palabras, números, simbolos especiales y demás, java administra dos
conjuntos de cadenas. La primera se relaciona al “char” y al “Character”. La
segunda se relaciona al “String” y al “StringBuffer”. Conceptualmente sólo a las
segundas clase se pueden clasificar como cadenas. Las primeras, en realidad, son
representaciones numéicas de los simbolos alfanuméricos.
La utilización de estas clases es sumamente amplia, baste con observar sus
constructores.
Constructores para la clase String

String()

String(byte[])

String(byte[], int, int)

String(byte[], int, int, String)

String(byte[], String)

String(char[])

String(char[], int, int)

String(String)

String(StringBuffer)
Constructores para la clase StringBuffer

StringBuffer()

StringBuffer(int)

StringBuffer(String)
Usos básicos de las clases String y StringBuffer
Los String son clases donde se supone, el contenido de la instancia perdura hasta
que no se redefina. Los StringBuffer son clases similares a los String pero, con la
particularidad de que el contenido de la cadena puede alterarse por secciones. La
clase String es mucho más eficiente que la clase StringBuffer
Las cadenas pueden visualizarse como arreglos de caracteres alfanuméricos, así,
String A = new String(“LUNA LIBERIANA”);
0
L
1
U
2
N
3
A
4
5
L
6
I
7
B
8
E
9
10 11 12 13 14 15 16
R
I
A
N
A
StringBuffer B = new StringBuffer(“Tiempo para vivir”);
0
T
1
I
2
E
3
M
4
P
5
O
6
7
P
8
9
10 11 12 13 14 15 16
A
R
A
V
I
V
I
R
int Longitud;
Longitd = A.length;
el valor de Longitud es 14
Longitd = B.length;
el valor de Longitud es 17
Char = MiCaracter;
MiCaracter = A.charAt(7);
el valor de MiCaracter es “B”.
MiCaracter = B.charAt(0);
el valor de MiCaracter es “T”.
A = B.substruing(7,11);
el valor de A es “PARA”.
A = B.substring(0,2) + B.substring(7,9);
el valor de A es “TIPA”.
Los hilos
Los hilos en java tienen la virtud de mitigar, en parte, los problemas de eficiencia
que implica el diseño conceptual de la computadora: la lógica secuencial. (Por lo
menos a la hora de escribir estas notas lo anterior es cierto, porque, es de esperar
que, en un futuro no muy lejano las computadoras personales –de bajo costotengan una lógica paralela... y más de dos estados para evolucionar el actual
paradigma binario que empezó a incomodar desde hace algún tiempo).
Continuando con la idea de generar imágenes para luego trasladarla al ambiente
del lenguaje java, los hilos tienen que mirarse como aquella persona, a quien
denominaríamos “tinteritero”, quien, mediante hilos amarrados en sus dedos, tiene
la habilidad de mover muchas figuras en un pequeño escenario, cuyas piezas de
las figuras, -manos, piernas, cabeza,...- están asociadas a un hilo. Si el movimiento
que ejerce uno o varios tinteritero actuando al unísolo es uniforme, armonioso e
inteligente, las figuras, vistas como participante del auditorio, “pareciera” que
tienen vida propia.
Exactamente ocurre lo mismo en el ambiente java cuando se desarrollan
apliacaciones con hilos. La clase, el tintoritero, hace uso de la superclase
“java.awt.Threads” y la interface “java.awt.Runnable”... y obviamente, el potencial
de java se extiende aún más pues, un hilo, puede encargarse del sonido de la
aplicación, otro, por ejemplo, de las imágenes, otro, de un algoritmo en particular
para resolver alguna situación en especial, y así sucesivamente.
Las bases de dato
Los servlets
Jacó, marzo del 2002.
Jacó, diciembre del 2002.
Descargar