Capac Unidad I IntroduccionJavaWeb

45
UNIVERSIDAD DE EL SALVADOR ADACAD INTRODUCCION A LA PROGRAMACION WEB EN JAVA Elaborado por: Rudy Chicas Jefe de ADACAD Ciudad Universitaria, abril de 2009

description

Programacion orientada a objetos, perfeccionamiento en ambito de programacion modular, java a nivel web utilizando servlets utilizando analisis detallados en estructuras secuenciales predeterminadas POO

Transcript of Capac Unidad I IntroduccionJavaWeb

Page 1: Capac Unidad I IntroduccionJavaWeb

UNIVERSIDAD DE EL SALVADOR

ADACAD

INTRODUCCION A LA PROGRAMACION WEB EN JAVA

Elaborado por:

Rudy Chicas

Jefe de ADACAD

Ciudad Universitaria, abril de 2009

Page 2: Capac Unidad I IntroduccionJavaWeb

INDICE

Introducción.................................................................................................................................1

1.Conceptos básicos de Java.....................................................................................................1

1.1.Variables y tipos de dato...................................................................................................1

1.2.Tipos primitivos de datos..................................................................................................1

1.3.Operadores.......................................................................................................................2

1.4.Estructuras de control.......................................................................................................3

1.5.Las clases.........................................................................................................................3

1.6.Construcción y destrucción de objetos.............................................................................5

1.7.Invocación de variables y métodos..................................................................................6

1.8.Paquetes...........................................................................................................................9

2.Conceptos avanzados y JSP.................................................................................................10

2.1.Conceptos básicos de JSP.............................................................................................10

2.2.Constructores..................................................................................................................20

2.3.Casting............................................................................................................................20

2.4.Arrays..............................................................................................................................21

2.5.La clase String................................................................................................................22

2.6.Ambito de las variables...................................................................................................23

2.7.Encapsulamiento............................................................................................................26

2.8.Excepciones....................................................................................................................30

2.9.Herencia..........................................................................................................................31

2.10.Modificadores................................................................................................................33

2.11.Finalización...................................................................................................................35

2.12.Polimorfismo.................................................................................................................35

2.13.Sobrecarga de métodos...............................................................................................36

2.14.Superposición de métodos...........................................................................................38

2.15.Clases abstractas.........................................................................................................40

2.16.Interfaces......................................................................................................................42

Bibliografía................................................................................................................................43

i

Page 3: Capac Unidad I IntroduccionJavaWeb

Introducción

Este capitulo está dedicado a la introducción a la Programación Orientada a Objetos en Java, particularmente a la programación Web a través de JSP.

La compresión de la estructura del lenguaje y el funcionamiento de la implementación de JSP es fundamental para el resto del contenido de esta capacitación, ya que JSF está fundamentada en la experiencia de desarrollo JSP.

El diseño de la capacitación intenta introducir de forma rápida al desarrollo Web con Java. Para ello es esencial que los participantes ahonden en algunos conceptos presentados en este trabajo, que no han sido profundizados por razones de tiempo como programación en Java estándar.

1. Conceptos básicos de Java

1.1. Variables y tipos de dato

En Java, el tipo de una variable puede ser:

● De tipo primitivo.● Una clase o interfaz.● Un array de elementos

En Php, los tipos de una variable pueden ser:

● De tipo primitivo.● De tipo compuesto (array u object).● De tipo especial (resourse o NULL).● Una clase o interfaz.

1.2. Tipos primitivos de datos

En la tabla 1.2.1 se describen los tipos primitivos de datos para Java. Para Php los tipos de datos primitivos son: boolean, integer, float y string. En Java, las cadenas de caracteres se almacenan en instancias de la clase String.

Existe un tipo especial de variables: las variables finales. Una variable final es en realidad una constante. En Java, una variable final se debe declarar de la siguientes forma:

final int constante = 6;

En Php, las constantes se definen de la siguiente manera:

const constante = 6;

1

Page 4: Capac Unidad I IntroduccionJavaWeb

Tipo Definición Rango

boolean Tipo de dato booleano true o false

char Caracter de 16 bits Todos los caracteres Unicode

byte Entero de 8 bits con signo -128 a 127

short Entero de 16 bits con signo -32.768 a 32.767

int Entero de 32 bits con signo -2.147.483.648 a 2.147.483.647

long Entero de 64 bits con signo -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807

float Punto flotante de 32 bit

double Punto flotante de 64 bit

Tabla 1.2.1. Tipos primitivos de datos en Java.

1.3. Operadores

Prioridad1 Operador Operandos Descripción Php

1 ++, -- Aritméticos Incremento decremento ++,--

1 ! Booleano Complemento lógico !

1 ~ Entero Complemento en binario ~

1 (tipo) Cualquiera Casts

2 *, /, % Aritméticos Multiplicación, división y módulo *,/,%

3 +, - Aritméticos Suma, resta +,-

3 + String Concatenación de cadenas .

4 << Entero Desplazamiento de bits hacia la izquierda

<<

4 >> Entero Desplazamiento de bits hacia la derecha

>>

5 <, <=, >, >= Aritméticos Comparación numérica <, <=, >, >=

5 instanceof Objeto Comparación de tipo instanceof

6 ==, != Tipos primitivos

Igualda y desigualdad ==, !=2

7 & Entero AND de bits &

7 & Booleano AND lógico and

1 La prioridad descrita en la tabla es la correspondiente a Java. Estas prioridades varían ligeramente para Php, además de no incluir algunos operadores que son propios de este lenguaje. Para más detalles acerca de la prioridad de los operadores en Php ver: http://www.php.net/manual/es/language.operators.precedence.php.

2 En Php también es posible usar <> como operador de desigualdad. Además se cuentan con dos operadores adicionales: idéntico (===) y no idénticos (!==).

2

Page 5: Capac Unidad I IntroduccionJavaWeb

Prioridad Operador Operandos Descripción Php

8 ^ Entero XOR de bits ^

8 ^ Booleano XOR lógico xor

9 | Entero OR de bits |

9 | Booleano OR lógico or

10 && Booleano AND condicional &&

11 || Booleano OR condicional ||

12 = Cualquiera Asignación =

12 *=, /=, %=, +=, -=, <<=, >>=, >>>=,

&=, ^=, |=

Cualquiera Asignación con operación. *=, /=, %=, +=, -=, <<=, >>=, >>>=,

&=, ^=, |=, .=

Tabla 1.3.1. Operadores en Java y Php

1.4. Estructuras de control

Las estructuras de control en ambos lenguajes son similares.

Java Php

if-else if-else

switch switch

while while

do-while do-while

for for

foreach

declare

goto

Tabla 1.4.1. Estructuras de control en Java y Php

1.5. Las clases

Para iniciar el estudio de la implementación de clases en Java, iniciaremos con una sola clase. En la figura 1.5.1 se muestra el diseño de la clase Alumno, que representa de forma abstracta a cualquier alumno de la Universidad.

Esto quiere decir que cualquier alumno tiene un carnet, nombre, apellidos y documento de identidad, a estos les llamamos atributos. Cuando asignamos valores a estos atributos para representar a un alumno en particular, estamos hablando de una instancia u objeto de esa clase.

3

Page 6: Capac Unidad I IntroduccionJavaWeb

Figura 1.5.1: Definición de la clase Alumno

Además de sus atributos, las clases también cuentan con métodos. Los métodos representan las operaciones que puede realizar una clase en particular. Estas operaciones debieran ser acciones relacionadas a la naturaleza y definición de la clase, aunque en este caso; a manera de ejemplo la clase Alumno cuenta con un método llamado mostrar, que devuelve un tipo void y no recibe ningún argumento.

La implementación de la clase Alumno en Php se verá como se muestra en la lista de código 1.5.1.

