miércoles, 10 de noviembre de 2010

Hilos

Hilo.
Es un único flujo de ejecución dentro de un proceso.
Un proceso es un programa ejecutándose dentro de su propio espacio de direcciones. Un hilo es una secuencia de código en ejecución dentro del contexto de un proceso. Los hilos no pueden ejecutarse ellos solos; requieren la supervisión de un proceso padre para correr. Dentro de cada proceso hay varios hilos ejecutándose.
Los hilos a menudo son conocidos o llamados procesos ligeros. Un hilo, en efecto, es muy similar a un proceso pero con la diferencia de que un hilo siempre corre dentro del contexto de otro programa. Por el contrario, los procesos mantienen su propio espacio de direcciones y entorno de operaciones. Los hilos dependen de un programa padre en lo que se refiere a recursos de ejecución. La siguiente figura muestra le relación entre hilos y procesos.
Clases.


Thread
La clase Thread es la clase responsable de producir hilos funcionales para otras clases. Para añadir la funcionalidad de hilo a una clase simplemente se deriva la clase de Thread y se ignora el método run. Es en este método run donde el procesamiento de un hilo toma lugar, y a menudo se refieren a él como el cuerpo del hilo. La clase Thread también define los métodos start y stop, los cuales te permiten comenzar y parar la ejecución del hilo, además de un gran número de métodos útiles.

Runnable
Java no soporta herencia múltiple de forma directa, es decir, no se puede derivar una clase de varias clases padre. Esto nos plantea la duda sobre cómo podemos añadir la funcionalidad de Hilo a una clase que deriva de otra clase, siendo ésta distinta de Thread. Para lograr esto se utiliza la interfaz Runnable. La interfaz Runnable proporciona la capacidad de añadir la funcionalidad de un hilo a una clase simplemente implementando la interfaz, en lugar de derivándola de la clase Thread.
Las clases que implementan la interfaz Runnable proporcionan un método run que es ejecutado por un objeto hilo asociado que es creado aparte. Esta es una herramienta muy útil y a menudo es la única salida que tenemos para incorporar multihilo dentro de las clases. Esta cuestión será tratada más ampliamente en el apartado de Creación de hilos.
ThreadDeath
La clase de error ThreadDeath proporciona un mecanismo que permite hacer limpieza después de que un hilo haya sido finalizado de forma asíncrona. Se llama a ThreadDeath una clase error porque deriva de la clase Error, la cual proporciona medios para manejar y notificar errores. Cuando el método stop de un hilo es invocado, una instancia de ThreadDeath es lanzada por el moribundo hilo como un error. Sólo se debe recoger el objeto ThreadDeath si se necesita para realiza una limpieza específica a la terminación asíncrona, lo cual es una situación bastante inusual. Si se recoge el objeto, debe ser relanzado para que el hilo realmente muera.

Creación de threads derivando de la clase Thread

Considérese el siguiente ejemplo de declaración de una nueva clase:
public class SimpleThread extends Thread {
// constructor
public SimpleThread (String str) {
super(str);
}
// redefinición del método run()
public void run() {
for(int i=0;i<10;i++)
System.out.println("Este es el thread : " + getName());
}
}
En este caso, se ha creado la clase SimpleThread, que hereda de Thread. En su constructor se utiliza un String (opcional) para poner nombre al nuevo thread creado, y mediante super() se llama al constructor de la super-clase Thread. Asimismo, se redefine el método run(), que define la principal actividad del thread, para que escriba 10 veces el nombre del thread creado.
Para poner en marcha este nuevo thread se debe crear un objeto de la clase SimpleThread, y llamar al método start(),heredado de la super-clase Thread, que se encarga de llamar a run(). Por ejemplo:
SimpleThread miThread = new SimpleThread(“Hilo de prueba”);
miThread.start();

Creación de threads implementando la interface Runnable

Esta segunda forma también requiere que se defina el método run(), pero además es necesario crear un objeto de la clase Thread para lanzar la ejecución del nuevo hilo. Al constructor de la clase Thread hay que pasarle una referencia del objeto de la clase que implementa la interface Runnable.
Posteriormente, cuando se ejecute el método start() del thread, éste llamará al método run() definido en la nueva clase. A continuación se muestra el mismo estilo de clase que en el ejemplo anterior implementada mediante la interface Runnable:
public class SimpleRunnable implements Runnable {
// se crea un nombre
String nameThread;
// constructor
public SimpleRunnable (String str) {
nameThread = str;
}
// definición del método run()
public void run() {
for(int i=0;i<10;i++)
System.out.println("Este es el thread: " + nameThread);
}
}

CICLO DE VIDA DE UN THREAD
En el apartado anterior se ha visto cómo crear nuevos objetos que permiten incorporar en un programa la posibilidad de realizar varias tareas simultáneamente. En la Figura se muestran los distintos estados por los que puede pasar un thread a lo largo de su vida. Un thread puede presentar cuatro estados distintos:
1. Nuevo (New): El thread ha sido creado pero no inicializado, es decir, no se ha ejecutado todavía el método start(). Se producirá un mensaje de error (IllegalThreadStateException) si se intenta ejecutar cualquier método de la clase Thread  distinto de start().
2. Ejecutable (Runnable): El thread puede estar ejecutándose, siempre y cuando se le haya asignado un determinado tiempo de CPU. En la práctica puede no estar siendo ejecutado en un instante determinado en beneficio de otro thread.
3. Bloqueado (Blocked o Not Runnable): El thread podría estar ejecutándose, pero hay alguna actividad interna suya que lo impide, como por ejemplo una espera producida por una operación de escritura o lectura de datos por teclado (E/S). Si un thread está en este estado, no se le asigna tiempo de CPU.
4. Muerto (Dead): La forma habitual de que un thread muera es finalizando el método run(). También puede llamarse al método stop() de la clase Thread, aunque dicho método es considerado “peligroso” y no se debe utilizar.







