PI-016 Programacion en Java V2 PDF
PI-016 Programacion en Java V2 PDF
PROGRAMACION EN JAVA
Manual del Estudiante
Agosto 6 de 2012 Versión 3.0
Ninguna parte de este documento puede ser reproducida o transmitida de ninguna forma, ni
por ningún medio ya sea electrónico o mecánico, con ningún propósito, sin la previa
autorización por escrito de Asesoftware Ltda.
Tabla de Contenido
1 Introducción ....................................................................................................................... 1
1.1 Historia ........................................................................................................................... 1
1.2 Java y su JDK ................................................................................................................. 1
1.3 Arquitectura .................................................................................................................... 4
1.4 Por qué Utilizar Java....................................................................................................... 5
2 Fundamentos de Programación Orientada a Objetos.................................................... 9
2.1 Complejidad del Software .............................................................................................. 9
2.2 Paradigma Orientado a Objetos .................................................................................... 10
2.3 Conceptos Básicos OO ................................................................................................. 11
3 Programación Básica en Java......................................................................................... 17
3.1 Introducción .................................................................................................................. 17
3.2 Sintaxis ......................................................................................................................... 17
3.3 Bienvenida a la Programación en Java ......................................................................... 17
3.4 Variables y Tipos de Datos ........................................................................................... 19
3.5 Operadores .................................................................................................................... 21
3.6 Arreglos ........................................................................................................................ 24
3.7 Estructuras de Control .................................................................................................. 25
4 Clases en JAVA................................................................................................................ 33
4.1 Encapsulamiento y Visibilidad ..................................................................................... 34
4.2 Definición de Clases ..................................................................................................... 35
4.3 Declaración de Atributos .............................................................................................. 37
4.4 Declaración de Métodos ............................................................................................... 38
4.5 Manejo de la Memoria en Java. .................................................................................... 39
5 Herencia ............................................................................................................................ 43
5.1 Redefinición de Métodos .............................................................................................. 44
5.2 Super ............................................................................................................................. 44
5.3 Clases Abstractas vs Clases Concretas ......................................................................... 44
5.4 Polimorfismo ................................................................................................................ 45
6 Cadena de caracteres (String) ........................................................................................ 47
6.1 Creación de Objetos Tipo String .................................................................................. 47
6.2 Comparación de Cadenas ............................................................................................. 47
6.3 Concatenación de Cadenas ........................................................................................... 48
6.4 Operaciones de búsqueda ............................................................................................. 48
6.5 Clase StringBuffer ........................................................................................................ 49
7 Interfaces .......................................................................................................................... 51
7.1 Definición de Interfaces ................................................................................................ 52
7.2 Implementación de Interfaces ....................................................................................... 53
8 Paquetes ............................................................................................................................ 55
8.1 Import ........................................................................................................................... 55
8.2 Package ......................................................................................................................... 56
8.3 CLASSPATH y el Sistema de Archivos ...................................................................... 56
8.4 Opcion -d ...................................................................................................................... 57
9 Colecciones ....................................................................................................................... 59
9.1 Definición ..................................................................................................................... 59
9.2 Tipos de Colecciones .................................................................................................... 59
9.3 Clases que implementan las interfaces ......................................................................... 61
9.4 Interfaz Iterator ............................................................................................................. 63
9.5 Las Interfaces de Map .................................................................................................. 63
9.6 Las clase Map ............................................................................................................... 64
9.7 Colecciones en JDK 1.1................................................................................................ 65
9.8 Clases Genéricas y Colecciones (J2SE 5.0) ................................................................. 65
10 Excepciones .................................................................................................................... 68
10.1 Excepciones en Java ................................................................................................... 68
10.2 Throwable ................................................................................................................... 69
10.3 Manejo de excepciones ............................................................................................... 70
10.4 Captura de excepciones .............................................................................................. 70
10.5 Declaración de excepciones ........................................................................................ 72
10.6 Definición de nuevas excepciones .............................................................................. 73
10.7 Consideraciones .......................................................................................................... 74
10.8 Aserciones................................................................................................................... 74
11 Clases Anidadas ............................................................................................................. 76
11.1 Propiedades de las clases Internas .............................................................................. 79
11.2 Clases Internas vs. Anidadas ...................................................................................... 79
12 Streams ........................................................................................................................... 80
12.1 InputStream................................................................................................................. 80
12.2 OutputStream .............................................................................................................. 81
12.3 Manejo de archivos ..................................................................................................... 81
12.4 Serialización ............................................................................................................... 83
12.5 Sockets ........................................................................................................................ 85
13 Applets ............................................................................................................................ 88
13.1 Tag Applet de HTML ................................................................................................. 88
13.2 Ciclo de vida de un Applet ......................................................................................... 89
13.3 Parametrización de Applets ........................................................................................ 90
13.4 Restricciones de los Applets ....................................................................................... 91
14 Interfaces Gráfica de Usuario ...................................................................................... 92
14.1 Componentes AWT .................................................................................................... 92
14.2 Manejo de eventos ...................................................................................................... 95
15 Programación Multihilos (Threads) .......................................................................... 102
15.1 Fundamentos de los Hilos: ....................................................................................... 102
1 Introducción
1.1 Historia
En 1991 Sun Microsystems dio inicio al proyecto de investigación Oak liderado por James
Gosling, con el objetivo de crear un lenguaje de programación liviano, rápido, eficiente y
portable que pudiera ser empleado en el desarrollo de software para electrodomésticos
como televisores, radios y reproductoras de videos.
A pesar de las bondades del lenguaje Oak, su verdadero potencial fue explotado a partir de
1994 con el desarrollo de un navegador Web denominado HotJava, con la capacidad de
cargar, instalar y ejecutar programas (denominados applets) de forma automática a través
de la red. Posteriormente, Netscape adoptó las mismas capacidades de HotJava,
consolidando a Java como el lenguaje de facto para el desarrollo de aplicaciones
interactivas y funcionales en el Web.
Este API ha pasado por múltiples versiones y realease que han extendido la funcionalidad y
aumentado la robustez y eficiencia del lenguaje. Las principales versiones del JDK son:
El siguiente diagrama ilustra los componentes (herramientas APIs) del JDK de Java:
javap Permite examinar una clase Java para determinar sus interfaz
(métodos y atributos)
1.3 Arquitectura
Código Fuente
.java
compilación
bytecode
110110100111000
1011101101100011
000110100111000
.class 1011101111100011
001011101101000
1011101101110001
001011100111000
10111011010000011
0010110100111000
1011010011100011
API
001010100111000
011010011100011
Runtime
Máquina Virtual
Sistema operativo
Hardware
Los creadores de Java diseñaron una "máquina virtual", para garantizar la portabilidad
y la transparencia entre sistemas operacionales y procesadores, con su propio ejecutor
de instrucciones. Esta máquina virtual simula una CPU que toma como entrada el
bytecode e interpreta una a una las instrucciones, reflejando los cambios de estado del
programa que se está "ejecutando".
1.3.2 Bytecode
Portabilidad Una aplicación escrita y compilada con Java puede ser ejecutada
(interpretada) en diferentes plataformas, gracias a la utilización de la
máquina virtual de Java.
Interpretadores
(Máq Virtual)
Solaris
Código Fuente
Java bytecode
Compilador (portable)
00101110110100111000
Java 10111011010011100011
00101110110100111000 MSWindows
10111011010011100011
00101110110100111000
10111011010011100011
00101110110100111000
10111011010011100011
00101110110100111000
10111011010011100011
00101110110100111000
10111011010011100011
00101110110100111000
MAC
.java .class
Código móvil Los Applets de Java son denominados código móvil ya que son
transportados, instalados y ejecutados de forma automática.
1 http://www.serv
/aplic.html N
2 Enviar el
bytecote
3 Cargar el
bytecote
4 Interpretar el
bytecode
(ejecutar)
2. Tamaño de las aplicaciones: Las exigencias de los usuarios y tecnológicas, hacen las
aplicaciones cada vez más voluminosas, conformadas por decenas o cientos de módulos
que deben ser construidos por diferentes desarrolladores.
1. El modelo OO aplica para todo el ciclo de vida del software; análisis, desarrollo,
construcción y mantenimiento. Los conceptos y términos empleados en cada una de
estas fases se conservan, extiendiendose o refinando en cada fase.
Esta técnica busca abordar la complejidad del dominio del problema, haciendo una
abstracción de las entidades mediante la creación de tipos de datos abstractos cuya
definición se compone de datos y funciones.
2.2.2.3 Encapsulamiento
2.3.1 Objeto
objeto
Un objeto es un dato abstracto encapsulado, cuyos atributos pueden ser otros objetos
con complejidad arbitraria. Esto nos permite crear correspondencias uno a uno entre los
objetos y las entidades del mundo real que estamos modelando. Una entidad simple del
mundo real se representa como un objeto simple (sin necesidad de descomponerla en
relaciones independientes).
Un objeto puede estar embebido en otros objetos, ser utilizado como parámetro y/o ser
utilizado como valor de retorno de alguna función (método).
2.3.2 Clase
2.3.3 Relaciones
Los objetos no son entes aislados, sino por el contrario interactuan con otros objetos
para lograr el objetivo final de la aplicación. Esta interacción sigue el esquema
cliente/servidor, donde el objeto con el rol cliente solicita la ejecución de un servicio al
objeto con rol servidor.
1: retirar(monto)
Cada objeto puede asumir el rol de cliente o servidor. Esta invocación de servicios se
denomina paso de mensajes entre objetos, y los servicios que presta un objeto están
representados por los métodos del objeto.
El conjunto de métodos o servicios que presta un objeto determina su conducta (como
responde o reacciona a las solicitudes externas).
2.3.5 Herencia
2.3.5.1 Especialización
Punto
x: float
y: float
mover(px, py)
estaEn(Rectangulo)
distancia(Punto)
Pixel
color:TColor
pintarse()
La especialización, crea clases derivadas que extienden la clase base por medio de la
adición de métodos y atributos, haciéndolas más potentes y especializadas. Esto
permite la reutilización de código, disminuyendo los tiempos de desarrollo y la
probabilidad de errores, ya que un solo segmento de código es empleado múltiples
veces (una por cada clase derivada).
2.3.5.2 Generalización
En este tipo de herencia, las clases derivadas redefinen o sustituyen los métodos de
la clase derivada. Esto permite organizar las clases en jerarquías de tipos y subtipos,
que satisfacen la condición de que las instancias de una clase derivada (subclases)
son a su vez instancias de la clase base (superclase).
FiguraGeometrica
2.3.6 Polimorfismo
metodoEjemplo(FiguraGeometrica fg)
{
float area;
area = fg.calcularArea();
}
2.3.7 Sobrecarga
La sobrecarga permite que dos o más funciones puedan compartir su nombre siempre y
cuando las declaraciones de los parámetros sean diferentes. Esto busca hacer las
interfaces entre objetos más sencillas y fáciles de usar.
Adicionalmente a las funciones o métodos, es posible sobrecargar los operadores del
lenguaje de programación.
2.3.8 Persistencia
3.1 Introducción
Este capitulo introduce las sentencias básicas de Java excluyendo las sentencias para
construir y manipular objetos. Ya que la sintaxis base de Java es muy similar a la sintaxis
del lenguaje C, los desarrolladores experimentados en C o C++ asimilarán este capitulo de
forma inmediata.
3.2 Sintaxis
La sentencias (operaciones simples) en Java se delimitan por el símbolo punto y coma (;) y
pueden llegar a extenderse en múltiples líneas de código. A continuación se presentan
ejemplos de sentencias en Java:
Los bloques son sentencias conformadas por una o más sentencias simples delimitadas por
llaves ({ }).
Java es case-sensitive, es decir que las letras mayúsculas difieren de las minúsculas.
Los conceptos del presente capitulo se introducen a partir del programa Bienvenida a la
programación en Java.
class Bienvenida
{
public static void main(String args[])
{
String mensaje = ", Bienvenido a la programacion en Java.";
System.out.println(args[0] + mensaje);
}
}
Para compilar este programa el código fuente se debe almacenar en un archivo tipo texto
con nombre Bienvenida y extensión java (teniendo en cuenta la distinción entre mayúsculas
y minúsculas). El proceso de compilación genera el bytecode de la clase Bienvenida en un
archivo denominado Bienvenida con extensión class. Para este proceso se emplea el
compilador de Java:
En caso que la compilación haya sido satisfactoria, en el directorio actual se debe encontrar
el archivo Bienvenida.class.
Para ejecutar (interpretar) el programa se debe emplear el runtime de Java:
Este programa está representado por la clase Bienvenida que contiene un único método
denominado main. El método main recibe como parámetros un arreglo de objetos tipo
String.
La primera sentencia del método main declara la variable mensaje de tipo String y la
inicializa con el literal ", Bienvenido a la programacion en Java.".
System.out.println(args[0] + mensaje);
| | |
| | |__ método invocado
| |______ atributo de tipo PrintStream
|_____________ nombre de clase
3.4.1 Variables
Los identificadores de variables pueden incluir letras(a-z, A-Z), numeros (0-9) y los
símbolos subrayado(_) y pesos ($), donde el primer carácter no puede ser un número.
Clases e interfaces
Arreglos
Buscando mayor eficiencia, en Java los tipos de datos básicos no son orientados a
objetos(no poseen atributos ni métodos), sino por el contrario representan valores
atómicos como enteros, reales y caracteres. Estos tipos de datos son independientes de
la plataforma, por lo cual su tamaño y comportamiento son idénticos para todas las
implementaciones de JVM.
Los tipos básicos son; byte, short, int, long, float, double, char y boolean. No existe
posibilidad de crear, modificar o definir nuevos tipos de datos básicos. Cualquier otra
construcción como clases, interfaces o arreglos (predefinida o definida por el
programador) está basada en tipos básicos.
Enteros
Tipo Tamaño Rango
byte 8 bits -128 a 127
short 16 bits -32,768 a 32,767
int 32 bits -2,147,483,648 a 2,147,483,647
long 64 bits -9223372036854775808 a 9223372036854775807
Reales
Tipo Tamaño Rango
float 32 bits 3.4e-038..3.4e+038
double 64 bits 1.7e-308..1.7e+308
\n Nueva línea
\t Tabulador
\b Backspace
\r carriege return
\f formfeed
\\ backslash
\' Comilla sencilla
\" Comilla doble
Por último, el tipo booleano se emplea para representar valores lógicos (verdadero y
falso), y los posibles valores que puede tomar son true y false.
Para la declaración de variables se hace a través de una sentencia que especifica el tipo
de dato, el identificador y de forma opcional el valor inicial:
int x;
int a, b, c;
float f_ejemplo = 3.14;
char c;
char letra = 'b';
boolean confirmado = true;
3.5 Operadores
Los operadores son símbolos especiales empleados en expresiones que se evalúan para
retornar un valor. Estos se pueden clasificar en aritméticos, de asignación, increméntales y
decrementales, relacionales, lógicos y bitwise.
El tipo de dato retornado por el operador división depende de sus operandos; en caso
que sus operandos sean enteros el valor retornado será un entero, y en caso que alguno
de los operandos sea real el valor retornado será un real.
El operador incremento (++) y el decremento (--) son operadores unarios. Estos son
empleados para incrementar o decrementar una variable en una unidad. De esta forma,
las siguientes expresiones son equivalentes.
a = a + 1;
a += 1;
a++;
++a;
class AritmeticaEjem {
public static void main (String args[]) {
int a;
int b = 10;
int c = 1;
b ++ ; // Incrementar el valor de b en uno
a = b - c;
b *= c; // Equivalente a : b = b*c;
c = ++a;
System.out.println(“El valor de a es = “ + a);
System.out.println(“El valor de b es = “ + b);
System.out.println(“El valor de c es = “ + c);
}
}
Operación Ejemplo
== Igualdad vBool = (b == c);
!= Diferencia vBool = (b != c);
> Mayor que vBool = (b > c);
< Menor que vBool = (b < c);
>= Mayor o igual que vBool = (b >= c);
<= Menor o igual que vBool = (b <= c);
Los operadores && y ¦¦ producen el mismo resultado lógico que los operadores & y ¦
respectivamente. La diferencia entre los operadores lógicos short-circuit y los
operadores lógicos tradicionales radica en la evaluación de las expresiones utilizadas
como operandos:
3.6 Arreglos
Un arreglo es un objeto que contiene un conjunto de valores (objetos o tipos básicos) del
mismo tipo. Los arreglos son considerados como objetos en el lenguaje Java.
int[] arregloEjemplo;
int otroEjemplo[];
String[] palabras;
Al utilizar el operador new, todos los elementos del nuevo arreglo son
inicializados de forma automática, con cero (0) para valores numéricos, false
para booleanos, fin de cadena ('\0') para caracteres y null para objetos.
arregloEjemplo[0] = 25;
x = arregloEjemplo[1] + arregloEjemplo[8];
Los índices de los elementos del arreglo inician con el valor cero (al igual que
C). Para acceder al valor de un elemento del arreglo, se debe emplear el nombre
del arreglo y el índice del respectivo elemento entre paréntesis cuadrados.
Los arreglos poseen el atributo length que almacena la longitud del arreglo.
int[][] m;
m = new int[10][15];
m[0][3] = 8;
Es mas, cada posición del arreglo de arreglos es independiente, y es posible que cada
subarreglo tenga longitud diferente.
Int a [][];
a = new int[3][];
a[1] = new int[1];
a[2] = new int[2];
a[3] = new int[10];
Las instrucciones de flujo de control en Java son muy similares a las empleadas en C y
C++.
3.7.1 If-else
Ejemplo
int maximo;
if (a < b) {
maximo = b;
}
else {
maximo = a;
}
Esta construcción es empleada para expresar una decisión múltiple. Las expresiones
booleanas son evaluadas en orden y la primera que evalue a true hará que su bloque de
instrucciones asociado se ejecute. Solo un bloque de instrucciones es ejecutado.
if (expresion_booleana1)
bloque1
else if (expresion_booleana2)
bloque2
else if (expresion_booleana3)
bloque3
.....
[else bloqueOmision]
Ejemplo
3.7.3 Switch
switch(expresion) {
case valor1:
bloque1
break;
case valor2:
bloque2
break;
.....
default:
bloqueOmision
}
Ejemplo
char a;
String sOpt;
System.out.println("Digite un valor numérico entre 1 y 3: ");
a = (char) System.in.read();
switch(a) {
case '1' :
sOpt = "Opcion uno";
break;
case '2' :
sOpt = "Opcion dos";
break;
case '3' :
sOpt = "Opcion tres";
break;
default:
sOpt = "Opcion invalida";
}
System.out.println("Usted oprimio la " + sOpt);
3.7.4 Break
Permite terminar la ejecución de un bloque de control. En este caso los bloques deben
poseer un nombre (label) que los identifique.
break label;
Ejemplo
lb1: {
lb2: {
if (a > 5) {
break lb2
}
else {
break lb1
}
}
System.out.println("Despues del bloque lb2");
}
System.out.println("Despues del bloque lb1");
3.7.5 While
while (condicion) {
bloque
}
Ejemplo
int i = 0;
while (i < 10) {
System.out.println("Iteración número: " + i);
i++;
}
3.7.6 Do-while
Similar al while, excepto que se garantiza que el bloque de instrucciones se ejecuta por
lo menos una vez, asi la condición sea falsa.
do {
bloque
} while (condicion);
Ejemplo
int suma = 0;
int i = 1;
do {
suma += i;
i++;
} while (i < 10);
3.7.7 For
La estructura for por lo general es empleada para iteraciones simples en las cuales un
bloque de instrucciones se debe ejecutar un número determinada de veces y
posteriormente parar.
Ejemplo
for (int i=0 ; i < 10 ; i++) {
System.out.println("Iteración número: " + i);
}
3.7.8 Continue
Esta sentencia es utilizada en el interior de un ciclo (bloque del ciclo) para omitir la
ejecución de las sentencias restantes de la actual iteración, pero sin salir del ciclo.
4 Clases en JAVA
El proceso de análisis orientado a objetos tiene como principal objetivo identificar las cosas
o entidades del mundo real que son relevantes para la aplicación que se desea construir.
Por ejemplo, para modelar la planta física de un campus universitario, los edificios, aulas,
laboratorios, oficinas y áreas libres son entidades relevantes para el sistema. Cada uno de
estas entidades tienen propiedades y un comportamiento especifico. Un aula tiene
capacidad, dimensiones y localización. En cuanto al comportamiento, una aula puede llegar
a rechazar su reserva en caso de estar previamente reservada.
En POO cada una de estas entidades se modela como clases. Una clase es una abstracción
de datos que representa las entidades del mundo real.
Las clases son la construcción base de los lenguajes orientados a objetos. Los objetos que
comparten la misma funcionalidad y propiedades son agrupados en clases. De esta forma,
en una clase se especifican las propiedades y comportamiento) de un conjunto de objetos
similares. Los objetos que se crean a partir de la definición de una clase se denominan
instancias de esa clase.
Aula
capacidad
dimensiones
localizacion
reservar()
awt
image Button
Checkbox
Choice
Label
private Los métodos y atributos con acceso private solo son visibles
por los métodos de la misma clase. Esta es la visibilidad más
restrictiva.
cuerpo
}
donde
Los atributos son variables que definen el estado de un objeto en un instante dado.
El tipo de dato de estos atributos puede ser un tipo básico (float, int, char ..) o un clase
definida por el usuario o del API del JDK.
Si se desean definir atributos que son constantes se emplea final que especifica que el
valor inicial del atributo no puede ser modificado.
Ejemplo:
class Prueba {
private float var1;
public int var2;
public final float PI = 3.14;
public static int total;
}
Los atributos por omisión son atributos de instancia, mientras que los static son
atributos de clase.
Cada instancia tiene copias "propias" de los atributos de instancias, así que el valor que
posee cada objeto es independiente de los valores que tienen otros objetos.
Para los atributos de clase sólo se crea una copia, la cual es compartida entre todas las
instancias de la respectiva clase. Si un objeto modifica el valor de un atributo de clase,
este cambio se reflejará en cada una de las instancias de la clase.
La conducta de los objetos es determinada por los métodos que conforman su respectiva
clase. Estos métodos se pueden ver como funciones o procedimientos, que pueden ser
invocados según las reglas de visibilidad del método.
final Indica que este método no puede ser redefinido en las clases derivadas.
Este es un mecanismo de seguridad en java que evita que los métodos
sean reemplazados erróneamente.
tipoRetorno Es el tipo de valor que el método retorna como salida. Este puede ser un
tipo básico, el nombre de una clase o void si el método no retorna nada.
4.4.2 Sobrecarga
donde args es un arreglo de cadenas de caracteres que almacena cada uno de los
parámetros de la línea de comandos.
Java provee un manejo automático de la memoria. Cuando usted crea un nuevo objeto, Java
reserva la cantidad de memoria requerida para dicho objeto de manera implícita. De esta
forma el programador no tiene que preocuparse por reservar memoria explícitamente.
De igual forma, cuando un objeto deja de ser utilizado (no hay variables que lo
referencian), Java lo destruye y libera la memoria ocupada por dicho objeto. Esto lo logra a
través de un mecanismo de recolección de basura automático (Garbage Collection) , que
periódicamente barre la memoria buscando objetos no utilizados.
Es posible tener una o más variables que referencien el mismo objeto en memoria.
El operador new es utilizado para crear nuevas instancias de clases (objetos) asignando
espacio en memoria. Dentro de este proceso de creación, se invoca de forma automática
el constructor de la clase para inicializar los atributos del objeto. Finalmente, el
operador new retorna una referencia al objeto creado.
La forma de acceder los atributos y métodos de una objeto es por medio del operador
punto. La forma general de acceder de un elemento de un objeto es:
referenciaObjeto . nombreAtributo
referenciaObjeto . nombreMetodo
Ejemplo:
p1 = new Punto(1,2);
p2 = new Punto(3,4);
...
p2 = p1;
p1.x = 5;
p1.y = 6;
System.out.println(“la posición de p1 es: “ + p1.x + “, “ + p1.y);
System.out.println(“la posición de p2 es: “ + p2.x + “, “ + p2.y);
Memoria
p1
5, 6
1, 2
p2
4.5.4 This
this es una variable especial que referencia al objeto actual (el objeto al cual pertenece
el método que está empleando la variable this). En el ejemplo Punto, el método
constructor puede reescribirse de la siguiente forma:
5 Herencia
Punto
x : int
public class Punto3D extends Punto y : int
{
private int z; <<constructor>>
Punto(pX : int, pY : int)
public Punto3D(int pX, int pY, int pZ) {
trasladar(otro : Punto )
x = pX;
toString()
y = pY;
z = pZ;
}
Punto3D
public String toString() {
return z : int
"(" + x + "," + y + "," + z + ")";
} <<constructor>>
} Punto3D(
pX:int, pY:int,pZ:int)
toString()
5.2 Super
Así como this es una variable que referencia el objeto actual, super es una referencia al
objeto base. Super también es empleado para invocar los constructores de la clase base:
Ejemplo: El método constructor de la clase Punto3D puede ser reescrito empleando super y
así evitar la duplicación de código:
en este caso super(pX, pY) es una invocación al método constructor de la clase Punto.
Las clases a partir de las cuales se pueden crear instancias (objetos), se denominan clases
concretas, y por lo general representan entidades tangibles del mundo real.
Nota: Las clases heredadas de una clase abstracta deben implementar todos los métodos
abstractos declarados en la clase base, o ser a su vez declaradas abstractas.
Ejemplo:
abstract class Empleado {
String nombre;
float salario;
abstract int valorImpuesto();
public String toString() {
return nombre;
}
}
5.4 Polimorfismo
Circulo
dibujar Cuadrado
Linea
Ejemplo:
class A {
public String info(){
return “Datos de la clase A“;
}
}
class B extends A{
public String info(){
return “Datos de la clase B“;
}
}
class C extends A{
public String info(){
return “Datos de la clase C“;
}
}
el mecanismo de polimorfismo se aplica en el siguiente segmento de código:
:
void imprimirInfo(A obj){
System.out.println(obj.info());
}
:
Teniendo en cuenta el siguiente principio ; "Si B es una clase derivada de A y objB es una
instancia de B, entonces objB también es una instancia de A". Continuando con el ejemplo
anterior, las siguientes invocaciones al método imprimirInfo son válidas:
imprimirInfo(objB);
imprimirInfo(objC);
Por medio del siguiente constructor se pueden crear objetos tipo String:
String(char[] caracteres, int posIni, int numeroCaracteres)
Ejemplo
char[] arregloCar = {'d', 'a', 't', 'o'};
String varStr = new String(arregloCar);
String varOtra = new String(arregloCar, 0, 4);
Aunque las sentencias del ejemplo anterior son correctas, Java provee un mecanismo más
simple de crear objetos tipo String;
Para la comparación de cadenas de caracteres la clase String provee los métodos equals y
equalsIgnoreCase:
if ( str.equals("dato") ) {
....
}
Java no soporta la sobrecarga de operadores, con la excepción del operador +, que cuando
opera sobre objetos String actúa como el operador de concatenación.
Ejemplo:
class Prueba {
public static void main(String[] args) {
String mensaje;
int numParam = args.lenght;
mensaje = "los parametros de la línea de comandos son : " +
numParam;
System.out.println(mensaje);
}
}
La clase StringBuffer representa una cadena de texto que puede ser modificada
dinámicamente, y por ende es mucho más eficiente en algoritmos que manipulan
intensamente cadenas de texto. No existe una relación de herencia entre esta clase y la clase
String; usted no puede asignar un objeto String a una variable declarada como StringBuffer.
Sin embargo usted puede crear un nuevo String de un StringBuffer invocando el método
toString.
StringBuffer insert (int punto, String cadena): Modifica el string insertando la cadena
en la posición indicada por el parámetro punto.
void setCharAt (int punto, char ch). Modifica el string cambiando el caracter ‘ch’ en la
localización especificada por el parámetro punto.
7 Interfaces
Interfaz
Implementación
Una interfaz es similar a una clase abstracta, que provee los prototipos de los métodos que
se espera sean implementados por las clases concretas. Las interfaces no proveen el cuerpo
(implementación) de los métodos.
El principal uso de las interfaces es proveer métodos comunes a diferentes clases, sin
requerir el mecanismo de generalización(polimorfismo sin requerir jerarquías de herencia).
Se dice que una clase implementa una interfaz cuando la clase implementa cada uno de los
métodos definidos en la interfaz. A diferencia de la herencia, una clase puede implementar
múltiples interfaces, solucionando así la limitante de herencia simple en Java.
<<interface>>
Cuenta Producto
Ejemplo:
interface Activo
{
void depreciar();
float costo();
}
Ejemplo
8 Paquetes
8.1 Import
La sentencia import se emplea al inicio de los archivos fuentes para importar clases que se
encuentran en otros paquetes.
Los paquetes se referencian y recorren a través del operador punto:
pkg1.pkg2.pkg3.ClaseA
en este caso estamos referenciando la clase ClaseA que se encuentra en el paquete pkg3,
que a su vez se encuentra en el paquete pkg2. Por último, pkg2 se encuentra en el paquete
raíz pkg1.
import java.util.Vector;
import java.awt.*;
El paquete java.lang es el paquete por omisión, por lo cual si se desean emplear clases de
este paquete no es necesario hacer el import explícitamente.
8.2 Package
Para incorporar una clase en un paquete es necesario introducir la sentencia package como
primera línea de código en el archivo fuente donde se está declarando la clase.
Ejemplo
package pck1;
import java.util.Vector;
impot java.awt.Applet;
public class Clase1 {
public metodo1 () {
System.out.println(“Ejemplo“);
}
}
class Clase2 {
public metodo2 () {
System.out.println(“Ejemplo“);
}
}
class Clase3 {
public metodo3 () {
System.out.println(“Ejemplo“);
}
}
CLASSPATH es una variable de ambiente que determina los directorios del sistema de
archivos que son utilizados como raíces de los paquetes. Tanto el compilador como el
runtine de Java utilizan la variable CLASSPATH para determinar la localización de las clases
refenciadas.
/usr/rgalindo/classes/
banco/
productos/
cuentas/
CuentaCorriente.class
8.4 Opcion -d
El compilador de Java (javac) ofrece la opción -d que permite definir el directorio donde se
deben almacenar los archivos compilados (.class)
9 Colecciones
9.1 Definición
Una colección es un simple objeto que representa un grupo de objetos llamados elementos.
Los tipos de colecciones varían dependiendo del mecanismo usado para almacenar,
acceder a datos, o en las reglas usadas para ordenar los objetos de la colección.
El API Collections provee una variedad de interfaces y clases que nos proporcionan
implementaciones diferentes de las interfaces estándar.
Interfaz Collection
Método Descripción
Boolean add (Object obj): Adiciona objetos a la colección.
Devuelve true si obj fue agregado a la
colección.
o false si el objeto ya es miembro de la
colección o si la colección no admite
duplicados.
Boolean remove(Object obj): Remueve un objeto de la colección.
Devuelve true si el elemento fue removido,
si no retorna false.
Interfaz Set
Ejemplo:
import java.util.*;
public class SetEjemplo{
public static void main(String[] args){
Set set= new HasSet();
set.add("uno");
set.add("dos");
set.add("tres");
set.add(new Integer(4));
set.add(new Float(5.0F));
set.add("dos"); // Los duplicados no son adicionados
set.add(new Integer(4)); // Los duplicados no son adicionados
System.out.println(set);
}
}
Interfaz List
Métodos Descripción
void add(int indice, object obj) : Inserta el objeto a la lista en la posición
que indica el índice.
Ejemplo:
import java.util.*;
Clase TreeSet
Proporciona una implementación de la interfaz Set que usa una estructura de árbol para el
almacenamiento de los elementos.
Los objetos se organizan en forma ascendente, los tiempos de acceso y recuperación son
rápidos siendo una excelente alternativa en situaciones donde se requiera almacenar gran
cantidad de información.
ArrayList y LinkedList
Dos clases que implementan la interfaz List son : ArrayList y LinkedList. Se pueden usar
dependiendo de las necesidades específicas.
Si se necesita soportar accesos aleatorios, remover un rango de elementos de la lista y
recorrer la lista en una sola dirección de principio a fin el ArrayList es una buena
alternativa.
Pero si necesita recorrer una lista en forma secuencias en ambas direcciones LinkedList
ofrece la mejor implementación.
Esta interfaz proporciona métodos que permiten recorrer una colección en la dirección
principio–fin. Si la colección es un Set la iteración no es ordenada. Para el caso de un List
se puede utilizar la interfaz ListIterator que hereda de Iterator y permite recorrer la
colección en forma bidireccionalmente de principio-fin con el método next () o de fin-
principio con el método previous ().
El método remove permite remover de la colección el elemento retornado por los métodos
next () y previous durante una iteración.
El método set reemplaza el elemento indicada por el cursor.
+hasNext() :boolean
+next(): Object
+remove()
+hasPrevious() :boolean
+previous() :Object
+add(Object obj)
+set(Object obj)
Además de las colecciones Java 2 agregó al paquete java.util los mapas. Un mapa es un
objeto que almacena relaciones u asociaciones entre claves y valores., dada una clave se
puede recuperar su valor. La clave debe ser única pero los valores pueden ser duplicados.
Mapea claves únicas a valores. Una clave es un objeto que se usa para recuperar un
valor.
Los mapas giran alrededor de dos operaciones básicas, get (Clave) para recuperar y put
() para adicionar un objeto en el Map.
Los mapas no son colecciones pero se puede obtener una vista colección de un mapa,
utilizando el método entrySet () que retorna un Set con los elementos.
Para obtener una vista de las claves usamos keySet() y para los valores se usa values().
Mediante la vista de colección los mapas se integran a la estructura de las colecciones.
Interfaz SortedMap
Hereda de Map y asegura que las claves se ordenen en forma ascendente. Los mapas
ordenados permiten la manipulación eficiente de submapas o subconjunto de mapas.
HashMap
Implementa la interfaz Map y hereda de AbstractMap, usa una tabla de dispersión para
implemementar la interfaz Map. No garantiza el orden de los elementos, en otras palabras
el orden en que se agregaron los elementos no necesariamente es el orden en que los lee el
Iterator.
Una tabla de dispersión solo permite almacenar objetos que sobrescriban los métodos
hashCode() e equals() definidos en la clase java.lang.Object.
El método hashCode () debe calcular y devolver el código de dispersión del objeto para que
posteriormente el método equals compare los objetos.
La principal diferencia entre un Hashtable y un Hashmap, es que el Gastable no permite
almacenar valores nulos.
Clase TreeMap
Clase TreeSet
Proporciona una implementación de la interfaz Set con los elementos ordenados en forma
de árbol.
A diferencia de TreeMap, TreeSet no necesita implementar la interfaz Comparable.
Las clases como Vector, Stack, Hashtable, Properties que fueron introducidas desde el JDK
1.0 y JDK1.1 continúan existiendo pero han sido reestructuradas para que puedan
interactuar con la nueva API Collection.
Por ejemplo la clase Vector ahora implementa la interfaz List, la clase Stack es una
subclase de Vector y adiciona las operaciones tipicas de push(), pop() y peek().
La clase Hashtable es una implementación de Map, y la clase Properties es una subclase de
Hashtable que sólo usa Strings para las claves y valores.
Estas colecciones se consideran hilos-seguros por que están sincronizadas lo cual hace
pesada su implementación.
Las clases genéricas son un mecanismo introducido en J2SE 5.0 que proporciona mayor
confiabilidad a las aplicaciones escritas en Java, reduciendo la probabilidad de errores de
código ocasionados por operaciones de “casting” y en general por la manipulación de tipos
de objetos. Adicionalmente, abre la posibilidad de tener diseños de clases fácilmente
reutilizables, reduciendo el esfuerzo en codificación.
9.8.1 Iteradores
Esta definición emplea un variable de tipo denominado E. Esta variable de tipo asume
el tipo de objeto que se desee en el instante de declarar variables. A continuación se
presenta el uso de la interfaz genérica Iterator:
Iterator<Integer> it = listaEnteros.iterator();
while (it.hasNext()) {
Integer x = it.next();
System.out.println(x);
}
J2EE 5.0 introduce una forma más elegante de iterar las colecciones:
for (Elemento x : c) {
procesar x.....
}
y aplica para cualquier objeto que implemente la interfaz Iterable, la cual es extendida
por la interfaz Collection.
10 Excepciones
Durante la ejecución de una aplicación, el flujo normal de control puede verse afectado por
situaciones excepcionales, como datos en formatos erróneos, archivos corruptos, daños en
los periféricos o en los medios de almacenamiento y ruptura en conexiones de red, entre
otros.
2. Definir y lanzar excepciones propias del negocio ("generar error al intentar asignar un
instructor a dos cursos que se dictan en el mismo horario").
3. Separar el código de manejo de errores del código que implementa la lógica normal del
programa:
10.2 Throwable
Error Exception
NullPointerException EOFException
El compilador de Java exige que los métodos atrapen (catch) o declaren todas la posibles
excepciones (excepto las RuntimeExcepcion) que puedan ser lanzadas (thrown) por las
instrucciones internas del método. Al intertar compilar una clase que viole la regla anterior,
el compilador fallará y generará el siguiente mensaje de error:
try {
// código protegido
} catch (tipoExcepcion1 e){
// procesar error;
} catch (tipoExcepcion2 e ) {
throw e; // re-enviar
} finally {
// ejecutar siempre
}
Una sentencian try debe estar acompañada de una o más cláusulas catch para
especificar que tipos de excepciones son manejadas.
Uno o más bloques catch definen los manejadores de excepciones de un bloque try. La
sentencia catch requiere un parámetro cuyo tipo debe corresponder a una clase que
herede de Throwable. Si el catch tiene como parámetro una clase base, entonces este
bloque catch define un manejador de excepciones generico que atrapa todas la
excepciones representadas por clases derivadas de la clase utilizada como parámetro
del catch.
La cláusula finally es utilizada para definir instrucciones que se deben llevar a cabo,
independientemente de la ocurrencia o no ocurrencia de excepciones. (por ejemplo
liberar recursos).
Ejemplo:
class SumaParametros {
public static void main(String[] args) {
int suma = 0;
int[] datos = new int[5];
try {
for (int i=0; i<args.length; i++) {
datos[i] = Integer.parseInt(args[i]);
suma += datos[i];
}
System.out.println("Total " + suma);
} catch(NumberFormatException e) {
System.out.println("Los parametros deben ser numeros");
} catch(ArrayIndexOutOfBoundException e) {
System.out.println("Arreglo desbordado");
}
}
}
Un método que en su interior invoque instrucciones que puedan generar excepciones, tiene
la posibilidad de manejar dichas excepciones por medio de un bloque try-catch o
declararlas.
La declaración de excepciones es empleado para propagar las excepciones al método
invocador.
La cláusula throws puede hacer parte del prototipo de un método, y es empleada para
indicar que excepciones no son manejadas en el interior del método, y que serán
propagadas hacia el método que haga la invocación.
Ejemplo:
class SumaParametros {
static int suma;
}
}
A pesar que el API de Java ofrece un gran número de excepciones predefinidas (clases
derivadas de Throwable), en el desarrollo de aplicaciones se puede requerir la definición de
excepciones propias del negocio para facilitar el entendimiento de los sucesos no deseados
en la aplicación.
Para definir nuevas excepciones , basta con crear una clase derivada de alguna clase que
pertenezca a la jerarquía Throwable.
Ejemplo: El intentar realizar una transferencia de fondos por un valor superior al saldo de la
cuenta origen debería generar una excepción.
throw objetoThrowable;
donde objetoThrowable debe ser una referencia a una instancia de objeto de una clase
derivada de Throwable. Ejemplo:
class CuentaAhorro{
public void transferencia(Cuenta ctaDestino, float monto) throws exception {
if (monto <= 0) {
Exception e = new MontoInvalidoException(
“El monto no puede ser negativo”);
throw e;
}
:
}
}
10.7 Consideraciones
10.8 Aserciones
Las aserciones son especialmente útiles en tiempo de desarrollo y depuración, por que
ayudan a seguir la ejecución del código , con una característica particular que pueden ser o
no utilizadas en tiempo de ejecución. Las aserciones se agregaron a partir de la versión 1.4
J2DK por lo que sería imposible compilar código de aserciones con una versión anterior.
La idea es que si se tiene conocimiento de un resultado o del comportamiento de alguna
variable, se utilicen las aserciones para evaluar un caso excepcional en que esa variable o
elemento se comporte de manera distinta. Aunque estos comportamientos se pueden
evaluar con una excepción se recomienda usar las aserciones ya que estas solamente se van
a utilizar en el periodo de prueba, y luego en tiempo de ejecución no es necesario que se
ejecuten.
La sintaxis es la siguiente :
/**
Tiene que dar true para que la suposición sea aceptada, en caso de ser false
java termina abruptamente a través de una excepción llamada AssertionError.
*/
assert expresión booleana;
/**
Este módelo es mas usado cuando la expresión booleana pueda retorna false,
En tal caso toma la segunda expresión sin importar el tipo de dato de ésta
por que se convierte en String y es pasado como como argumento al constructor
de la excepción AsserTionError para que imprima ese elemento cuando arroja
el mensaje de la excepción.
*/
assert expresión booleana : expresión de culaquier tipo
Las aserciones son generalmente usadas para verificar lógica interna de un método o un
pequeño grupos de métodos. Las aserciones pueden considerarse como precondiciones
de código, en caso de requerir evaluar el valor de alguna variable antes de realizar
alguna acción.
Por ejemplo si se quiere que la variable ‘Y’ sea positiva, podemos utilizar la siguiente
aserción.
Pero también las aserciones son útiles como postcondición de un código, esto cuando
se sabe que un método debe retornar algo con ciertas características, evaluando sí el
valor retornado cumple con esas características.
Por defecto las aserciones están desactivadas, por esta razón para poder compilar y
ejecutar un programa debemos hacerlo de la siguiente manera:
Por medio de la instrucción –source 1.4 se le indica a java que compile considerando el
concepto de aserciones, sin esa opción java no reconoce la sentencia assert y arrojara
un error de compilación.
Para el proceso de ejecución como las aserciones por defecto están desactivadas, y si
deseamos activarlas debemos digitar la siguiente instrucción:
11 Clases Anidadas
Las clases anidadas fueron adicionadas en el JDK 1.1. La característica especial de estas
clases es que se definen dentro de la definición de otra clase.
Se utilizan principalmente para agrupar clases que según el paradigma orientado a objetos
deberían estar agrupadas juntas de acuerdo con la lógica que manejan, y así poder controlar
la visibilidad de una, dentro de la otra.
Estas clases se construyen dentro de otra clase y pueden poseer todos lo posibles
modificadores de visibilidad como los métodos y atributos de clase.
Por tanto una clase anidada puede ser private, public, protected o default. Las propiedades
de cada uno de sus modificadores se mantienen, por ejemplo si una clase anidada se declara
protected podrá ser accedida por todas las clases y subclases dentro y fuera del paquete que
la contiene.
Ejemplos:
Ejemplo:
Dentro del alcance que contiene la clase anidada, podemos referirnos a la clase anidada
por su nombre Interna interna = new Interna().
Fuera de ese alcance se debe referir la clase como “Outer.Interna” y el nombre de
clase interna debe ser diferente de la clase que la contiene.
Se puede crear una clase anidada dentro de un método. Estas se denominan clases
locales.
Las clases locales pueden acceder variables locales incluyendo los argumentos del
método, siempre y cuando estas variables tengan el modificador final.
La clases anidadas pueden ser abstract
Un interface puede ser también anidada, e implementada de igual forma.
Excepto para las clase locales, las clases anidadas pueden ser declaradas con cualquier
modificador de visibilidad.
Las clases anidadas son compiladas cuando la clase que la contiene es compilada. El
.class que genera será del estilo: Outer$Interna.class
La clases anidadas pueden ser declaradas static, es cuyo caso no necesitan una referencia de
la clase que las contiene. Ej: Externa.Interna objeto= new Externa.Interna();
Si se van a declarar variables o métodos static dentro de una clase interna , es necesario que
dicha clase se declare static.
Ahora, si se declara static no va tener acceso a los elementos de la clase externa.
La idea de la clase static es obviar el paso de instancias de la clase externa en donde se
encuentra la clase interna o anidada. Es posible declarar en una clase interna estática
atributos o métodos no estáticos, sin embargo para poder acceder a dichos elementos es
necesario una instancia de la clase interna.
Las clases internas pueden acceder a variables de instancia de la clase que la contiene
usando la referencia this.
Las clases internas no pueden declara miembros static. En caso de necesitar de éstas, deben
ser declaradas en la clase que la contiene para que puedan ser usadas.
12 Streams
12.1 InputStream
InputStream es una clase abstracta que define los métodos fundamentales para la lectura de
información en el lado destinatario de los Streams.
12.2 OutputStream
OutputStream es una clase abstracta que representa un Stream de salida. Los métodos de
esta clase son:
12.3.1 File
Los objetos que son instancias de la clase File, representan y describen un archivo o
directorio.
Los métodos que provee está clase retornan las propiedades del archivo:
canRead()
canWrite()
exists()
getAbsolutePath()
getName()
getPath()
isDirectory()
isFile()
lastModified()
list(), list(FilenameFilter)
delete()
mkdir()
renameTo()
Ejemplo:
Estas clases extienden sus respectivas clases bases con los métodos finalize() y
getFD(). finalize() es el destructor de la clase que garantiza que el archivo se cerrara
cuando el objeto sea eliminado por el Garbage Collector. getFD() retorna un objeto de
tipo FileDescriptor que representa el descriptor de archivo respectivo del sistema
operativo.
Los constructores de estas clases pueden recibir como parámetro un String, un objeto
tipo File o un objeto FileDescriptor.
Ejemplo:
import java.io.*;
Cuando se emplea cache en la lectura de un Stream, por cada acceso al medio físico, el
buffer es llenado. Posteriores lecturas de bytes realizadas por el programa son
obtenidas del buffer.
De forma similar, cuando un programa escribe a un Stream los bytes son almacenados
temporalmente en el buffer hasta que este se llene. Los datos serán enviados a su
respectivo destino cuando el buffer esté lleno.
BufferedReader in =
new BufferedReader(fr);
String str;
12.4 Serialización
Los objetos que pueden ser serializados deben implementar la interfaz Serializable.
Esta interfaz no posee definición de métodos, pero si exige que todos los atributos de
las clases que la implementan, también implementen la interfaz Serializable.
transient es un modificador que aplica a los atributos de instancia de una clase. Este
modificar indica que el atributo no debe ser serializado en caso de emplear el método
writeObject.
Esto es deseable en atributos que pueden ser derivados de otros atributos o que son
creados en por el constructor de la clase.
Ejemplo:
12.5 Sockets
A pesar que el tema de comunicaciones en Java requiere más que un capitulo, en este
numeral introducimos el mecanismo de Sockets para ilustrar la funcionalidad de Streams y
Serialización en contextos diferentes al sistema de archivos.
Los Sockets permiten establecer un puente de comunicación entre procesos que pueden
estar corriendo en máquinas remotas interconectados via TCP/IP. Está comunicación es
bidireccional y está basada en el esquema Cliente/Servidor, donde el proceso servidor está
permanentemente activo, esperando la solicitud de algún cliente. Los servidores se
identifican por una dirección IP (máquina en la cual están corriendo) y un puerto
(identificación del proceso).
En Java los procesos Cliente y Servidor se representan por las clases Socket y ServerSocket
respectivamente.
Cliente Servidor
ServerSocket(puerto,
tamCola);
OutputStream OutputStream
InputStream InputStream
close() close()
br = new BufferedReader(
new InputStreamReader(sck.getInputStream()));
bw = new BufferedWriter(
new OutputStreamWriter(sck.getOutputStream()));
1. Crear el servidor por medio del constructor de la clase ServerSocket, el cual recibe el
puerto por el cual atenderá a sus clientes. Este debe ser un puerto no reservado por otro
servidor.
2. Invocar el método accept, que es un método bloqueante (detiene la ejecución de las
instrucciones hasta que un evento suceda), que queda en espera de la conexión de un
cliente.
3. Una vez un cliente se ha conectado, se establecen los streams de entrada/salida que
permiten comunicar los dos procesos.
5. Leer y escribir desde y para los streams de entrada y salida.
6. Cerrar la conexión con el cliente.
Ejemplo:
InputStream is = sck.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
Date fecha = (Date)ois.readObject();
OutputStream os = sck.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(new Date());
13 Applets
Un Applet es una aplicación pequeña que es accedida desde un servidor Web, transportada
a través de la red, instalada automáticamente y ejecutada como parte de una página HTML.
Estos son denominados subprogramas, ya que corren bajo el control de otro programa, que
generalmente es una navegador del web.
Ejemplo:
import java.awt.*;
import java.applet.*;
public class BienvenidaApplet extends Applet {
public void paint (Graphics g){
g.drawString(“Bienvenidos !“, 20, 20);
}
}
Este ejemplo crea la clase derivada BienvenidaApplet de la clase Applet. Esta clase
implementa el método paint, el cual es invocado cada vez que se requiera refrescar la
ventana en la cual está corriendo el Applet.
Para probar el applet BienvenidaApplet es necesario tener una página HTML que lo
contenga:
Para embeber un Applet en el interior de una página HTML, la página debe emplear el tag
Applet con la siguiente sintaxis:
<APPLET
[CODEBASE = URL] CODE = nombreapplet.class
[ALT = texto] [NAME = nombreInst]
[WIDTH = pixels][HEIGHT = pixels]
[ALIGN=alinear][VSPACE=pixels] [HSPACE=pixels]
>
[<PARAM NAME = param1 VALUE = value1 >]
[<PARAM NAME = param2 VALUE = value2 >]
[ Mensaje ]
</APPLET>
donde:
CODEBASE Especifica el URL raíz, donde se encuentra el
bytecode (archivos .class) que implementa el applet
Los Applets pasan por diferentes estados durante su ejecución en el navegador. Estos son:
Para cada uno de los estados por los cuales puede pasar un Applet, existe un método que se
puede redefiner para dar uso óptimo de la aplicación. Estos métodos son:
El tag Param de HTML es empleado para pasar parámetros al Applet. La sintaxis es:
<PARAM NAME=param1 VALUE=value1 >
donde param1 es el nombre del parámetro y value1 el valor que toma dicho parámetro. Un
tag APPLET puede presentar cero, uno o más tag PARAM.
Para capturar el valor de los parámetros, la clase Applet posee el método getParameter que
recibe el nombre del parámetro y retorna un String con su respectivo valor.
Ejemplo:
Las interfaces Gráfica de Usuario se desarrollan con el API Abstract Window Toolkit
(AWT), que provee los elementos o componentes gráficos como Botones, Ventanas y
Listas de selección. Adicionalmente, este API define el sistema de manejo de eventos para
la programación de aplicaciones gráficas. Las clases que conforman el API AWT se
encuentran en el paquete java.awt.
Una aplicación gráfica está conformada por componentes AWT anidados, donde la ventana
es el componente principal que actúa como contenedor de componentes AWT.
Component
La siguiente tabla presenta los componentes UI de AWT con sus respectivos métodos.
import java.awt.*;
import java.applet.*;
this.add(lb);
this.add(bt);
this.add(cb);
this.add(pn);
pn.add(rb1);
pn.add(rb2);
pn.add(rb3);
pn.add(ch);
}
}
A partir del JDK 1.1 el manejo de eventos sigue el modelo de delegación. Las definiciones
más importantes en este modelo son:
Ejemplo: Las siguientes clases conforman una aplicación con manejo de eventos:
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
valorActual++;
campoTexto.setText( "" + valorActual );
}
bAdicionar.addActionListener(actualizador);
java.awt.AWTEvent
java.awt.event.ComponentEvent (redimensionar un componente, mover)
java.awt.event.FocusEvent (obtener o perder el foco)
java.awt.eventInput
java.awt.event.KeyEvent
java.awt.event.MouseEvent
java.awt.event.ContainerEvent
java.awt.event.WindowEvent
14.2.2 Listener
Por cada clase Event existe una interfaz. A su vez, esta interfaz declara un método por
cada tipo de evento que la clase Event representa. Por ejemplo, la interfaz
FocusListener define los métodos focusGained() y focusLost().
Interfaz Métodos
ComponentListener componentHidden
componentMoved
componentResized
componentShown
ContainerListener componentAdded
componentRemoved
FocusListener focusGained
focusLost
KeyListener keyPressed
keyReleased
keyTyped
MouseListener mouseClicked
mouseEntered
mouseExited
mousePressed
mouseReleased
MouseMotionListener mouseDragged
mouseMoved
Interfaz Métodos
WindowListener windowActivated
windowClosed
windowClosing
windowDeactivated
windowDeiconified
windowIconified
windowOpened
ActionListener actionPerformed
AdjusmentListener adjustmentValueChanged
ItemListener itemStateChanged
TextListener textValueChanged
Los objetos que generan o disparan eventos pueden registrar uno o más objetos listener
que respondan a los eventos, mediante los métodos addTipoEventoListener.
La siguiente tabla define los métodos para registrar listener de cada componente:
14.2.4 Adaptadores
AWT provee clases denominadas Adaptadores que implementan las interfaces listener.
La implementación que proveen las clases adaptador se hace a través de métodos
vacíos.
Por ejemplo, si se desea crear una clase listener para capturar y procesar el evento
mouseClicked, esta clase debe implementar la interfaz MouseListener:
public ManejarClick() {
contador = 0;
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public ManejarClick() {
contador = 0;
}
public void mouseClicked(MouseEvent e) {
contador++;
}
}
ComponentAdapter
ContainerAdapter
FocusAdapter
KeyAdapter
MouseAdapter
MouseMotionAdapter
WindowAdapter
Observe que no existen clases adaptador para interfaces con un solo método.
Otra forma de conceptualizar un Hilo es definirlo como una CPU virtual con su propio
código y datos, la cual es encapsulada en una instancia de la clase Thread.
CPU
Código Datos
CPU
Código: Código que la CPU esta ejecutando.
Datos: Los datos sobre los cuales el código trabaja.
Crear una clase que implemente la interfaz Runnable, e implementar el método run(). El
constructor con argumentos de la clase Thread recibe a través de la instancia de
Runnable el código y datos que el hilo necesita para correr.
Permite abstraer la unidad de código que vamos a ejecutar. Se puede construir un hilo sobre
cualquier instancia de una clase que implemente la interfaz Runnable. Para ello la clase
debe implementar un único método llamado run(). Este método definirá el código que
constituye el nuevo hilo, y será el punto de entrada para la ejecución de otro hilo
concurrentemente.
Después de crear la clase que implemente la interfaz Runnable se creara una instancia de
Thread en otra clase o el misma, pasando como argumento al constructor de Thread la
instancia de la clase que implemento la interfaz Runnable.
El hilo que se acaba de crear no comenzara su ejecución hasta que llame al método start()
de la clase Thread, convirtiéndolo en elegible para ser ejecutado por parte del programador
de hilos.
Ejemplo:
La segunda forma de crear un hilo es crear una nueva clase que herede de la clase Thread.
La nueva clase debe sobrescribir el método run(), que será el punto de entrada del nuevo
hilo.
public class NuevoHilo extends Thread{
public void run(){
for(int i=0;i<500;i++){
System.out.println("valor de i"+i);
}
}
El método run() no se llama directamente, se debe llamar al método start() de la clase padre
(Thread) y este método registra el thread con el programador de hilos quien se encargara de
ordenar cuando ejecutar el hilo y al mismo tiempo llamar al método run()
Blocked
Runnable: El hilo esta listo para ejecutarse y esperando que el programador de hilos le
permita correr.
Blocked : Temporalmente el hilo esta bloqueado por que no encontró los recursos de I/O
que necesitaba o por que se pauso por la llamada a los método sleep(), join(), yield(), o
wait().
Dead : El hilo termino su ejecución. En este estado el hilo no puede volver a ser ejecutado.
El programador o Schedule de hilos utiliza las prioridades de los hilos que van de 1 a 10
para decidir cuándo permitir la ejecución de un hilo.
Para obtener la prioridad de un hilo podemos utilizar el método getPriority().
y para establecer una prioridad utilizamos el método setPriority(int nivel) donde nivel es
valor que se le asignara como prioridad al hilo.
La clase Thread incluye unas constantes que podemos utilizar para asignar prioridades.
Thread.MIN_PRIORITY =1;
Thread.NORM_PRIORITY =5;
Thread.MAX_PRIORITY =10;
Por defecto cuando se crea un hilo su prioridad es 5.
Método Thread.sleep()
Este método es una de las maneras de pausar un hilo por un periodo de tiempo, que puede
ser milisegundos o nanosegundos.
new NuevoThread("uno");
new NuevoThread("dos");
new NuevoThread("tres");
}
}
El método join() causa que el hilo que actualmente se este ejecutando espere hasta el hilo
que invoco el método termine su ejecución.
Veamos una modificación del ejemplo anterior para ilustrar el uso de los métodos:
Use este método para darle la oportunidad a otros hilos de ejecutarse. Si otros hilos están en
estado runnable, al invocar yield() el hilo cede el tiempo asignado de CPU , y se coloca en
el pool de runnable, permitiendo que otros hilos de igual o mayor prioridad puedan
ejecutarse. Si no hay hilos en el pool de runnable no hace nada. Se diferencia con el método
sleep() por que sleep() si permite que se ejecuten hilos de cualquier prioridad.
Cuando dos o mas hilos quieren acceder a un recurso compartido, es necesario asegurarse
de alguna manera que solo un hilo a la vez pueda acceder al recurso, y evitar el riesgo de
dañar la consistencia de los datos. Este proceso se llama sincronización.
La clave para la sincronización es el concepto de monitor. Monitor es un objeto que se
utiliza con cerrojo.
La sincronización en java es sencilla por que todos los objetos poseen su propio monitor.
Para entrar en el monitor de un objeto basta con invocar al método modificado con la
palabra synchronized. Mientras un hilo este en un método sincronizado, todos los demás
hilos que intenten entrar al código sincronizado deberán esperar en el pool de hilos
asociado al objeto dueño del monitor a que el monitor sea liberado.
Para sincronizar un código podemos utilizar dos técnicas, pero ambas utilizan la palabra
reservada synchronized.
Colocar la palabra synchronized como modificador del método, permitiendo que todo el
código del método quede sincronizado. Esta técnica tiene la ventaja de que al generar la
documentación de la aplicación con el javadoc, el usuario tiene la ventaja de saber que
se esta trabajando con métodos sincronizados y diseñar la aplicación contra posibles
deadlock (abrazo mortal). Sin embargo tiene la desventaja de sacrificar desempeño de
la aplicación por tener mucho tiempo el monitor del objeto.
Synchronized(this){
:
:
}
}
En programas multilhilos donde están compitiendo por acceso a múltiples recursos una
condición conocida como deadlock o abrazo mortal puede ocurrir.
Este fenómeno puede ocurrir por ejemplo cuando un hilo ‘A’ esta esperando el monitor del
hilo ‘B’, pero el hilo ‘B’ esta esperando a su vez el monitor del hilo ’A’. En esta situación
ninguno puede proceder hasta el otro termine de pasar el bloque sincronizado. Como
ninguno puede proceder ni liberar el monitor, se produce el abrazo mortal.
Java no puede evitar esa condición, es responsabilidad del programador manejar esta
situación. Como regla general para evitar esta condición en caso de tener muchos objetos
que deseen tener acceso sincronizado a su código, debe tener una decisión del orden en el
cual se deberán obtener los monitores de los objetos e implementarlo en la aplicación. La
liberación deberá ser en el orden inverso en que se obtuvieron.
o cerrojo. Este hilo entra al pool de hilos en espera el cual es manejado por el objeto que
posee el código sincronizado y que llamo al método wait()... (objeto.wait()).
Wait() : indica al hilo que realiza la llamada que debe liberar el monitor y quedar en espera
hasta que algún otro hilo entre en el mismo monitor (código sincronizado) y llame al
método notify()
notifyAll() : activa todos los hilos que llamaron wait() en el mismo objeto. El hilo de
prioridad mas alta será el primero en ejecutarse.
Dentro del get() se llama a wait(), esto ocasiona que el hilo suspenda su ejecución hasta
que el productor notifique con el método notify() que los datos están listos para ser
recuperados. Cuando sucede esto, se reanuda la ejecución dentro del get(), una vez
obtenidos los datos desde el método get() se llama a notify(), esto le indica al productor que
puede colocar mas datos. Dentro del put() el método wait() suspende la ejecución hasta que
el consumidor haya recuperado el dato. Cuando la ejecución continua continúa se coloca el
siguiente dato en la cola y se llama a notify(), lo que le indica al consumidor que puede
retirarlo o consumirlo.
}
}
this.n=n;
valueSet=true;
System.out.println("Produce"+n);
notify();
}
}
16 JDBC
16.1 Introducción
JDBC es un API que permite enviar sentencias SQL estándares hacia una base de datos
relacional. La principal ventaja de la utilización de este API, es su independencia del motor
de bases de datos que se esté empleando. Así, una aplicación cliente desarrollada con Java
y JDBC es independiente de la plataforma (sistema operativo, hardware) y del motor de
bases de datos donde reside la información.
JDBC se considera como un API de bajo nivel ya que no pretende abstraer como objetos
los conceptos de tablas, registros y columnas.
JDBC está basado en drivers los cuales son componentes de software proveídos y/o
optimizados por cada motor de bases de datos. Cada driver debe proveer la implementación
a las interfaces Connection, Statement, PreparedStatement, CallableStatement, ResultSet y
Driver.
Aplicación Java
API
JDBC
Driver Manager Driver JDBC
Implementaciones
del driver JDBC
SMBD
17 Código JDBC
Este capítulo ilustra la utilización de las interfaces que conforman el API JDBC
(Connection, Statement, PreparedStatement y CallableStatement).
1 import java.sql.*;
2
3 class Cliente {
4 public static void main (String args[]) {
5
6 Class.forName ("oracle.jdbc.driver.OracleDriver");
7
8
9 Connection conn = DriverManager.getConnection(
10 "jdbc:oracle:thin:@10.57.56.25:1521:bdA",
11 "usuario", "clave");
12
13 Statement stmt = conn.createStatement();
14
15 ResultSet rset = stmt.executeQuery("select nombre from Cliente");
16
17 while( rset.next () ) {
18 System.out.println (rset.getString(1));
19 }
20 }
21 }
jdbc:<subprotocol>:<subname>
Los objetos de tipo ResultSet permiten acceder a los registros retornados por una
sentencia SELECT. Cada ResultSet mantiene una referencia al registro actual. El
registro actual se actualiza cada vez que se invoque el método next().
Las columnas (o campos) del registros actual son accedidas por medio de los métodos
getXXX (donde XXX corresponde al tipo de dato de la columna). Las columnas en los
métodos getXXX pueden ser especificadas por el nombre (String) o por el índice de la
columna (int).
La parametrización se logra por medio del símbolo ?, en los campos que pueden
modificados:
PreparedStatement ps = conn.prepareStatement(
"insert into personas values(?, ?, ?)");
Los datos pendiente por definir (?), son llenados por medio de la familia de métodos
setXXX.
ps.setInt(1, 25);
ps.setString(2, "SEBASTIAN");
ps.setString(3, "RODRIGUEZ");
Una vez cada una los parámetros (símbolo ?) han sido reemplazados, se puede invocar
la ejecución de la sentencia:
CallableStatement cs = conn.prepareCall(
"{call obtener_nombre(?,?)}");
Los parámetros de entrada deben ser reemplazarlos por su respectivo valor, usando los
métodos setXXX :
cs.setInt(1, 1234);
Los parámetros de salida deben ser registrados antes de ejecutar la sentencia, con el fin
de determinar el tipo de dato que se espera sea retornado:
cs.registerOutParameter(2, Types.VARCHAR);
Una vez se ha ejecutado la sentencia, se pueden recuperar los parámetros de salida por
medio de los métodos getXXX:
cs.executeUpdate();
String strNombre = cs.getString(2);
17.2 Transacciones
conn.setAutoCommit(false);
18 Ejercicios
18.1 Capitulo 1.
Respuesta (C)
_______________________
Respuesta (Bytecode)
Respuesta
18.2 Capitulo 3.
1. Cual debe ser el prototipo del método main() para que sea empleado como punto de
entrada de una aplicación Java:
Respuesta
int[] arrA;
int[] arrB;
arrB = arrA;
arrA = new int[10];
_______________________
Respuesta arrA[1] = 1
4. ECO de frases en reversa: Desarrolle un programa que recibe como argumentos las
palabras que conformen una frase, y que imprima dicha frase al revés:
>java ReversarFrase esta es prueba facil
>facil prueba una es esta
k-1 n
∑ (k-i) . arr[i] = ∑ (j-k) . arr[j]
i=0 j=k+1
donde n es el tamaño de arreglo arr.
6 0 8 4 1 2
Notas:
1. Los datos del arreglo se reciben de la línea de comandos. Ejemplo
>java Centro 6 0 8 4 1 2
2. Emplee el método parseInt de la clase Integer para convertir cadenas de
texto a valores numéricos.
3. Emplee el método abs de la clase Math para calcular el valor absoluto de
un valor entero.
18.3 Capitulo 4 y 5
<<abstract>>
MedioTransporte
Terrestre Aereo
9. terr2 = aut1;
10. mt1 = trans1;
11. mt2 = av1;
3. Respuesta Ninguna
En a no se esta creando una instancia
En b no se requiere cast
En c no se puede convertir un medio de transporte hacia moto
En d no se puede convertir avión hacia moto
Respuesta
Valores: 5 20 30
Valores: 5 15 25
5. Sobrescriba el método toString() en la clase Persona. Este método debe retornar una
cadena como la concatenación de nombres, primer apellido y segundo apellido. Ej:
Jairo Orlando Perez Silva.
Respuesta
Respuesta
18.4 Capitulo 6
Respuesta
// Reversar frase
/*StringBuffer st;
Respuesta
En la clase Persona
{
return(true);
}
else
{
return(false);
}
}
En la clase de prueba
if (p1.equals(p2))
{
System.out.println("Son iguales");
}
else
System.out.println("No son iguales");
Respuesta
BufferedReader in =
new BufferedReader(fr);
BufferedWriter out =
new BufferedWriter (fw);
String str;
}
in.close();
out.close();
}catch(IOException e) {
System.out.println("Error: " + e);
}
}
}
Respuesta
//Escribir archivo
FileOutputStream fOut = new
FileOutputStream("c:\\java\\persona.txt");
ObjectOutputStream out = new ObjectOutputStream (fOut);
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}*/
try {
FileInputStream fIn = new FileInputStream("c:\\java\\persona.txt");
ObjectInputStream in = new ObjectInputStream(fIn);
Persona p2 = (Persona) in.readObject();
System.out.println(p2);
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
1. Cuáles de las siguientes son sentencias son válidas para inicializar un arreglo?
Respuesta (a)
System.out.println(a[1]);
System.out.println(a[3]);
}
}
Respuesta (d)
3. Según el fragmento de código siguiente, ¿cuál es el índice del elemento que contiene
45?
int[] numbers = {-1, 45, 6, 132};
(a) 2
(b) 45
(c) 0
(d) 1
Respuesta (d)
Respuesta (d)
5. ¿En cuál de las siguientes formas pueden agregarse elementos a una colección
implementada por java.util.ArrayList?
I. Items pueden ser insertados al inicio de la colección.
Respuesta (b)
Respuesta (b)
7. Un objeto que contiene métodos que recorre una colección linealmente desde el inicio
hasta el fin se conoce como.
(a) loop
(b) iterator
(c) int
(d) Exception
Respuesta (b)
java.util.ArrayList?
(a) Items almacenados por un objeto ArrayList pueden ser accesados usando
indices enteros.
(b) Una vez un objeto es insertado en una instancia de ArrayList, este nunca
puede ser eliminado.
(c) El constructor de la clase ArrayList, cuando es llamado sin argumento, Causa
que un ArrayList vacio sea construido.
(d) Una instancia de ArrayList puede crecer para acomodar nuevos items cuando
la colección está llena.
Respuesta (b)
Respuesta (b)
(a) GridBagLayout
(b) BorderLayout
(c) FlowLayout
(d) GridLayout
Respuesta (c)
Respuesta (d)
4. Cuáles de las siguientes sentencias son verdaderas con respecto al manejo de eventos
en Java?
I. Cuando un componente GUI es creado, el component automaticamente tiene
la habilidad para generar eventos durante la interacción con èl usuario.
II. Cada objeto Listener debe estar registrado con el componente específico
para que el objeto Listener responda.
(a) Ninguno
(b) Solo II
(c) I y II
(d) Solo I
Respuesta (c)
5. En Java, Cual es la firma del método de la interfaz WindowListener donde se
adiciona el código para finalizar un programa cuando el botón es presionado?
(a) ButtonEvent
(b) ClickEvent
(c) ActionEvent
(d) WindowEvent
Respuesta (c)
7. La clase ListSelectionEvent y la interface ListSelectionListener estàn
disponibles en el paquete ____________ de Java.
(a) java.awt.event
(b) java.event
(c) javax.event
(d) javax.swing.event
Respuesta (d)
8. Cuál de los siguientes eventos Java es generado cuando el botón cerrar de un
componente JFrame es presionado?
(a) ExitEvent
(b) DisposeEvent
(c) CloseEvent
(d) WindowEvent
Respuesta (d)
La clase Catalog tiene un método llamado getCodes que retorna un arreglo de código de
productos que usa el CatalogGUI para llenar el JList. Una complete implementación
Catalog es proporcionada.
Archivos
Los siguientes archivos son necesarios:
student-files.zip:
o Archivos de clases
Product.class
Coffee.class
CoffeeBrewer.class
Catalog.class
CatalogLoader.class
FileCatalogLoader.class
DataFormatException.class
DataField.class
o Documentacion
Product.html
Coffee.html
CoffeeBrewer.html
Catalog.html
CatalogLoader.html
FileCatalogLoader.html
DataFormatException.html
DataField.html
o Archivo Java
Tareas
o Cambiar la implementación de manejo de archivos planos hacia consultas de
base de datos (Access)
o Modificar la interface con el fin de permitir modificar uno de los atributos
del producto.
o Modificar la interface para permitir eliminar productos de la base de datos
o Modificar la interface para permitir adicionar productos.
o Documentar cada una de las anteriores funcionalidades para posteriormente
generar documentación con Javadoc
Solución
public CatalogSolution loadCatalog(String filename)
throws FileNotFoundException, IOException, DataFormatExceptionSolution {
try {
Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver");
//
Connection conn = DriverManager.getConnection("jdbc:odbc:cafe");
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery("select codigo,descripcion,precio from Producto where
tipo='producto'");
while( rset.next () ) {
//System.out.println (rset.getString(1));
//System.out.println (rset.getString(2));
//System.out.println (rset.getDouble(3));
product= new ProductSolution(rset.getString(1),rset.getString(2),23f);
catalog.addProduct(product);
}
}
catch(ClassNotFoundException e){
e.printStackTrace();
}
catch(SQLException e){
e.printStackTrace();
}
return catalog;
}