Lista de código 1.5.1: Implementación de la clase Alumno en Php.

<?php/** * author: rudy */ class Alumno{ public $carnet; public $apellidos; public $nombre; public $documento_identidad; function mostrar(){ echo $this->nombre . "<br>"; echo $this->apellidos . "<br>"; echo $this->carnet . "<br>"; echo $this->documento_identidad; } }?>

La implementación en código Java, se muestra en la lista de código 1.5.2.

4

Page 7: Capac Unidad I IntroduccionJavaWeb

Lista de código 1.5.2: Implementación de la clase Alumno en Java.

/** * author: rudy */class Alumno{

String nombre;String apellidos;String carnet;String documentoIdentidad;

void mostrar(){System.out.println(nombre);System.out.println(apellidos);System.out.println(carnet);System.out.println(documentoIdentidad);

}}

Las piezas de código 1.5.1 y 1.5.2 son análogas. Sin embargo, para ir introduciendo el uso del código Java, se ha implementado en Java estándar, que podrá ser ejecutado desde la línea de comandos de cualquier sistema operativo que tenga instalada la máquina virtual de Java.

Nótese también que en Php se requiere el uso del operador $this. Esto se debe que la flexibilidad del lenguaje en cuanto al uso de variables sin que estas tengan que ser declaradas, vuelve necesario especificar a qué variable se está haciendo referencia.

En Java existen una serie de convenciones para el uso del lenguaje. Las más importantes y básicas son las definidas por Sun Microsystems en sus Convenciones de código para el lenguaje de programación Java. Estas convenciones son complementadas en las especificaciones de cada producto basado en Java, cuando es necesario.

1.6. Construcción y destrucción de objetos.

En Java, la construcción de un objeto se hace con el operador new, así:

Alumno juan = new Alumno();

El proceso de instanciar una clase en similar en Php:

$juan = new Alumno();

Nótese que Java, por ser un lenguaje más rígido en la sintaxis, exige que se especifique el tipo de

5

Page 8: Capac Unidad I IntroduccionJavaWeb

dato que se le asignará a la variable, en este caso la clase Alumno.

En ambos lenguajes, la destrucción de los objetos se realiza de forma automática. En Php, se destruyen los objetos cuando se han eliminado todas la referencias hacia él. En Java, existe un recolector de basura, que se encarga de buscar objetos no utilizados y eliminarlos.

1.7. Invocación de variables y métodos.

La invocación de variables y métodos de un objeto puede realizarse de las siguientes formas:

• El objeto se encuentra instanciado y por lo tanto listo para invocar a sus variables y métodos.

• La variable o método es de tipo estática, por lo que puede invocarse sin necesidad de instanciar un objeto.

Las variables y métodos estáticos se estudiarán en la sección 2.9, por lo que nos centraremos en la invocación de variables y métodos de objetos instanciados. Para ello, continuaremos con la implementación en Java estándar de la clase Alumno.

Si deseamos que una clase tenga la capacidad de ejecutar su propio código, deberá contar con un método main. Cuando ejecutamos una clase, la máquina virtual de Java busca un método main para ejecutar el código, sino lo encuentra devolverá un error.

6

Page 9: Capac Unidad I IntroduccionJavaWeb

Lista de código 1.7.1: Implementación de clase Alumno ejecutable en Java

class Alumno{String nombre;String apellidos;String carnet;String documentoIdentidad;

void mostrar(){System.out.println(nombre);System.out.println(apellidos);System.out.println(carnet);System.out.println(documentoIdentidad);

}

public static void main(String args[]){Alumno alumno = new Alumno();

alumno.nombre = "Brian Virgilio";alumno.apellidos = "Hernández Jimenez";alumno.carnet = "HJ09001";alumno.documentoIdentidad = "01010101-0";

alumno.mostrar();}

}

La compilación y ejecución de este código se deberá realizar de la siguiente forma:

rudy@ada-laptop:~$ javac Alumno.javarudy@ada-laptop:~$ java Alumno

Brian VirgilioHernández JimenezHJ0900101010101-0

rudy@ada-laptop:~$

En Java, los nombres de los archivos deben ser igual al nombre de la clase que almacenan. Solo puede haber una clase en un archivo, excepto cuando esa clase tenga clases internas.

El compilador javac creará un archivo de extensión .java, que es el que se usará para ejecutarlo a través del comando java.

Si deseáramos que la clase reciba como parámetros los valores desde la consola, deberemos utilizar el arreglo args para recibir los parámetros. En la línea de comandos se especificarán los parámetros separados por espacios en blanco.

7

Page 10: Capac Unidad I IntroduccionJavaWeb

Lista de código 1.7.2: Implementación de clase Alumno en Java que recibe parámetros.

class Alumno{String nombre;String apellidos;String carnet;String documentoIdentidad;

void mostrar(){System.out.println(nombre);System.out.println(apellidos);System.out.println(carnet);System.out.println(documentoIdentidad);

}

public static void main(String args[]){Alumno alumno = new Alumno();

alumno.nombre = args[0];alumno.apellidos = args[1];alumno.carnet = args[2];alumno.documentoIdentidad = args[3];

alumno.mostrar();}

}

rudy@ada-laptop:~$ javac Alumno.javarudy@ada-laptop:~$ java Alumno Virgilio Henández HJ09001 010101-0

VirgilioHenándezHJ09001010101-0

rudy@ada-laptop:~$

Nótese que solamente se enviaron el primer nombre y el primer apellido del alumno. Esto es porque los parámetros se reciben separados por espacios en blanco, lo que significa que el segundo nombre del alumno hubiera sido almacenado en el lugar del apellido. Separar los valores recibidos habría requerido que se modificara la estructura de la clase, debiendo recibirse 6 parámetros.

Hasta ahora se ha abordado la invocación de variables y métodos dentro de la misma clase en Java estándar, lo que ha representado la necesidad de crear una clase ejecutable (clase que contiene un método main). Este tipo de programación es muy frecuente en sistemas de escritorio (cliente-servidor o stand alone). En proyectos de desarrollo Web esto no es muy común; ya que las páginas pueden contar con código Java embebido o llamadas a clases que se encuentran en librerías de clases o que forman parte de la lógica del negocio de la aplicación.

8

Page 11: Capac Unidad I IntroduccionJavaWeb

1.8. Paquetes

Un paquete es un conjunto de clases e interfaces relacionados. Este concepto tiene a su base la idea de agrupar de forma ordenada el código que se genera en un proyecto de desarrollo, generalmente bajo el criterio de subsistemas. Estos paquetes posteriormente pueden ser utilizados como librerías para otros proyectos.

La forma en como se define a qué paquete pertenecerá una clase es con el uso de la palabra reservada package. Por ejemplo, si deseáramos que la clase Alumno fuera empaquetada en un paquete llamado ues, tendríamos que escribir al inicio de la clase la instrucción

package ues;

Cuando necesitamos hacer uso de un paquete usamos la palabra reservada import. El import es un equivalente a include o include_once de Php. Por ejemplo, si quisiéramos hacer uso de la clase Connection del paquete sql de java escribiremos:

import java.sql.Connection;

Si quisiéramos usar todas las clases del paquete, deberemos usar:

import java.sql.*;

9

Page 12: Capac Unidad I IntroduccionJavaWeb

2. Conceptos avanzados y JSP

2.1. Conceptos básicos de JSP

JSP (Java Server Pages) es una tecnología Java que permite generar contenido Web de forma dinámica. JSP es una forma extendida de servlets, que tienen como componentes principales: acciones JSP, directivas, declaraciones, expresiones y scriptlets.

• Las acciones JSP (JSP actions o tags JSP) ejecutan una serie de funciones que extienden las capacidades de JSP. Las acciones usan las reglas XML como reglas sintácticas, y son usados para manejar componentes JavaBean.