CREACIÓN DE HILOS
En Java, los hilos comparten el mismo espacio de memoria. Incluso comparten gran parte del entorno de ejecución, de modo que la creación de nuevos hilos es mucho más rápida que la creación de nuevos procesos. La ventaja que proporcionan los hilos es la capacidad de tener más de un camino de ejecución en un mismo programa. Así, con un único proceso, ejecutándose una JVM (Java Virtual Machine), habrá siempre más de un hilo, cada uno con su propio camino de ejecución.
En cuanto al proceso de creación de hilos, son dos los mecanismos que nos permiten llevarlo a cabo en Java: implementando la interfaz Runnable, o extendiendo la clase Thread, esto es, creando una subclase de esta clase.
Lo más habitual es crear hilos implementando la interfaz Runnable, dado que las interfaces representan una forma de encapsulamiento del trabajo que una clase debe realizar.
Así, se utilizan para el diseño de requisitos comunes a todas las clases que se tiene previsto implementar. La interfaz define el trabajo, la funcionalidad que debe cubrirse, mientras que la clase o clases que implementan la interfaz realizan dicho trabajo (cumplen esa funcionalidad).
Todas las clases o grupos de clases que implementen una cierta interfaz deberán seguir las mismas reglas de funcionamiento.
El otro mecanismo de creación de hilos, como ya hemos dicho, consistiría en la creación previa de una subclase de la clase Thread, la cual podríamos instanciar después.
Por ejemplo,
class MiThread extends Thread {
public void run() {
. . .
}
}
se corresponde con la declaración de un clase, MiThread, que extiende la clase Thread, sobrecargando el método Thread.run heredado con su propia implementación.

Es en el método run donde se implementa el código correspondiente a la acción (la tarea) que el hilo debe desarrollar. El método run no es invocado directa o explícitamente (a menos que no quieras que se ejecute dentro de su propio hilo). En lugar de esto, los hilos se arrancan con el método start, se suspenden con el método suspend, se reanudan con el método resume, y se detienen con el método stop (el cual supone también la muerte del hilo y la correspondiente excepción ThreadDeath), como ya explicaremos en el apartado de Estado y Control de Hilos. Un hilo suspendido puede reanudarse en la instrucción del método run en la que fue suspendido.
En el caso de crear un hilo extendiendo la clase Thread, se pueden heredar los métodos y variables de la clase padre. Si es así, una misma subclase solamente puede extender o derivar una vez de la clase padre Thread. Esta limitación de Java puede ser superada a través de la implementación de Runnable. Veamos el siguiente ejemplo:
public class MiThread implements Runnable {
Thread t;
public void run() {
// Ejecución del thread una vez creado
}
}
En este caso necesitamos crear una instancia de Thread antes de que el sistema pueda ejecutar el proceso como un hilo. Además, el método abstracto run que está definido en la interfaz Runnable tiene que implementarse en la nueva clase creada.
La diferencia entre ambos métodos de creación de hilos en Java radica en la flexibilidad con que cuenta el programador, que es mayor en el caso de la utilización de la interfaz Runnable.
Sobre la base del ejemplo anterior, se podría extender la clase MiThread a continuación, si fuese necesario. La mayoría de las clases creadas que necesiten ejecutarse como un hilo implementarán la interfaz Runnable, ya que así queda cubierta la posibilidad de que sean extendidas por otras clases.