• Las directivas son instrucciones que son procesadas por el motor JSP cuando la página es compilada a un servlet. Las directivas son utilizadas para definir instrucciones de nivel de página, insertar datos de archivos externos y especificar librerías de tags personalizados. Las directivas se definen entre <%@ y %>.

• Las declaraciones son similares a la declaración de variables en Java estándar. Define variables para su uso posterior en expresiones y scriptlets.

• Las expresiones son variables o constantes insertadas en los datos retornados por el servidor Web. Se definen con <%= y %>.

• Los scriptlets son bloques de código Java embebido en la JSP. El código scriptlet es insertado textualmente en la página. Se define entre <% y %>.

La ejecución de un servlet ocurre cuando un cliente realiza una petición (request) a una página. El navegador enviará la petición al servidor de aplicaciones (contenedor de servlets), buscará el servlet compilado (clase java) y lo ejecutará. Si el servlet no se encuentra compilado, busca el archivo jsp, lo compila y lo ejecuta. El resultado de la ejecución del servlet es combinado con las etiquetas HTML, XML, XHTML o cualquier otra que haya sido definida para ejecutarse del lado del cliente, y se envía la respuesta (response).

Para ilustrar los conceptos vistos hasta ahora, realizaremos un ejercicio práctico. El ejercicio tratará de resolver el problema de crear un usuario, con sus respectivos datos personales y los perfiles que sean necesarios para dicho usuario. El esquema de base de datos en el que se almacenarán los datos se muestra en la figura 2.1.1.

10

Page 13: Capac Unidad I IntroduccionJavaWeb

Figura 2.1.1: Modelo relacional para la gestión de usuarios (Ejemplo).

Omitiremos por el momento el diseño de clases del que deberíamos partir para programar las páginas Web para hacer un análisis sobre las alternativas que tenemos. Partiremos de la idea de registrar primero los datos personales del usuario, luego crear el registro del usuario y finalmente los perfiles que correspondan.

Aunque en nuestro caso usaremos un proyecto ya construido, vale la pena dar un vistazo a la forma en la que se crea un proyecto Web. Para ello abrimos NetBeans y seleccionamos en el menú archivo, la opción New project (o hacemos click en el botón New project).

11

Page 14: Capac Unidad I IntroduccionJavaWeb

Seleccionamos Web Application y presionamos Next. Esto abrirá una nueva ventana en la que se debe especificar el nombre, la ubicación, la versión de Java en la que estará basado y el servidor de aplicaciones sobre el que se desplegará.

12

Page 15: Capac Unidad I IntroduccionJavaWeb

Una vez hecho esto, hay que especificar los marcos de trabajo (frameworks) sobre los que deseamos basar nuestra aplicación. En este caso no seleccionaremos ninguno, lo que significa que deseamos construir una aplicación JSP estándar.

13

Page 16: Capac Unidad I IntroduccionJavaWeb

Una vez creada la aplicación, escribimos el código de las clases que conforman el ejemplo. Obsérvese que NetBeans genera automáticamente la página index de la aplicación.

14

Page 17: Capac Unidad I IntroduccionJavaWeb

Las clases que corresponden a la lógica de negocio de la aplicación deben ser escritas en el grupo de objetos Source Packages.

Definiremos ahora el paquete en el que se encontrarán las clases de la aplicación. Hacemos click derecho sobre Source Package y seleccionamos la opción New y luego Java Package. Esto nos mostrará una pantalla en la que definiremos el nombre y la ubicación del paquete.

15

Page 18: Capac Unidad I IntroduccionJavaWeb

Puede observarse que el nombre del paquete cumple con el estándar de código Java que se refiere a que el nombre de los paquetes está precedido por el dominio de la organización.

Una vez creado el paquete, creamos la clase que deseamos escribir. De igual manera que con el paquete, hacemos click derecho sobre el paquete, seleccionamos la opción New y luego la opción Java Class.

16

Page 19: Capac Unidad I IntroduccionJavaWeb

Esto nos mostrará una ventana en la que especificaremos el nombre y la ubicación de la clase.

17

Page 20: Capac Unidad I IntroduccionJavaWeb

Volvamos ahora al proyecto que ya tenemos disponible. Para bajar el proyecto desde bazaar ejecutamos:

rudy@ada-laptop:~$ cd NetBeansProjects/rudy@ada-laptop:~/NetBeansProjects$ bzr checkout sftp://[email protected]/home/java/repositorio/[email protected]'s password:rudy@ada-laptop:~/NetBeansProjects$

Una vez que lo tenemos descargado, abrimos el proyecto con NetBeans. File->Open project o Archivo->Abrir proyecto según sea el caso.

Como se mencionó antes, iniciaremos sin detenernos aun a pensar en un diseño de clases que nos permita tener una mayor claridad sobre la solución. Según el modelo de datos presentado, un usuario no puede ser agregado si antes no se ha creado su registro de datos personales en la tabla persona. Es por ello que iniciaremos con el mantenimiento a la tabla persona en la JSP persona.jsp.

Como es lógico, lo primero que hay que editar es el código HTML de la página que servirá de interfaz.

18

Page 21: Capac Unidad I IntroduccionJavaWeb

Obsérvese que el fragmento de código de lista sin orden está vinculado a la definición de comportamiento que describe la hoja de estilo importada.

La página inicia con la definición del tipo de código que contiene <%@page contentType="text/html" pageEncoding="UTF-8"%>. Este estándar ha sido incorporado al desarrollo Web como una forma de hacer más eficiente la interpretación del tipo de código que contiene el documento y la codificación que se utiliza.

La directiva <%@ page import="sv.edu.ues.adacad.capacitacion.Persona" %> es el equivalente a un include_once de Php. Incorpora al contexto de la página la definición de la clase Persona que se encuentra en el paquete sv.edu.ues.adacad.capacitacion y es necesario para poder realizar operaciones con esta clase.

El código Java embebido o scriptlet se encuentra delimitado por los marcadores <% y %>, que son el equivalente de <?php y ?> de Php.

Junto con algunas etiquetas HTML o XHTML se encuentran también invocaciones a los valores de las variables definidas en el servlet de la página, llamadas expresiones. La expresión <%=accion%> en Java es equivalente a <?php echo accion; ?> de Php

Examinemos ahora el código del scriptlet. El código tiene las siguientes características:

1. Manejo de eventos a través de la variable accion. La variable accion, que se encuentra asociada a un campo oculto del formulario, permite determinar qué acción hay que realizar (crear un nuevo registro de persona o actualizarlo). La variable caption sirve para manejar el rótulo del botón del formulario para que el usuario sepa que evento se disparará cuando se realice un submit del formulario.

2. Manejo de la navegación a través de la variable ref y las etiquetas asociadas a la hoja de estilo. Esto permite controlar el momento en que el usuario puede pasar a la siguiente página.

3. Asignación de valores a los controles HTML. El problema clásico en la edición de formularios HTML es que una vez realizado el submit los controles pierden el valor que se les asignó antes del submit. Esto se resuelve asignando los valores que han sido enviados vía POST y reasignándolos cuando se recarga la página.

Otro método es hacer un redireccionamiento a la página (ella misma) agregando como parámetro de tipo GET el ID del valor que se ingresó. Esto significaría que para cada submit se ejecutará una consulta a la base de datos buscando el registro que el ID que se reciba. La tercera opción es una combinación de las dos anteriores.

4. Asignación de valores a los atributos de la clase Persona para que sean almacenados en la base de datos. La clase persona cuenta con los métodos crear y actualizar a través de los que se almacena y se actualizan los datos en la base de datos. Si la instancia de la clase ya existe en la base de datos, devolverá un error a través del arreglo de tipo String mensaje en caso de que se desee ingresar a la base de datos. En caso de que el formulario se encuentre en modo de actualización, simplemente actualizará los campos.

Examinemos ahora el código de la clase Persona. La clase es básicamente una representación con orientación a objetos de la tabla persona en la base de datos. Hace uso de la clase Conexion, para

19

Page 22: Capac Unidad I IntroduccionJavaWeb

conectarse a la base de datos y de las clases PreparedStatement y ResultSet para realizar las validaciones y operaciones correspondientes en los métodos crear y actualizar.

2.2. Constructores

En casi todos los lenguajes orientados a objetos, cuando no se define un constructor de forma explícita, el compilador crea un constructor por defecto para esa clase. Sin embargo, cuando un constructor es definido de forma explícita, deben ser definidos todas las veces que sea necesario, puesto que el compilador no creará ninguno por defecto.

En Java, las reglas para definir un constructor de forma explícita son las siguientes:

1. El nombre del constructor es el mismo que el de la clase.

2. El constructor puede definirse como un método que no devuelve ningún tipo de dato, incluyendo void.

Como ejemplo, supongamos que quisiéramos definir un constructor a la clase Persona. El código de ese método quedaría de la siguiente manera:

public Persona(int idPersona, String nombre, String apellidos, String documentoIdentidad){ this.idPersona = idPersona; this.nombre = nombre; this.apellidos = apellidos; this.documentoIdentidad = documentoIdentidad; }

Este constructor crea una instancia de la clase inicializando los atributos de la clase con los valores que reciba como parámetro. Este tipo de constructores es muy común cuando se tienen procesos en los que las instancias de clase se forman a partir de valores preelaborados.

2.3. Casting

La operación de Casting permite cambiar el valor de un objeto o tipo primitivo a otro tipo diferente. Las consideraciones que hay que tomar para realizar castings son las siguientes:

1. Los castings entre tipos primitivos solamente pueden realizarse de tipos de datos más pequeños a más grandes. Esto quiere decir aquellos tipos de datos que ocupan menos bits a los que ocupan más bits. En este caso, el casting es automático.

2. Algo similar ocurre con el casting entre objetos. Solamente puede realizarse entre objetos que tengan alguna relación jerárquica entre ellos. Si se desea convertir un objeto de una subclase a una superclase, esto se realizará automáticamente como consecuencia del polimorfismo

20

Page 23: Capac Unidad I IntroduccionJavaWeb

que será explicado en la sección 2.11.

Si deseamos hacer un casting de una expresión a un tipo de dato debemos especificar explícitamente el tipo de dato al que estamos convirtiendo. Por ejemplo:

floar a = (float) 7/6;

En el casting entre los objetos es necesario especificar la clase a la que deseamos convertir ese objeto. Por ejemplo, la expresión CargoBean optCargo = (CargoBean) cargos.next(); contenida en la JSP perfil.jsp, es un cast del objeto que devuelve en el iterador cargos a la clase Cargo. Este objeto es de tipo Object, que es la clase primaria de toda la jerarquía de clases de Java.

El casting entre los objetos y tipos primitivos no es posible. Sin embargo, existen un conjunto de clases llamadas “evoltorio” (wrapper classes), que tienen como objetivo modelar los tipos primitivos como clases. Algunas de estas clases son: Integer, Float y Double. En la pieza de código 2.3.1 podemos observar el uso de la clase envoltorio Integer para realizar un casting (parse) del valor String recibido como parámetro de la página a al tipo primitivo int.

Lista de código 2.3.1: Uso de clase envoltorio Integer.

if (request.getParameter("id_persona") != null) {

persona = persona.buscarPersona(Integer.parseInt(request.getParameter("id_persona"))); nombre = persona.nombre; apellidos = persona.apellidos; docIdentidad = persona.documentoIdentidad; idPersona = request.getParameter("id_persona");

accion = "editar"; caption = "Actualizar"; ref = "usuario.jsp?id_persona=" + persona.idPersona;}

2.4. Arrays

Un array es una colección de elementos ordenados referenciados por un índice, que es la posición en la que se encuentra cada elemento. Un array es un objeto de Java, por lo que se instancia y se trata como tal.

Cuando definimos un arreglo, sus valores son inicializados de acuerdo a los siguientes criterios:

• 0 para los numéricos

• false para los booleanos

21

Page 24: Capac Unidad I IntroduccionJavaWeb

• '\0' para los caracteres

• null para los objetos

Como ejemplo puede observarse el arreglo mensaje que es utilizado por todas las JSP de la aplicación de ejemplo. A diferencia de la forma típica de definir un arreglo, el tamaño del arreglo mensaje se define de forma implícita, especificando su valor por defecto a través de la sentencia

String mensaje[] = {“”,””,””};

Esto es porque al tratarse de un arreglo de objetos, que de no ser inicializado, almacenaría valores nulos por defecto.

2.5. La clase String

La clase String es la que permite realizar operaciones con cadenas de caracteres, por lo que como en cualquier lenguaje, tiene una vital importancia.

Al igual que para cualquier clase que forme parte del JDK, podemos revisar la forma en como se ha implementado la clase String consultando el API de Java, ingresando al sitio: http://java.sun.com/javase/6/docs/api/. Este es el API para la versión 6 del JDK, si quisiéramos ver el API de otras versiones habrá que especificarlo en http://java.sun.com/reference/api.

22

Page 25: Capac Unidad I IntroduccionJavaWeb

En el API podemos observar los atributos y las operaciones (métodos) que la clase tiene disponible. En la JSP persona.jsp, podemos observar como se utiliza el método equals para determinar si una cadena es igual a otra.

if(request.getParameter(“accion”).equals(“crear”))

request.getParameter(“accion”) devuelve el valor del parámetro accion que recibe la página como una cadena de caracteres que posteriormente es comparada con el argumento (otra cadena de caracteres). El método devuelve true, si la cadena recibida es equivalente a la cadena que ejecuta el método, devuelve falso si no es así.

El API de Java está hecho con JavaDoc, la herramienta estándar para la generación de documentación de clases en formato HTML, en el proyecto de ejemplo la clase Persona ha sido documentada para generar la documentación de las clases a través de JavaDoc.

2.6. Ambito de las variables

Recordemos que el tipo de una variable puede ser:

1. Uno de los tipos primitivos.

2. Una clase o interfaz.

3. Un array de elementos

Se denomina ámbito de una variable a la zona del código donde esa variable es visible y por lo tanto puede ser utilizada.

Cuando llamamos una variable Java busca una definición de esa variable en el ámbito actual en que se encuentra, por ejemplo un ciclo. Si no la encuentra, busca en el siguiente nivel hasta llegar a la definición del método actual. Si tampoco aparece, es que no se trata de una variable local, por lo que sale del método y busca una variable de instancia o de clase con ese nombre. En caso de que tampoco la encuentre, sube a la superclase a buscarla.

Supongamos que tenemos una variable local y otra de instancia, ambas con el mismo nombre. Diremos que la variable local es de ámbito o alcance más corto. Entonces, la variable local enmascara a la de instancia.

Con esto podemos diferenciar las variables por su alcance de la siguiente manera:

1. Variable local. Es la que está definida dentro de la definición de un método. El compilador la reconocerá solamente dentro del método.

23

Page 26: Capac Unidad I IntroduccionJavaWeb

2. Variables de instancia. Son los atributos de las clases. Estas variables son visibles desde cualquier parte de la clase.

3. Variables de clase. También son atributos, se diferencian de las variables de instancia en que están especificadas como variables estáticas con la palabra reservada static. Esto quiere decir que todas las instancias de esa clase reconocerán a esa variable con un único valor.