ESTADOS DE UN HILO
El comportamiento de un hilo depende del estado en que se encuentre, este estado define su modo de operación actual, por ejemplo, si esta corriendo o no. A continuación proporcionamos la relación de estados en los que puede estar un hilo Java.
• New
• Runnable
• Not running
• Dead
New
Un hilo esta en el estado new la primera vez que se crea y hasta que el método start es llamado. Los hilos en estado new ya han sido inicializados y están listos para empezar a trabajar, pero aún no han sido notificados para que empiecen a realizar su trabajo.
Runnable
Cuando se llama al método start de un hilo nuevo, el método run es invocado y el hilo entra en el estado runnable. Este estado podría llamarse “running” porque la ejecución del método run significa que el hilo esta corriendo. Sin embargo, debemos tener en cuenta la prioridad de los hilos. Aunque cada hilo está corriendo desde el punto de vista del usuario, en realidad todos los hilos, excepto el que en estos momentos esta utilizando la CPU, están en el estado runnable (ejecutables, listos para correr) en cualquier momento dado. Uno puede pensar conceptualmente en el estado runnable como si fuera el estado “running”, sólo tenemos que recordar que todos los hilos tienen que compartir los recursos del sistema.
Not running
El estado not running se aplica a todos los hilos que están parados por alguna razón. Cuando un hilo está en este estado, está listo para ser usado y es capaz de volver al estado runnable en un momento dado. Los hilos pueden pasar al estado not running a través de varias vías.
A continuación se citan diferentes eventos que pueden hacer que un hilo esté parado de modo temporal.
• El método suspend ha sido llamado
• El método sleep ha sido llamado
• El método wait ha sido llamado
• El hilo esta bloqueado por I/O
Para cada una de estas acciones que implica que el hilo pase al estado not running hay una forma para hacer que el hilo vuelva a correr. A continuación presentamos la lista de eventos correspondientes que pueden hacer que el hilo pase al estado runnable.
• Si un hilo está suspendido, la invocación del método resume
• Si un hilo está durmiendo, pasarán el número de milisegundos que se ha especificado que debe dormir
• Si un hilo está esperando, la llamada a notify o notifyAll por parte del objeto por el que espera
• Si un hilo está bloqueado por I/O, la finalización de la operación I/O en cuestión
Dead
Un hilo entra en estado dead cuando ya no es un objeto necesario. Los hilos en estado dead no pueden ser resucitados y ejecutados de nuevo. Un hilo puede entrar en estado dead a través de dos vías:
• El método run termina su ejecución.
• El método stop es llamado.
La primera opción es el modo natural de que un hilo muera. Uno puede pensar en la muerte de un hilo cuando su método run termina la ejecución como una muerte por causas naturales.
En contraste a esto, está la muerte de un hilo “por causa” de su método stop. Una llamada al método stop mata al hilo de modo asíncrono.
Aunque la segunda opción suene un poco brusca, a menudo es muy útil. Por ejemplo, es bastante común que los applets maten sus hilos utilizando el método stop cuando el propio método stop del applet ha sido invocado. La razón de esto es que el método stop del applet es llamado normalmente como respuesta al hecho de que el usuario ha abandonado la página web que contenía el applet y no es adecuado dejar hilos de un applet corriendo cuando el applet no está activo, así que es deseable matar los hilos.
Control de un hilo
Arranque de un hilo
En el contexto de las aplicaciones, sabemos que es main la primera función que se invoca tras arrancar, y por tanto, lógicamente, es el lugar más apropiado para crear y arrancar otros hilos.
La línea de código:
t1 = new TestTh( "Thread 1",(int)(Math.random()*2000) );
Siendo TestTh una subclase de la clase Thread (o una clase que implemente la interfaz Runnable) crea un nuevo hilo. Los dos argumentos pasados, sin mayor relevancia, satisfarán el prototipo del constructor de la clase y se utilizarán para la inicialización del objeto.
Al tener control directo sobre los hilos, tenemos que arrancarlos explícitamente. Como ya se comentó anteriormente, es la función miembro start la que nos permite hacerlo. En nuestro ejemplo sería:
t1.start();
start, en realidad es un método oculto en el hilo que llama al método run.

Manipulación de un hilo
Si todo fue bien en la creación del objeto TestTh (t1), éste debería contener un hilo, una traza de ejecución válida, que controlaremos en el método run del objeto.
El cuerpo de esta función miembro viene a ser el cuerpo de un programa como ya los conocemos. Digamos que es la rutina main a nivel de hilo. Todo lo que queremos que haga el hilo debe estar dentro del método run. Cuando finalice run, finalizará también el hilo que lo ejecutaba.
Suspensión de un Hilo
La función miembro suspend de la clase Thread permite tener un control sobre el hilo de modo que podamos desactivarlo, detener su actividad durante un intervalo de tiempo indeterminado, a diferencia del uso de la llamada al sistema sleep, que simplemente lleva al hilo a un estado de “dormido”, y siempre durante un número de milisegundos concreto.
Este método puede resultar útil si, construyendo un applet con un hilo de animación, queremos permitir al usuario detener (que no finalizar) la animación, hasta que éste decida reanudarla.
Este método no detiene la ejecución permanentemente. El hilo es suspendido indefinidamente y para volver a activarlo de nuevo necesitamos realizar una invocación a la función miembro resume.
Parada de un Hilo
Ya conocemos los métodos de control de hilos que nos permiten arrancarlos, suspenderlos y reanudarlos. El último elemento de control que se necesita sobre hilos es el método stop, utilizado para terminar la ejecución de un hilo de forma permanente:
t1.stop();
Señalar que esta llamada no destruye el hilo, sino que detiene su ejecución, y ésta no puede reanudarse con el método start. Cuando se desasignen las variables que se usan en el hilo, el objeto hilo (creado con new) quedará marcado para eliminarlo y el garbage collector (recolector de basura de Java) se encargará de liberar la memoria que utilizaba.
Tiene sentido su utilidad, por ejemplo, en aplicaciones complejas que necesiten un control sobre cada uno de los hilos que se lancen.
Por último, un método de control de hilos que nos permite comprobar si una instancia está viva (el hilo se ha arrancado y aún no se ha detenido) o no (bien no se arrancó; bien ya finalizó).

Creación de threads derivando de la clase Thread

Considérese el siguiente ejemplo de declaración de una nueva clase:

public class SimpleThread extends Thread {
// constructor
public SimpleThread (String str) {
super(str);
}
// redefinición del método run()
public void run() {
for(int i=0;i<10;i++)
System.out.println("Este es el thread : " + getName());
}
}
En este caso, se ha creado la clase SimpleThread, que hereda de Thread. En su constructor se utiliza un String (opcional) para poner nombre al nuevo thread creado, y mediante super() se llama al constructor de la super-clase Thread. Asimismo, se redefine el método run(), que define la principal actividad del thread, para que escriba 10 veces el nombre del thread creado.
Para poner en marcha este nuevo thread se debe crear un objeto de la clase SimpleThread, y llamar al método start(),heredado de la super-clase Thread, que se encarga de llamar a run(). Por ejemplo:
SimpleThread miThread = new SimpleThread(“Hilo de prueba”);
miThread.start();

Creación de threads implementando la interface Runnable

Esta segunda forma también requiere que se defina el método run(), pero además es necesario crear un objeto de la clase Thread para lanzar la ejecución del nuevo hilo. Al constructor de la clase Thread hay que pasarle una referencia del objeto de la clase que implementa la interface Runnable.
Posteriormente, cuando se ejecute el método start() del thread, éste llamará al método run() definido en la nueva clase. A continuación se muestra el mismo estilo de clase que en el ejemplo anterior implementada mediante la interface Runnable:
public class SimpleRunnable implements Runnable {
// se crea un nombre
String nameThread;
// constructor
public SimpleRunnable (String str) {
nameThread = str;
}
// definición del método run()
public void run() {
for(int i=0;i<10;i++)
System.out.println("Este es el thread: " + nameThread);
}
}

jueves, 26 de agosto de 2010

Taller Calculadora

Ejercicio Propuesto:

Realizar un POO que solicite dos numeros y realice las siguientes operaciones:
- suma.
- resta.
- multiplicacion.
- factorial.
- modulo.

Diagrama Caso de Uso





Diagrama de Clases




Codigo fuente
Paquete logica
clase servicio

package logica;


public class servicio
{
private int dato;
public int getDato()
{
return dato;
}
public void setDato(int dato)
{
this.dato = dato;
}
public servicio ()//constructor inicializa la variable
{
this.dato=0;
}

public int[] ordenarPar(int vector[ ])
{
int vectorpar [ ] = new int [10];
for (int i = 0; i <= 9; i++)
{
int a = vector [i];
if (esPar(a) )
vectorpar [i] = a;
}

for (int i=0; i<vectorpar.length; i++)
{
for (int j=vectorpar.length-1; j>0; j--)
{
if (vectorpar [j]<vectorpar [j-1])
{
int temp = vectorpar [j];
vectorpar [j] = vectorpar [j-1];
vectorpar [j-1] = temp;
}
}
}
return (vectorpar);
}

static boolean esPar(int numero)
{
if (numero%2==0)
return true;
else
return false;
}
}


Paquete presentacion
clase formulario

package presentacion;


import java.io.*;
import logica.*;

public class formulario {
private servicio obj1= new servicio();
public static void main (String args[]) throws IOException {

servicio obj1 =new servicio();

System.out.println("digite primer numero");

int dato1=leer();
System.out.println("digite segundo numero");
int dato2=leer();
obj1.setDato(dato1);
obj1.setDato2(dato2);
System.out.println("Suma: " + dato1 + " + " + dato2 +" = "+obj1.sumar());// sumar(dato2));
System.out.println("Resta: " + dato1 + " - " + dato2 +" = "+obj1.restar());
System.out.println("Multiplicacion: " + dato1 + " * " + dato2 +" = "+obj1.multiplicar());
System.out.println("Factorial de "+dato1+": " +obj1.factorial());
System.out.println("Factorial de "+dato2+": " +obj1.factorial1());
System.out.println("Modulo: " + dato1 + " $ " + dato2 +" = "+obj1.modulo());
}
public static int leer () throws IOException
{
InputStreamReader entrada =new InputStreamReader(System.in);
BufferedReader lectura= new BufferedReader(entrada);
String cadena=lectura.readLine();
return (Integer.parseInt(cadena));
}
}

Resultado de pantalla
digite primer numero

5
digite segundo numero
3

Suma: 5 + 3 = 8
Resta: 5 - 3 = 2
Multiplicacion: 5 * 3 = 15
Factorial de 5: 120
Factorial de 3: 6
Modulo: 5 % 3 = 2

Taller Pares ordenados

Problema propuesto
Realizar un Programa Orientado a Objetos que solicite 10 numeros e imprima la lista de los numeros pares ordenados.

Solucion Propuesta

Diagrama de casos de uso:




Diagrama de clases



Codigo Fuente

Paquete presentacion
Clase formulario



package presentacion;

import logica.*;
import java.io.*;

public class Formulario {
public static void main(String arg[]) throws IOException
{
int vector [ ] = new int [10];
int vectorpar [ ] = new int [10];

int i;
for (i = 0; i <= 9; i++)
{
vector [i] = leer ();
}
servicio objeto = new servicio();
vectorpar = objeto.ordenarPar(vector);
System.out.println("Numeros ordenados");
for (i=0; i<vectorpar.length; i++)//<=9; i++)
{
System.out.println("numero: " + vectorpar [i]);
}
}
public static int leer()throws IOException
{
System.out.println ("Digite numero");
InputStreamReader entrada=new InputStreamReader (System.in);//entrada flujo de entrada de informacion
BufferedReader lectura=new BufferedReader (entrada);//lectura separa memoria para entrada
String cadena=lectura.readLine();//cadena ingresa la informacion en una cadena string
return(Integer.parseInt(cadena));//parseint convierte la cadena en un entero
}
}