Revisemos el método buscarPersona de la clase Persona mostrado en la pieza de código 2.6.1. La primera observación que se puede hacer es que la variable idPersona que se recibe como parámetro enmascara la variable idPersona que es miembro (atributo) de la clase. En otras palabras, cuando se hace referencia a idPersona dentro del método, se estará haciendo referencia a la variable local idPersona no al atributo de la clase.

Si quisiéramos hacer referencia al atributo idPersona de la clase, deberemos especificar que nos referimos a este atributo a través del operador this.

Otra observación importante es la instancia persona que se hace al interior de la condición. El ámbito de esta instancia tiene alcance únicamente dentro de la condición. Si quisiéramos hacer referencia a esa instancia fuera de la condición, deberemos de declararla fuera de la condición. En este caso en particular, escribir por ejemplo persona.nombre = “Juan”; no devolverá un error, porque el compilador interpretará esa referencia, no como una referencia a la instancia persona declarada dentro del if, sino como el atributo nombre de la clase misma, que es en la que se está ejecutando el código.

24

Page 27: Capac Unidad I IntroduccionJavaWeb

Lista de código 2.6.1: Método buscarPersona de la clase Persona.

public Persona buscarPersona(int idPersona) { Connection con; PreparedStatement prepStat; ResultSet result = null; String sql; Persona persona = null;

sql = "SELECT id_persona, nombre, apellidos, documento_identidad FROM persona WHERE id_persona = ?";

con = Conexion.getConecction(); try { prepStat = con.prepareStatement(sql); prepStat.setInt(1, idPersona);

result = prepStat.executeQuery(); if (result.next()) { persona = new Persona(); persona.idPersona = result.getInt(1); persona.nombre = result.getString(2); persona.apellidos = result.getString(3); persona.documentoIdentidad = result.getString(4); }

} catch (SQLException e) { System.out.println("Error en la consulta SQL " + sql + "" + e.getMessage()); } finally { Conexion.closeConnection(con); }

return persona; }

La pieza de código 2.6.2 si devolverá un error al intentar invocar a la variable a fuera del ciclo.

Lista de código 2.6.2: Ejemplo de interpretación del ámbito de las variables en Java

public string prueba(){private int i;

if(cond){int a = 0;

}

i = 2;a = 2;

}

25

Page 28: Capac Unidad I IntroduccionJavaWeb

2.7. Encapsulamiento

Volvamos a la aplicación de ejemplo para analizar la implementación de la página persona.jsp. Una de las primeras cosas que saltan a la vista es la estructura de la JSP. La necesidad de controlar los eventos y la navegación nos obligan a tener tres niveles de if anidados. Otra característica es la cantidad muy grande de variables que se están utilizando para controlar los valores por defecto de los controles del formulario. Esto sin mencionar el problema que representa el hecho que los atributos de la clase Persona son referenciados directamente en la página.

Supongamos que deseamos validar el valor del documento de identificación, tendríamos dos opciones: hacerlo en el servlet, lo que significaría que cada vez que queramos validar este atributo tendremos que escribir el mismo segmento de código, o hacerlo en el método antes de insertar o actualizar el registro en la base de datos. Esto último plantea el problema de que la validación estará disponible única y exclusivamente para estos métodos. El encapsulamiento es un concepto que está relacionado a los problemas planteados anteriormente.

En Java, el encapsulamiento se realiza a través de JavaBeans. Un JavaBean es una clase encapsulada que cumple con las siguientes condiciones:

1. Sus atributos son privados.

2. Los valores de los atributos son accedidos desde métodos get (obtener) y set (asignar).

Un ejemplo de esto es la clase UsuarioBean. Veamos como esto modifica la forma en la que implementamos la interfaz del usuario (usuario.jsp).

Lista de código 2.7.1: Segmento de código de la página usuario.jsp utilizando Tags JSP.

<jsp:useBean id="usuario" class="sv.edu.ues.adacad.capacitacion.Usuario" scope="request"/>

<jsp:setProperty name="usuario" property="idPersona" param="id_persona"/><jsp:setProperty name="usuario" property="usuario" param="usuario"/><jsp:setProperty name="usuario" property="clave" param="clave"/>

En la pieza de código 2.7.1 puede observarse el uso de las etiquetas jsp:UseBean y jsp:setProperty. Su operación es la siguiente:

1. La etiqueta useBean indica a Java que tiene que crear una instancia de la clase UsuarioBean. Esta instancia tendrá como identificador (nombre de la instancia) usuario. Además, esta instancia solamente tiene vigencia (scope) para la petición (request) de la página.

2. La etiqueta setProperty indica a Java que asigne los valores recibidos como parámetros a los atributos indicados. Se especifican: el nombre del bean al que pertenece la propiedad, el nombre de la propiedad y el nombre del parámetro cuyo valor es el que se asignará.

La asignación de los valores se hace a través de los métodos set del bean. Al igual que el método tradicional (el usado en la JSP persona), es posible haber llamadas a los métodos de la instancia de la clase. Si la clase no cuenta con métodos set, la etiqueta devolverá un error.

26

Page 29: Capac Unidad I IntroduccionJavaWeb

Al comparar el código entre ambas páginas podemos observar que en usuario.jsp no solamente se reducen las líneas de código necesarias para realizar el mismo proceso que en alumno.jsp, sino también que se reducen los niveles de las condiciones anidadas. Además de eliminarse las variables de control de los valores de los controles del formulario. Por otro lado, se elimina el problema de integridad de la clase que almacenará los datos en la base de datos y se asegura la reutilización de código.

Por último, nótese que el parámetro id_persona, que es enviado desde la página persona una vez que se ha creado el registro persona, sirve para saber para qué persona se está creando el usuario. En términos de modelo relacional este valor es una llave foránea de la tabla usuario. En el modelo de clases que va resultando de nuestra solución, esto es un atributo de la clase UsuarioBean, que no tiene ninguna relación con la clase Persona.

Esto ya nos da una idea de como podría ser el diseño de clases que requerimos. En general, beans que permitan realizar operaciones de almacenamiento y actualización en la base de datos. Si continuamos con esta lógica, el diseño de clases resultante será una conjunto de clases sin ninguna relación entre sí, como se muestra en la figura 2.7.1.

Veamos ahora lo que ocurre al continuar reproduciendo esta lógica de diseño para el perfil. La JSP perfil.jsp muestra como de la misma forma que con usuario, no requerimos muchas líneas de código, variables, etc. para programar una interfaz de mantenimiento a la tabla perfil. Sin embargo, resulta difícil obtener la lista de perfiles para el usuario en cuestión. Esto es porque la tabla perfil solamente almacena las llaves foráneas de las otras tablas, no su contenido. Habría que utilizar los atributos de la entidad para obtener instancias de las clases que representan los valores de esos atributos. Como es lógico, eso representa escribir más código con muy pocas posibilidades de reutilizarse.

En resumen, tenemos un diseño de clases en el que no hay relación alguna entre ninguna clase, una interfaz de usuario que, a pesar de manejar de forma simple y sencilla el despliegue de datos, representa un costo muy elevado en términos de líneas de código y por ende memoria en tiempo de ejecución.

27

Page 30: Capac Unidad I IntroduccionJavaWeb

Figura 2.7.1: Beans independientes con capacidad para realizar operaciones en la base de datos.

Tratemos de expresar en términos reales la relación entre PerfilBean y el resto de clases. Si vemos el modelo relacional la tabla perfil es una tabla relacional. Esto nos da una idea de lo que podría representar esta entidad en el modelo de clases, mostrada en la figura 2.7.2.

Figura 2.7.2: Diseño de clases para el ejemplo con clase Perfil como clase de asociación.

28

Page 31: Capac Unidad I IntroduccionJavaWeb

Esto significa que la clase perfil es una clase de asociación. Esta clase tiene como atributos instancias de otras clases, aunque de igual forma que el resto representa a un registro de la tabla perfil.

Al implementar esta clase como se plantea en el diseño, puede observarse que es más sencillo desplegar los datos que necesitamos para la interfaz propuesta.

Lista de código 2.7.2: Bloque de código que genera la lista de perfiles para un usuario en la JSP perfilAsoc.jsp.

<tbody> <!-- Lista de perfiles para el usuario --> <%while (perfiles.hasNext()) { PerfilBeanAsociacion iPerfil = (PerfilBeanAsociacion) perfiles.next(); %><tr> <td><a href="perfil.jsp<%=ref+"&id_perfil=" + iPerfil.getIdPerfil()%>"><%=iPerfil.getIdPerfil()%></a></td> <td><%=iPerfil.getCargo().getFuncional()%></td> <td><%=iPerfil.getEstructuraOrganizativa().getNombre()%></td> <td><%=iPerfil.getActivo()%></td> </tr> <% } %></tbody>

Por lógica, nuestro diseño final de clases debería asegurar que la clase PersonaBean esté relacionada no solamente con PerfilBeanAsociacion, sino también con UsuarioBean. El diseño resultante es el que se muestra en la figura 2.7.3.

Figura 2.7.3: Diseño de clases definitivo para el ejemplo.

29

Page 32: Capac Unidad I IntroduccionJavaWeb

2.8. Excepciones

Las excepciones permiten capturar errores en la ejecución de un programa. Las excepciones son clases Java que en su mayoría son heredadas de la clase Exception.

En el ejemplo que nos ocupa podemos observar el uso de la clase SQLException para dar tratamiento a los errores que puedan suceder durante el acceso a la base de datos. El tratamiento consiste en imprimir el error en la consola del contendor de servlets.

En la pieza de código 2.15.1 podemos observar que el código susceptible a error debe ser escrito entre las llaves que corresponden a la sentencia try. Para cada try debe haber al menos un catch, que es un segmento de código en el que se define el tratamiento que se dará al error, de acuerdo a la excepción presentada.

Lista de código 2.15.1: Bloque try-catch para el método buscarPerfiles de la clase PerfilBeanAsociacion

try { prepStat = con.prepareStatement(sql); prepStat.setInt(1, idPersona);

result = prepStat.executeQuery(); while(result.next()) { PerfilBean perfil = new PerfilBean(); perfil.setIdPersona(idPersona); perfil.setIdPerfil(result.getInt(1)); perfil.setEstructuraOrganizativa(result.getInt(2)); perfil.setActivo(result.getInt(3)); perfil.setIdCargo(result.getInt(4)); perfiles.put(i++, perfil); }

} catch (SQLException e) { System.out.println("Error en la consulta SQL " + sql + " " + e.getMessage()); } finally{ Conexion.closeConnection(con); }

La capacidad para capturar excepciones está determinada por el hecho de que los métodos que invocamos tienen la capacidad de lanzarlas. Esta capacidad se logra especificando en la firma del método la o las excepciones que puede lanzar. Para ello se utiliza la palabra reservada throws. Por ejemplo, si quisiéramos hacer que el método buscarPerfiles de la clase PerfilBeanAsociacion no capturara la excepción, sino que la lanzara al siguiente nivel de codificación, la firma del método sería como el siguiente:

public Collection<PerfilBean> buscarPerfiles() throws SQLException{...

30

Page 33: Capac Unidad I IntroduccionJavaWeb

Esto significaría que los bloques try, catch y finally no sería necesarios, puesto que ahora el método será capaz de lanzar excepciones. Sin embargo, esto obliga a quien haga uso de nuestro método de colocar la llamada al método entre un bloque try-catch para capturar la excepción.

Lista de código 2.15.2: Uso del método buscarPerfil cuando se traslada la Excepción.

try{ Iterator perfiles = perfil.buscarPerfiles().iterator(); } catch(SQLException e){ System.out.println("Error"); }

El bloque finally se ejecuta independiente de cual fue el resultado de la ejecución del bloque try. Es una forma de asegurar que un conjunto de instrucciones se ejecuten independientemente si se generó un error o no, sin necesidad de escribir dos o más veces el mismo código.

2.9. Herencia

En Java, al igual que en la mayoría de los lenguajes orientados a objetos, las clases operan dentro de una jerarquía de clases. Cada clase tiene únicamente una clase por encima de ella, llamada superclase. Puede además tener ninguna o varias clases por debajo de ella, a estas clases se les llama subclases.

En nuestro ejemplo no tenemos clases relacionadas por jerarquía. Podríamos hacerlo si analizamos la relación entre persona y usuario. De forma simple podemos decir que un usuario es un tipo especial de persona, puesto que un usuario es una persona; aunque no todas las personas están obligadas a tener un usuario.

Esto plantea una relación que se puede observar en la figura 2.8.1. En este modelo, la subclase hereda todas los atributos y métodos de la clase base. Esto quiere decir que la clase UsuarioBeanHereda, como subclase de PersonaBean, tendría además de los propios, los atributos: idPersona, nombre, apellidos y documentoIdentidad.

Este diseño se vería como se muestra en la lista de código 2.8.1. Podemos observar que se usa la palabra reservada extends para definir que la clase UsuarioBeanHereda extiende a la clase PersonaBean, es decir, que es una subclase de esta.

31

Page 34: Capac Unidad I IntroduccionJavaWeb

Figura 2.8.1: Relación jerárquica entre la clase Persona y Usuario.

Lista de código 2.8.1: Implementación de la clase UsuarioBeanHereda como subclase de PersonaBean.

package sv.edu.ues.adacad.capacitacion;

/** * * @author rudy */public class UsuarioBeanHereda extends PersonaBean {

private String usuario; private String clave;

public String getUsuario() { return usuario; }

public void setUsuario(String usuario) { this.usuario = usuario; }

public String getClave() { return clave; }

public void setClave(String clave) { this.clave = clave; }

...

}

32

Page 35: Capac Unidad I IntroduccionJavaWeb

En el modelo de clases, el impacto que esto tendría se puede ver en la figura 2.8.2. Desde el punto de vista de implementación de los métodos de acceso a la base de datos, esto significaría que la clase PersonaBean tendría un método crear y un método actualizar y la clase UsuarioBeanHereda deberá superponer estos métodos.

Figura 2.8.2: Modelo de clases con relación jerárquica entre persona y usuario.

2.10. Modificadores

Los modificadores son palabras reservadas que permiten cambiar la definición y el comportamiento de las clases, métodos y variables. Los más importantes son los modificadores de control de acceso a una clase, método o variable: public, protected y private. Veremos primero los que podríamos llamar modificadores de implementación.

1. El modificador static. Se utiliza para crear métodos y variables de clase. Los atributos y métodos estáticos pueden ser invocados aunque la clase no haya sido instanciada.

2. El modificador abstract para crear clases, métodos y variables abstractas.

3. El modificador final para indicar que finaliza la implementación de una clase, método o variable.

33

Page 36: Capac Unidad I IntroduccionJavaWeb

En el ejemplo que nos ocupa veremos que los métodos de la clase Conexion son estáticos. Esto quiere decir que pueden ser invocados sin que la clase sea instanciada. A los atributos estáticos también se les llama de clase porque, además de la característica anterior, los valores son comunes a todas las clases. En otras palabras, si existen dos instancias de una clase que tenga una atributo estático y una de ellas modifica su valor, la otra instancia también verá ese valor modificado. Esto es especialmente útil cuando se desea tener variables globales a nivel de aplicación que solamente sean reconocidas por una clase.

El control de acceso a clases se refiere a la forma en que se define la visibilidad de una clase respecto a otra que se encuentra en el mismo paquete o en otro. Los modificadores de control de acceso son:

1. Protección friendly o de paquete. Es la protección por defecto. Las clases, métodos y variables con protección de paquete son visibles a todas las demás clases del mismo paquete, pero no fuera de él.

2. Protección pública (public). Las clases, métodos y variables con protección pública son visibles a todas las demás clases, dentro y fuera del paquete en la que se encuentran.

3. Protección privada (private). Las clases métodos y variables con protección privada son accesibles únicamente por métodos de la misma clase.

Aparentemente, la aplicación de protección privada a una clase no tendría sentido, puesto que alguna clase debería poder invocar a esta clase. Sin embargo, existe un tipo especial de clase que si puede ser privada: las clases internas.

Las clases internas son aquellas que están definidas dentro de otra clase. Esto permite:

• Que un objeto de una clase interna pueda acceder a la implementación del objeto que lo creó, incluyendo sus datos. De no ser una clase interna, esos datos serían privados.

• Que las clases internas puedan estar ocultas a otras clases del mismo paquete.

Puesto que en el ejercicio que nos ocupa no existe ningún ejemplo de este tipo de clases, haremos un ejemplo más simple:

class ClasePrincipal{private atributo1;public metodo(){ }

private class ClaseInterna{//desde aquí podemos acceder a atributo1

}}

4. Protección protegida (protected). Proporciona cierto nivel de visibilidad menos estricta que la privada. Los métodos y variables de una clase están accesibles a todas las clases y subclases del paquete en el que se encuentren.

Nótese que todas las clases de la aplicación de ejemplo son públicas. Esto se debe a que, para que puede ser utilizada por los servlets de la aplicación, debe ser accesible desde una clase que se

34

Page 37: Capac Unidad I IntroduccionJavaWeb

encuentre fuera del paquete en el que se encuentran. No obstante, dentro de los beans podemos encontrar modificadores públic para los métodos y private para los atributos.

2.11. Finalización

La finalización permite bloquear la implementación de una clase, variable o método. Se especifica utilizando la palabra reservada final, generalmente a continuación de un modificador de protección.

La finalización de variables la convierte en una constante:

final int a = 10;

La finalización de un método, sirve para que el método no puede ser superpuesto o sobrecargado.

final void metodoInmutable()

La utilización de métodos finales acelera la ejecución de los programas, ya que el compilador no tienen que buscar otras definiciones de los métodos.

La finalización de clases evita que una clase tengan subclases. Esta características es poco utilizada, ya que generalmente tenemos que pensar en ampliar la funcionalidad de las clases.

2.12. Polimorfismo

El polimorfismo es la capacidad de utilizar un objeto de una subclase como si fuera un objeto de la clase base. Esto permite desacoplar el código que escribimos. El desacoplamiento se refiere a la capacidad de escribir código por separado e independiente, pero que en un determinado momento podemos integrar sin mucho esfuerzo.

El ejemplo más inmediato en nuestra aplicación es el que hemos tratado en la sección 2.3 Casting. Sin embargo, veamos como en la clase PerfilBeanAsociacion como se construye un mapa hash con con los perfiles que le corresponden a un usuario en particular a través del método buscarPerfiles.

El mapa hash es generado a través de la clase HashMap. La idea de esta clase es hacer un arreglo de valores en los que los índices del arreglo son llaves que determinamos nosotros, es decir un par (llave, valor). Por ejemplo, un mapa hash puede estar basado en el par de valores (carnet, nombre). La llave en ese caso es el número de carnet y el valor es el nombre del estudiante.

En la pieza de código 2.11.1 vemos como el mapa hash es creado con el par (indice, perfil), en el que la llave es un correlativo de tipo entero. Estos pares se van incorporando al mapa con el método put.

En el API de JDK podemos encontrar que los tipos de datos del método put de HashMap son de tipo Object. Esto permite soportar como parámetro cualquier clase de cualquier tipo y hacer operaciones con ellas. El polimorfismo en este caso, consiste en que el método está escrito utilizando como referencia una superclase (en este caso Object), pero si recibe cualquier otra clase que sea subclase de esta, el código será igualmente válido y por lo tanto funcionará.

Podríamos pensar que esto no tiene ningún tipo de polimorfismo explícito y que se trata únicamente de un casting. Cuando al final del método invocamos al método values del mapa hash, podemos ver

35

Page 38: Capac Unidad I IntroduccionJavaWeb

que lo que devuelve el método es una colección de valores del tipo de la clase que nosotros hemos ingresado como valores. Es decir, que devuelve una colección de valores de tipo PerfilBeanAsociacion. Si hubiéramos ingresado como valores datos de tipo Integer el método values nos hubiera devuelto una colección de valores de tipo Integer.

Lista de código 2.11.1: Método buscarPerfiles de la clase PerfilBeanAsociacion.

public Collection<PerfilBeanAsociacion> buscarPerfiles() { HashMap perfiles = new HashMap(); Connection con = Conexion.getConecction(); PreparedStatement prepStat; ResultSet result; String sql; int i = 1;

sql = "SELECT id_perfil, estructura_organizativa, activo, id_cargo FROM perfil WHERE id_persona = ?";

if (con != null) { try { prepStat = con.prepareStatement(sql); prepStat.setInt(1, idPersona);

result = prepStat.executeQuery(); while(result.next()) { PerfilBeanAsociacion perfil = new PerfilBeanAsociacion(); perfil.setIdPersona(idPersona); perfil.setIdPerfil(result.getInt(1)); perfil.setEstructuraOrganizativa(result.getInt(2)); perfil.setActivo(result.getInt(3)); perfil.setIdCargo(result.getInt(4)); perfiles.put(i++, perfil); }

} catch (SQLException e) { System.out.println("Error en la consulta SQL " + sql + " " + e.getMessage()); } finally{ Conexion.closeConnection(con); } }

return perfiles.values();}

2.13. Sobrecarga de métodos

La sobrecarga de métodos se refiere a que una clase puede tener varios métodos con el mismo nombre. El compilador diferencia los métodos por el número y tipo de los argumentos que recibe.

Como ejemplo veamos los métodos buscarUsuario de la clase UsuarioBean. Estos métodos no se

36

Page 39: Capac Unidad I IntroduccionJavaWeb

diferencian por el número de argumento que reciben, sino por el tipo de dato del único argumento que reciben.

Lista de código 2.12.1: Sobrecarga del método buscarUsuario en la clase UsuarioBean.

public UsuarioBean buscarUsuario(String strUsr) { UsuarioBean usr = null; Connection con = Conexion.getConecction(); PreparedStatement prepStat;

ResultSet result = null; String sql = "";

if (con != null) { try { sql = "SELECT clave, id_persona FROM usuario WHERE usuario = ?"; prepStat = con.prepareStatement(sql); prepStat.setString(1, strUsr);

result = prepStat.executeQuery();

...

} catch (SQLException e) { System.out.println("Error en la consulta SQL " + sql + " " + e.getMessage()); } finally { Conexion.closeConnection(con); } } return usr;}

public UsuarioBean buscarUsuario(int idPersona) { UsuarioBean usr = null; Connection con = Conexion.getConecction(); PreparedStatement prepStat;

ResultSet result = null; String sql = "";

if (con != null) { try { sql = "SELECT usuario, clave FROM usuario WHERE id_persona = ?"; prepStat = con.prepareStatement(sql); prepStat.setInt(1, idPersona);

result = prepStat.executeQuery();

...

} catch (SQLException e) { System.out.println("Error en la consulta SQL " + sql + " " + e.getMessage()); } finally { Conexion.closeConnection(con); } } return usr;}

37

Page 40: Capac Unidad I IntroduccionJavaWeb

2.14. Superposición de métodos

La superposición de métodos es una consecuencia de lo explicado en la sección 2.6: Ambito de las variables. La superposición se refiere a que un método definido en una clase base, puede ser redefinido en sus subclases. La suporposición del método supone que la firma del método es igual que la definida en la superclase, de no ser así; estaremos hablando de recarga del método y no de superposición.

La diferencia entre la superposición de variables y de métodos es que podemos reutilizar el código del método original.

Supongamos ahora que deseamos implementar el diseño propuesto en el apartado Herencia, en el que proponíamos que UsuarioBeanHereda fuera una subclase de la clase PersonaBean. Como se explicó en ese momento, los métodos de acceso a las clases deben definirse por aparte, ya que cada uno accederá a tablas diferentes. Esto significa que en la clase UsuarioBenaHereda los métodos crear y actualizar se superpondrán a los métodos crear y actualizar de su clase base PersonaBean.

Uno de los principales usos de la superposición de métodos es la reutilización de código. Esto quiere decir que cuando se superpone un método, se puede hacer uso del código escrito en el método original (el de la clase base) y luego expandirlo en el nuevo método. Siguiendo con el ejemplo, supongamos que en el método crear de la clase UsuarioBeanHereda deseamos que se realice la inserción en las tablas correspondientes de los dos registros y así evitar la incovación de los dos métodos por separado. El código resultante puede verse en la pieza de código 2.13.1.

La invocación al método crear de la clase PersonaBean se realiza a través del operador super. El operador super es similar al operador this. La diferencia consiste en que el operador this indica al compilador que estamos haciendo referencia a un atributo o método de la misma clase, el operador super indica que estamos haciendo referencia a un atributo o método de la superclase de la clase en la que estamos escribiendo el código.

38

Page 41: Capac Unidad I IntroduccionJavaWeb

Lista de código 2.13.1: Superposición del método crear de la clase PersonaBean en UsuarioBeanHereda.

@Override public boolean crear(String[] mensaje) { boolean creado = false; Connection con = Conexion.getConecction(); PreparedStatement prepStat; ResultSet result;

String sql;

//Invocando al método crear de la clase base if (super.crear(mensaje)) { sql = "SELECT usuario FROM usuario WHERE usuario = ?";

if (con != null) { try { prepStat = con.prepareStatement(sql); prepStat.setString(1, usuario);

result = prepStat.executeQuery(); if (result.next()) { mensaje[0] = "El usuario ya existe"; } else { sql = "INSERT INTO usuario(usuario,clave,id_persona) VALUES(?,?,?)"; prepStat = con.prepareStatement(sql); prepStat.setString(1, usuario); prepStat.setString(2, clave); prepStat.setInt(3, super.getIdPersona());

if (prepStat.executeUpdate() > 0) { creado = true; mensaje[0] = "El usuario fue creado correctamente"; } else { mensaje[0] = "No fue posible crear el usuario"; }

}

} catch (SQLException e) { System.out.println("Error en la consulta SQL " + sql + " " + e.getMessage()); } finally { Conexion.closeConnection(con); } } } return creado; }