Paquete logica

Clase servicio


package logica;


public class servicio {
private int dato;
public int getDato() {
return dato;
}

public void setDato(int dato) {
this.dato = dato;
}
public servicio ()//constructor inicializa la variable
{
this.dato=0;
}
public int[] ordenarPar(int vector[ ])
{
int vectorpar [ ] = new int [10];
for (int i = 0; i <= 9; i++)
{
int a = vector [i];
if (esPar(a) )
vectorpar [i] = a;
}
for (int i=0; i<vectorpar.length; i++)
{
for (int j=vectorpar.length-1; j>0; j--)
{

if (vectorpar [j]<vectorpar [j-1])
{
int temp = vectorpar [j];
vectorpar [j] = vectorpar [j-1];
vectorpar [j-1] = temp;
}
}
}
return (vectorpar);
}
static boolean esPar(int numero)
{
if (numero%2==0)
return true;
else
return false;
}
}

Applets en Java

APPLETS EN JAVA


A continuación se dara una breve explicación de los applets en java:
Los applets (miniaplicación) son programas escritos en Java que sirven para "dar vida" a las páginas Web (interacción en tiempo real, inclusión de animaciones, sonidos...), de ahí su potencia.

Los applets son programas que se incluyen en las páginas Web. Las applets son ejecutadas en la máquina cliente, con lo que no existen ralentizaciones por la saturación del ancho de banda. Permiten cargar a través de la red una aplicación portable que se ejecuta en el navegador. Para que esto ocurra tan sólo hace falta que el navegador sea capaz de interpretar Java.

Los applets no son exactamente aplicaciones Java, ya que presentan las siguientes diferencias respecto a las aplicaciones normales Java:

• Se cargan mediante un navegador, no siendo lanzados por el intérprete Java.

• Son cargados a través de la red por medio de páginas HTML y no residen en el disco duro de la máquina que los ejecuta.

• Poseen un ciclo de vida diferente; mientras que una aplicación se lanza una vez, una applet se arranca (inicia) cada vez que el usuario recarga la página en la que se encuentra la applet.

• Tienen menos derechos que una aplicación clásica, por razones de seguridad. De modo predeterminado en el puesto que los ejecuta no pueden ni leer ni escribir ficheros, ni lanzar programas, ni cargar DLLs. Sólo pueden comunicarse con el servidor Web en que se encuentra la página Web que las contiene.

LA CLASE APPLET


La clase Applet Java, de la cual han de heredar todos los programas Java que vayan a actuar como applets, es la única clase que contiene el paquete java.applet de la API de Java.
Esta clase hereda de Object (como todas las clases Java), pero además hereda de Component y Container, que son dos clases del paquete gráfico AWT. Esto ya perfila las posibilidades gráficas de este tipo de aplicaciones Java.

Métodos del ciclo de vida

Un applet no tiene un ciclo de vida tan "sencillo" como el de una aplicación, que simplemente se ejecuta hasta que finaliza su método main().

La siguiente figura modeliza el ciclo de vida de una applet:





Cada círculo representa una fase en el ciclo de vida de la applet. Las flechas representan transiciones y el texto representa la acción que causa la transición. Cada fase está marcada con una invocación a un método de la applet:

void init(); Es invocado cuando se carga la applet. Aquí se suelen introducir las iniciaciones que la applet necesite.

void start(); Es invocado cuando la applet, después de haber sido cargada, ha sido parada (cambio de página Web, minimización del navegador,...), y de nuevo activada (vuelta a la página, restauración del navegador,...). Se informa a la applet de que tiene que empezar su funcionamiento.

void stop(); Es invocado para informar a la applet de que debe de parar su ejecución. Así una applet que utilice threads, debería detenerlos en el código de este método.

void destroy(); Es invocado para informar a la applet de que su espacio está siendo solicitado por el sistema, es decir el usuario abandona el navegador. La applet debe de aprovechar este momento para liberar o destruir los recursos que está utilizando.

void paint(); Es invocado cada vez que hay que el navegador redibuja la applet.

Al crear una applet no es necesario implementar todos estos métodos. De hecho habrá applets que no los necesiten.
Cuando un navegador carga una página Web que contiene una applet, suele mostrar en su parte inferior un mensaje como:

initializing... starting...

Esto indica que la applet, se está cargando, luego:
1. Una instancia de la clase applet es creada.
2. La applet es iniciada, mediante su método init().
3. La applet empieza a ejecutarse, mediante su método start().

Cuando el usuario se encuentra con una página Web, que contiene una applet y salta a otra página, entonces la applet se detiene invocando a su método stop(). Si el usuario retorna a la página donde reside la applet, ésta vuelve a ejecutarse nuevamente invocando a su método start().
Cuando el usuario sale del navegador la applet tiene un tiempo para finalizar su ejecución y hacer una limpieza final, mediante el método destroy().

Inclusión de la applet en una página Web

Para incluir una applet en una página Web, una vez compilada la applet, debe incluirse entre el código HTML de la página Web una etiqueta <APPLET>, que como mínimo ha de presentar los siguientes tres parámetros:
code: Especifica el URL del fichero de clase Java (*.class) que contiene la applet.
width: Especifica la anchura inicial de la applet (en pixels).
heigth: Especifica la altura inicial de la applet (en pixels).

Además, de la etiqueta inicial, una applet puede tener parámetros que se especificarán mediante etiquetas <PARAM>, que como mínimo han de presentar dos parámetros:
name: Indica el nombre del parámetro de la applet al que esta etiqueta hace referencia.
value: Establece este valor al parámetro indicado en name de la misma etiqueta.

Así un ejemplo de esto sería:

<applet code="AppletDiagonal.class" width=200 height=200>
<param name=Parametro1 value=Valor1>
<param name=Parametro2 value=Valor2>
</applet>

En este ejemplo la applet puede entender los parámetro Parametro1 y Parametro2, mediante los métodos que se describen en el siguiente apartado, y obtendría Valor1 y Valor2 respectivamente.

Se observa que además de la etiqueta <applet> en el código HTML también aparece una etiqueta </applet>. Esto sucede porque HTML es un lenguaje etiquetado, en el que casi todas las etiquetas de inicio de elemento (<etiq>) tienen una etiqueta de fin (</etiq>).

EJEMPLO DE UN APPLET

A continuación se mostrara un sencillo ejemplo de un applet:
Código

Para crear una applet normalmente será necesario importar al menos las bibliotecas java.awt.* y la java.applet.*.

La clase que represente a la applet se ha de declarar como una subclase de la clase Applet, para poder sobreescribir los métodos de la clase Applet.
Siempre conviene sobreescribir al menos el método paint() que será llamado por los navegadores que soporten applets para mostrarles por pantalla.
Vamos a construir una applet denominada AppletDiagonal que simplemente dibuje una línea diagonal. Un ejemplo de código para este applet sería:

import java.awt.*;
import java.applet.*;

public class AppletDiagonal extends Applet {

public void paint(Graphics g)
{
g.setColor( Color.red );
g.drawLine(0, 0, getWidth(), getHeight() );
}
}

Pasemos a comentar el funcionamiento de este código:

1. El método paint() recibe un objeto de la clase Graphics. La clase Graphics, incluida en el AWT, contiene métodos para mostrar varios tipos de gráficos.

2. Mediante el método setColor() de la clase Graphics se establece el color de primer plano a rojo, que es uno de los colores predefinidos de la clase Color.

3. Por último, mediante drawLine() se dibuja una línea dadas las coordenadas de su esquina superior izquierda y de la inferior derecha. En este caso se indican la esquina superior izquierda de la applet mediante las coordenadas (0,0), y la esquina inferior derecha se obtiene mediante dos métodos de la clase Dimension ( getWidth(), getHeight() ).

Ejecución

Para ejecutar la applet, una vez compilado el fichero, se introduce la llamada a la applet en una página Web (por ejemplo AppletDiagonal.htm), introduciendo entre su código HTML lo siguiente:

<applet code="AppletDiagonal.class" width=200 height=200>

</applet>

martes, 17 de agosto de 2010

Clase 12 de Agosto de 2010

Desarrollo Clase:

Ejercicio.
Decripción: crear un POO que solicite 2 valores, identifique y muestre si son Primo Relativos.

Desarrollo:
Teoria:
PRIMOS RELATIVOS

Dos números naturales se llaman primos relativos si el máximo común divisor entre ellos es 1.
Los números 6 y 9 NO son primos relativos ya que los divisores de 6 son 1, 2, 3 y 6. Los divisores de 9 son 1, 3 y 9. Por lo tanto el máximo común divisor es 3.
Los números 9 y 14 son primos relativos ya que los divisores de 9 son 1, 3 y 9, mientras que los divisores de 14 son 1, 2, 7 y 14. Por lo tanto el máximo común divisor es 1.

Paquete Logica.

package logica;


public class primorelativo {
private int dato;
public int getDato()
{
return dato;
}

public void setDato(int dato)
{
this.dato = dato;
}

public primorelativo()
{
dato=0;
}
public primorelativo(int dato)
{
this.dato=dato;
}

public boolean verificarPrimoRelativo(int dato2)
{
int divisor=2; boolean resultado=true;
while((divisor<=dato/2)
(divisor<=dato2/2))
{
if(((dato %divisor)==0)&&((dato2%divisor)==0))
return (resultado=false);
divisor++;
}
return(resultado);
}
}

Paquete Presentación
package presentacion;


import logica.*;
import java.io.*;

public class formulario {

public static void main(String arg[]) throws IOException

{
int dato=leer();
primorelativo obj1, obj2;
obj1=new primorelativo(dato);
dato=leer();
obj2=new primorelativo(dato);
if(obj1.verificarPrimoRelativo(obj2.getDato()))
System.out.println ("Son primo relativo");
else
System.out.println ("No son primo relativo");
}
public static int leer()throws IOException
{
System.out.println ("Digite numero");
InputStreamReader entrada=new InputStreamReader (System.in);//entrada flujo de entrada de informacion
BufferedReader lectura=new BufferedReader (entrada);//lectura separa memoria para entrada
String cadena=lectura.readLine();//cadena ingresa la informacion en una cadena string
return(Integer.parseInt(cadena));//parseint convierte la cadena en un entero
}
}
 
UML
 
 

Conceptos Iniciales Programación Orientada a Objetos