39

Page 42: Capac Unidad I IntroduccionJavaWeb

2.15. Clases abstractas.

Las clases abstractas son aquellas clases que cuentan con al menos un método abstracto en su definición. Estas clases sirven solo como referencia a sus subclases, puesto que no pueden ser instanciadas.

Los métodos abstractos son aquellos que no están implementados, es decir; métodos de los que solo se tiene la firma. Al contrario que en la herencia, en la que obligamos a las subclases a utilizar los métodos de la superclase tal y como ha sido definida (salvo que se superpongan), en la abstracción se obliga a las subclases a que implementen los métodos como se desee, pero se obliga a incluirlos con la misma firma que en la superclase.

Es importante aclarar que cuando definimos una subclase de una clase abstracta, no estamos obligados a implementarlos todos. Sin embargo, los métodos que no sean implementados deben ser declarados como abstractos, lo que convierte la clase en abstracta también. Esto significa que para tener una clase que pueda ser instanciada, debe implementar todos los métodos abstractos de la clase base.

Supongamos ahora que deseáramos hacer nuestra clase PersonaBean como clase abstracta. Esta clase se vería como se muestra el listado 2.14.1.

Como se ha dicho antes, bastará con que un solo método de la clase sea abstracto para convertir a la clase en abstracta. El objetivo de la abstracción, al contrario que en la herencia, es obligar a las subclases que queramos sean instanciadas; implementen los métodos que hemos definido como abstractos.

En el ejemplo, la clase UsuarioBeanHereda, que hereda de PersonaBean deberá de implementar estos métodos obligatoriamente o declararlos como abstractos. En este último caso la clase Usuario deberá de ser declarada como abstracta también.

40

Page 43: Capac Unidad I IntroduccionJavaWeb

Lista de código 2.14.1: Clase PersonaBean como clase abstracta (PersonaBeanAbstract)

package sv.edu.ues.adacad.capacitacion;

/** * * @author rudy */public abstract class PersonaBeanAbstract {

private int idPersona; private String nombre; private String apellidos; private String documentoIdentidad;

public int getIdPersona() { return this.idPersona; }

public void setIdPersona(int idPersona) { this.idPersona = idPersona; }

public String getNombre() { return this.nombre; }

public void setNombre(String nombre) { this.nombre = nombre; }

public String getApellidos() { return this.apellidos; }

public void setApellidos(String apellidos) { this.apellidos = apellidos; }

public String getDocumentoIdentidad() { return this.documentoIdentidad; }

public void setDocumentoIdentidad(String documentoIdentidad) { this.documentoIdentidad = documentoIdentidad; }

public abstract boolean crear(String mensaje[]);

public abstract boolean actualizar();

public abstract int estaIngresado();}

41

Page 44: Capac Unidad I IntroduccionJavaWeb

2.16. Interfaces

Aun cuando las interfaces no son clases, podríamos definirlas como pseudo clases en la que solo se especifica el comportamiento, es decir; solamente se especifican firmas de métodos y constantes. Una clase que implemente la interfaz debe implementar todos los métodos.

La idea de las interfaces es crear un nivel de abstracción que permitan definir características de las clases que las implementan, pero sin especificar el comportamiento. El uso más frecuente de este nivel de abstracción es cuando se desea crear una capa estándar de comportamiento que posteriormente puede ser implementada por otros proyectos de desarrollo. El ejemplo más inmediato que podemos encontrar de esto es el paquete sql de Java, en el que se encuentran definidas las interfaces Driver, Connection, PreparedStatement, ResultSet entre otros.

Cada fabricante de gestores de bases de datos debe implementar estas clases de acuerdo a las características del gestor, pero manteniendo las características especificadas por la interfaz. Para el ejemplo que estudiamos, estas clases son implementadas por el driver de PostgreSQL.

En las clases de nuestra aplicación, un ejemplo podría ser crear una interfaz llamada Persistente para que sea implementada por todas las clases que requieren incluir métodos de almacenamiento en la base de datos, como se muestra en la figura 2.16.1. Hasta donde hemos avanzado, solamente las clases PersonaBean, UsusarioBean y PerfilBeanAsociacion deberían implementar la interfaz Persistente.

Figura 1.16.1: Modelo de clases con interfaz Persistente.

42

Page 45: Capac Unidad I IntroduccionJavaWeb

Bibliografía

• JavaServer Pages: A Developer's Perspective

http://java.sun.com/developer/technicalArticles/Programming/jsp/

• Referencia del lenguaje Php

http://www.php.net/manual/es/

• Manual de Iniciación a Java, versión 2.0

Juan Angel Lorenzo de Castillo

Grupo Universitario de Informática, Universidad de Valladolid.

43