Objeto: El objeto va a ser la modelización de los objetos que nos encontramos en el mundo real, estos objetos los vamos a utilizar en nuestros programas para dar la solución al problema que nos ocupe en cada caso. Un objeto es la pieza básica de la POO, es una representación o modelización de un objeto real perteneciente a nuestro mundo, por ejemplo, podemos tener un objeto perro que represente a un perro dentro de nuestra realidad, o bien un objeto factura, cliente o pedido. (Programación en Java - Ángel Esteban).

Clases: Una clase es un molde o prototipo que define un tipo de objeto determinado. Una clase define los atributos y métodos que va a poseer un objeto. Mediante las clases podremos crear o instanciar objetos de un mismo tipo, estos objetos se distinguirán unos de otros a través de su estado, es decir, el valor de sus atributos.
La clase la vamos a utilizar para definir la estructura de un objeto, es decir, estado (atributos) y
comportamiento (métodos). La clase es un concepto abstracto que generalmente no se va a utilizar directamente en nuestros programas o aplicaciones. Lo que vamos a utilizar van a ser objetos concretos que son instancias de una clase determinada.
La clase es algo genérico y abstracto, es similar a una idea. Cuando decimos piensa en un coche todos tenemos en mente la idea general de un coche, con puertas, ruedas, un volante, etc., sin embargo cuando decimos "ese coche que está aparcado ahí fuera", ya se trata de un coche determinado, con una matrícula, de un color, con un determinado número de puertas, y que podemos tocar y utilizar si es necesario. Sin embargo como ya hemos dicho la clase es la idea que define al objeto concreto. (Programación en Java - Ángel Esteban).

Herencia: La herencia es un mecanismo mediante el cual podemos reutilizar clases ya definidas. La herencia dentro de la POO es un mecanismo fundamental que se puede definir también como una transmisión de las características de padres a hijos.
Entendiendo aquí características como métodos y atributos de una clase. La clase hija puede añadir atributos, métodos y redefinir los métodos de la clase padre.
Podemos ver la herencia como una sucesiva especialización de las clases. La clase de la que se hereda se suele denominar clase padre o superclase, y la clase que hereda se denomina clase hija o subclase.(Programación en Java - Ángel Esteban).

Paso de Mensajes: Una aplicación orientada a objetos consiste en un número determinado de objetos que interactúan entre si enviándose mensajes unos a otros para invocar sus métodos. Este intercambio de mensajes facilita su comportamiento, cambios de estado, destrucción o almacenamiento. Ya que todo lo que un objeto puede realizar está expresado en sus métodos, este simple mecanismo de mensajes soporta todas las posibles interacciones entre ellos. Mediante el denominado paso de mensajes, un objeto puede solicitar de otro objeto que realice una acción determinada o que modifique su estado. El paso de mensajes se suele implementar como llamadas a los métodos de otros objetos. Desde el punto de vista de la programación estructurada, esto correspondería con la llamada a funciones. (http://www.adrformacion.com/cursos/java/leccion1/tutorial5.html).

Los atributos: Los datos se encapsulan dentro de una clase declarando variables dentro de las llaves de apertura y cierre de la declaración de la clase, variables que se conocen como atributos. Se declaran igual que las variables locales de un método en concreto.
Los atributos se pueden declarar con dos clases de tipos: un tipo simple Java (ya descritos), o el nombre de una clase. (http://zarza.usal.es/~fgarcia/doc/tuto2/II_5.htm).

Los Métodos: son las acciones que se pueden realizar con los objetos. También se podría definir un método como la implementación de un mensaje, al fin y al cabo, un mensaje es la llamada o invocación de un método de un objeto.
Existen dos métodos especiales dentro de la POO que se denominan constructor y destructor.
El método constructor se ejecuta automáticamente cada vez que se crea un objeto de la clase en cuestión, sobre el objeto que acaba de crearse, inmediatamente después de haberse asignado memoria a dicho objeto.
El método destructor se invoca automáticamente inmediatamente antes de liberar la memoria del objeto en cuestión, o lo que es lo mismo, antes de que se salga del ámbito de la declaración del objeto, por lo que se ha de emplear para que la destrucción del objeto se efectúe correctamente y contendrá operaciones tales como liberación de memoria asignada dinámicamente dependiente del objeto, grabación de todos o parte de los atributos del objeto en un fichero o base de datos y operaciones similares.(Programación en Java - Ángel Esteban).

Polimorfismo: Expresa la posibilidad de que el mismo mensaje, enviado a objetos distintos, ejecute métodos distintos. Esto significa que podemos definir dentro de dos clases distintas dos operaciones con el mismo nombre y aspecto externo, pero con distintas implementaciones para cada clase.
En el momento de emplear estas operaciones, el lenguaje es capaz de ejecutar el código correspondiente dependiendo de la clase del objeto sobre el que se ejecuta la operación. Esto permite definir un interfaz común, un aspecto externo idéntico, para una serie de clases.(Programación en Java - Ángel Esteban).

UML: UML es un conjunto de herramientas, que permite modelar (analizar y diseñar) sistemas orientados a objetos.
Veamos qué herramientas contiene:
- Diagrama de casos de uso
- Diagrama de clases
- Diagrama de estados
- Diagrama de secuencias
- Diagrama de actividades
- Diagrama de colaboraciones
- Diagrama de componentes
- Diagrama de distribución.
(http://www.ingenierosoftware.com/analisisydiseno/uml.php).

Tipos de datos: permiten dimensionar un dato en memoria. Hay dos tipos de dato en Java: simples y compuestos. Los simples son los numéricos, los booleanos y los caracteres. Dichos tipos son manejados directamente por el compilador, y no necesitan de bibliotecas Java específicas. Los compuestos son las tablas, las cadenas de caracteres y los nombres de clases o interfaces. Su uso puede necesitar clases específicas de la biblioteca de java. (ENI, Ediciones. JAVA 2 Manual Práctico. P 40).

La programación Orientada a objetos (POO):  Es una forma especial de programar, más cercana a como expresaríamos las cosas en la vida real que otros tipos de programación.

Con la POO tenemos que aprender a pensar las cosas de una manera distinta, para escribir nuestros programas en términos de objetos, propiedades, métodos y otras cosas que veremos rápidamente para aclarar conceptos y dar una pequeña base que permita soltarnos un poco con este tipo de programación. (http://www.desarrolloweb.com/articulos/499.php)

Paradigma de programación: Es una colección de modelos conceptuales que juntos modelan el proceso de diseño y determinan, al final, la estructura de un programa.
Cuando un lenguaje refleja bien un paradigma particular, se dice que soporta el paradigma, y en la práctica un lenguaje que soporta correctamente un paradigma, es difícil distinguirlo del propio paradigma, por lo que se identifica con él.


Tipos de paradigmas:
Robert Floyd describió tres categorías de paradigmas de programación:

a) Los que soportan técnicas de programación de bajo nivel (ej.: copia de ficheros frente estructuras de datos compartidos)

b) Los que soportan métodos de diseño de algoritmos (ej.: divide y vencerás, programación dinámica, etc.)

c) Los que soportan soluciones de programación de alto nivel, como los descritos en el punto anterior

Floyd también señala lo diferentes que resultan los lenguajes de programación que soportan cada una de estas categorías de paradigmas. Sólo comentaremos los paradigmas relacionados con la programación de alto nivel.

Se agrupan en tres categorías de acuerdo con la solución que aportan para resolver el problema

a) Solución procedimental u operacional. Describe etapa a etapa el modo de construir la solución. Es decir señala la forma de obtener la solución.

b) Solución demostrativa. Es una variante de la procedimental. Especifica la solución describiendo ejemplos y permitiendo que el sistema generalice la solución de estos ejemplos para otros casos. Aunque es fundamentalmente procedimental, el hecho de producir resultados muy diferentes a ésta, hace que sea tratada como una categoría separada.

c) Solución declarativa. Señala las características que debe tener la solución, sin describir cómo procesarla. Es decir señala qué se desea obtener pero no cómo obtenerlo. (http://www.wikilearning.com/curso_gratis/metodologias_usadas_en_ingenieria_del_software-paradigmas_de_programacion_y_sus_tipos/3618-3)

Cohesión: se puede definir como la medida de la fuerza o relación funcional de los elementos de un módulo, entendiendo por elementos a la sentencia o grupo de sentencias que lo componen, a las definiciones de datos o a las llamadas a otros módulos. Los niveles de cohesión con un comportamiento aceptable (de mejor a peor) son los siguientes:


- Cohesión funcional.
- Cohesión secuencial.
- Cohesión comunicacional.
- Cohesión lógica.
- Cohesión coincidental.
(Rodríguez Sala, Jesús. Introducción a la programación. P 44-45).

Acoplamiento: se refiere a el grado en que una clase conoce datos acerca de los miembros de otra clase.

Un bajo acomplamieto es deseable, puesto que las otras clases solo deben de saber cosas que realmente le interezan y los datos deben estar encapsulados.
(http://javacertificationtips.blogspot.com/2008/11/acoplamiento-y-cohecion.html)

Encapsulamiento: El encapsulamiento consiste en unir en la Clase las características y comportamientos, esto es, las variables y métodos. Es tener todo esto es una sola entidad. En los lenguajes estructurados esto era imposible. Es evidente que el encapsulamiento se logra gracias a la abstracción y el ocultamiento que veremos a continuación.
La utilidad del encapsulamiento va por la facilidad para manejar la complejidad, ya que tendremos a las Clases como cajas negras donde sólo se conoce el comportamiento pero no los detalles internos, y esto es conveniente porque nos interesará será conocer qué hace la Clase pero no será necesario saber cómo lo hace.

Los lenguajes de programación: Son herramientas que nos permiten crear programas y software. Entre ellos tenemos Delphi, Visual Basic, Pascal, Java, etc.. Una computadora funciona bajo control de un programa el cual debe estar almacenado en la unidad de memoria; tales como el disco duro. Los lenguajes de programación de una computadora en particular se conoce como código de máquinas o lenguaje de máquinas. Estos lenguajes codificados en una computadora específica no podrán ser ejecutados en otra computadora diferente. (http://www.lenguajes-de-programacion.com/lenguajes-de-programacion.shtml)

Archivo Fuente: Texto escrito en un lenguaje de programación específico y que puede ser leído por un programador. Debe traducirse a lenguaje máquina para que pueda ser ejecutado por la computadora o a bytecode para que pueda ser ejecutado por un intérprete. Este proceso se denomina compilación. Acceder al código fuente de un programa significa acceder a los algoritmos desarrollados por sus creadores. Es la única manera de modificar eficaz y eficientemente un programa. (http://www.alegsa.com.ar/Dic/codigo%20fuente.php)