PRÁCTICA 10

•18 Mayo, 2008 • 2 comentarios

Esta práctica nos ha parecido un poco extraña, ya que en un principio no sabíamos de que iban los Threads o hilos de ejecución ni tampoco estábamos muy seguros en que se diferenciaban los programas de los procesos…un lío. Menos mal que con la explicación del profe más o menos nos quedó claro.

Ejercicio 1:

Un programa necesita procesos para funcionar (por lo tanto siempre habrá mas procesos que programas). En sí son lo mismo, lo único que los procesos son el código que estamos ejecutando, por lo tanto es más incomprensible, por eso se crean los programas (que hacen que cualquier persona lo pueda entender).

Al principio nos dan el código de un programa llamado Ding. Es un programa sencillo que lo único que hace es esperar a que metas algo por teclado y cuando esto ocurra si es un enter te imprime DING! y si es cualquier otra letra no hace nada.

El apartado 2 es muy parecido al anterior pero en vez de imprimirtelo cada vez que das al enter, lo hace cada 1000 ms (1s), además esta vez se imprime DONG!. Para hacer que lo haga cada segundo se usa la sentencia :

Thread.sleep(1000); //siempre va en ms

En el tercer apartado te juntan los dos anteriores, es decir que imprima DING! cada vez que das al enter y DONG! cada segundo. Este programa funciona mal, puesto que el System.in.read() bloquea el equipo hasta que se introduce el enter por teclado, por lo tanto el DONG! no sale hasta que lo introduces (en vez de salir cada segundo que es como debería). Además nos hemos dado cuenta de que hace otra cosa que no nos concuerda, ya que cuando de las a enter debería salir DING! DONG!, sale DONG! DING! DONG!, como si cada vez que le dieras al enter hubiera antes otra cosa y al hacer el if no lo cumple…no entendemos muy bien porque ocurre.

Ejercicio 2:

Un hilo de ejecución( o thread ) es una característica que permite a una aplicación realizar varias tareas ( independientes) simultáneamente. Los distintos hilos de ejecución comparten recursos como el espacio de memoria, los archivos abiertos etc. Esta técnica permite simplificar el diseño de una aplicación que debe llevar a cabo distintas funciones simultáneamente. Cada vez que se lanza un thread se hace una nueva bifurcación en el programa para hacer lo que te van poniendo en el método run().

El proceso sigue en ejecución mientras al menos uno de sus hilos de ejecución siga activo. Cuando el proceso es terminado, todos sus hilos de ejecución también lo son. Además si mato a la raíz ( desde la que he lanzado los thread), mato a todos los otros hilos aunque estos no hayan acabado aún de hacer todo su código.

El apartado 1 tiene varias cosas que nos extrañaron,por lo que investigamos un poco:

Runnable r = new Runnable() {
public void run() {
PrintThreadName();
}
};

  • Se trata de una clase interna: que solo se puede usar en la clase en la que esta integrada. Todo esto se podría haber hecho en otra clase, pero como solo lo vamos a usar aqui, no hace falta.
  • Runnable es una interfaz y r es un objeto que implementa a esa interfaz.
  • Siempre que implementemos la interfaz Runnable tenemos que implementar su único método que es el run(). Dentro del run ponemos lo que queremos que haga el nuevo hilo que vamos a lanzar.

Thread t = new Thread(r);
t.start();

  • Al crear un nuevo Thread le paso por parámetro el objeto de Runnable.
  • El método start() lo único que hace es lanzar el hilo nuevo (hacer la bifurcación), va al método run() para ver que tiene que hacer, y lo ejecuta. Al método start no se le pasa nada por parámetro.

Los demás hacen lo mismo. Lo único que cambia es que una hereda de Thread y la otra implementa a Runnable. Esto es lo mismo, ya que si nos vamos al api nos encontramos con que la clase Thread ya implementa a Runnable por lo que al heredarla ya lo tenemos.

Ejercicio 3:

En este ejercicio se tratan las condiciones de carrera que se producen cuando dos hilos intentan acceder en el mismo momento al mismo recurso.

Miramos el código que nos daban ( clase RaceCondition) y nada mas verla piensas que van a salir los 10000 ceros y luego los 10000 unos ( pues así es el orden en el que está escrito), pero al compilarlo se ve que salen aleatoriamente ( según cual es el primero que llega)

No se nos ocurrieron muchas formas de solucionar este problema, si acaso alguna puede ser que cuando uno vaya a acceder a un recurso antes compruebe si hay otro accediendo a la vez…

El programa RaceConditionSolved esta evitando que dos hilos accedan a salida estándar ( esta solucionando la condición de carrera), para ello usa vectores, miramos un poco el código y lo ejecutamos.

Ya no hemos avanzado mas.Se nota que ya se acercan los exámenes, el día de entregar el juego… así que estamos demasiado liados con todo…

Un saludo

PRÁCTICA 9

•5 Mayo, 2008 • 1 comentario

Ya que le hemos cogido gustillo a esto, pues no vamos a parar, que si no, nos conocemos y estamos una semana y algo sin escribir nada…

Por fin empezamos con el tema de las interfaces gráficas, que la verdad es que nos parece más entretenido,porque ya no lo vamos a ver en la consola todo negro…si no que por fin tenemos ventanitas y cosas, aunque tiene su dificultad..pero bueno como todo.

Ejercicio 1:

En este ejercicio nos dan un programa y lo tenemos que compilar y ejecutar para ver lo que hace.Es un programa sencillito ( más o menos lo habíamos visto todo en la clase de teoría). Lo único que no conocíamos era el método setDefaultCloseOperation con el parámetro EXIT_ON_CLOSE, que lo buscamos en el API y vimos que sirve para que cuando le des al aspa de cerrar, el programa además de cerrarse deje de ejecutarse.

En el programa HelloWorldGUIBig únicamente tenemos que cambiar los parámetros del método setSize(x,y), por ejemplo : frame.setSize(400,200);

El siguiente programa que tenemos que hacer es el HelloWorldGUIColor, con el fondo de la etiqueta de color azul. Para hacerlo, basta con añadir estas dos líneas de código antes de añadir al contentPane la etiqueta:

label.setBackground(Color.RED); // este es el que sirve para cambiar el fondo

label.setOpaque(true); // se usa para poder ver la etiqueta (que no sea transparente).

La clase HelloWorldGUIDelayed hace que la ventana no salga nada más darle a ejecutar, si no que tarde un poco más. Si añades el System.exit(0) lo que hace es que se cierra solo, ni siquiera sale la ventana.

Ejercicio 2:

Para hacer que un programa ignore el mensaje de cierre ( que es lo que piden en la clase HelloWorldGUIDeaf) tenemos que usar otro de los parámetros que se le pueden pasar al método setDefaultCloseOperation quedando:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // que no te hace caso si le das a cerrar

Otra forma para cerrar la ventana es no poner nada, se te cierra aunque no deja de ejecutarse.

Luego te piden el HelloWorldGUIUndecorated que no tenga ninguna decoración del manejador de ventanas. Para ello se usa al final del código,antes de hacerlo visible:

frame.setUndecorated(true) // que no te saca la barra de menú ( ni los botones de minimizar, maximizar y cerrar)

En el último apartado de este ejercicio te dicen que utilices el Look and Feel por defecto de java para hacer la clase HelloWorldGUIDecorated. Nos dan una gran pista en el enunciado, por lo que directamente fuimos al método setDefaultLookAndFeelDecorated():

JFrame.setDefaultLookAndFeelDecorated(true);

que se lo añadimos antes de crear el frame ( antes de la línea : frame = new JFrame (“HelloWorldGUIDecorated”) ) si no, no funciona.

Ejercicio 3:

En este ejercicio ya te piden usar Layouts que es la clase encargada de decidir como se colocan los componentes, un método de Layout muy usado es el pack() que hace que la ventana tenga el tamaño adecuado para que se vea todo lo que tenemos en ella ( ni más grande ni más pequeño) y nos quita de usar el setSize() para decirle el tamaño que queremos.

En el primer apartado de este ejercicio te piden el programa CompassSimple en la que la etiqueta tenga el fondo negro, la letra blanca, y que la ventana salga directamente maximizada al tamaño completo de la ventana.

Después de crear la etiqueta y de decirla que no sea transparente ponemos:

label.setBackground(Color.BLACK); // color de fondo
label.setForeground(Color.WHITE); //color de texto

Lo de que salga directamente maximizada, no sabemos muy bien como hacerlo. Nos pasaremos por algún blog a ver si alguien lo ha hecho.

Luego nos piden que modifiquemos el CompassSimple para que tenga 4 etiquetas cada una de una forma y en un sitio distinto.Tenemos que hacer 4 veces lo siguiente:

label = new JLabel(“North”);
label.setOpaque(true);

label.setBackground(Color.BLACK); // color de fondo
label.setForeground(Color.WHITE); //color de texto
contentPane.add(label, BorderLayout.NORTH);

Pero cada uno siguiendo las indicaciones que nos dan. El siguiente tendriamos que poner SOUTH donde pone NORTH y poner Background(Color.WHITE) y el Foreground(Color.BLACK) y así con todos.

Para hacer el CompassBetter tenemos que añadir en cada una de las etiquetas anteriores antes de añadirlas al ContenPane :

label.setHorizontalAlignment(JLabel.CENTER); //alineación horizontal centrada
label.setVerticalAlignment(JLabel.CENTER); //alineación vertical centrada

En todas es igual, ya que nos dicen que todas tengan el texto centrado. Además tenemos que poner que todas tengan el fondo negro y el texto blanco.

En el siguiente apartado nos piden que ya incorporemos una imagen , es el CompassMuchBetter. Para hacer esto, tenemos que añadir al código lo siguiente:

ImageIcon flecha = new ImageIcon(“./flecha.jpg”); //creo el icono pasándole como parámetro la URL de la imagen
label = new JLabel(flecha); //creo la etiqueta metiéndole como parámetro la anterior ImageIcon
label.setOpaque(true);
label.setBackground(Color.BLACK);
label.setVerticalAlignment(JLabel.CENTER);
label.setHorizontalAlignment(JLabel.CENTER);
contentPane.add(label, BorderLayout.CENTER);

En CompassMuchBetterSmall lo único que hay que hacer es sustituir el setSize() por el pack() que es el que hemos explicado antes.Vamos, que sería poner : frame.pack();

El último apartado de este ejercicio te pide que hagas un método llamado centerAndShowFrame(JFrame frame, double xScale, double yScale)que centre la ventana en la pantalla, la ponga con los valores mínimos necesarios en función de los parámetros xScale e yScale y la haga visible.El programa en el que está este método es el CompassMuchBetterCentered. Este apartado no lo hemos conseguido hacer…lo hemos estado intentando, pero no nos sale, asi que si alguien nos ayuda…

Ejercicio 4:

El apartado 1 aún no hemos conseguido hacerlo, aunque tenemos alguna ligera idea de como hacerlo, pero no sabemos como unirlo todo.

  • Sabemos que tiene que haber un método que me compruebe si es par o impar, un simple si el resto de dividir el entero entre 2 es 0 es par si no, es impar (para que te lo coloree blanco o negro)
  • Además hay que hacer un for que te vaya poniendo los números 1,2… y que dentro de él nos compruebe si ese número es par o impar y así te vaya poniendo el color de fondo y el color de texto de una forma u otra.

Creemos que es eso lo que tenemos que hacer, pero nos da 1 error al compilar, cuando lo resolvamos ( que pensamos hacerlo) lo colgamos.

El apartado 2 nos ha dado bastante miedo, porque lo hemos visto muy largo, y lo hemos dejado…de todas formas al igual que el anterior, lo colgaremos cuando lo hagamos.

Hasta la próxima!!

PRÁCTICA 8

•4 Mayo, 2008 • Dejar un comentario

Aquí estamos de nuevo…

Ejercicio 1:

En este apartado nos pedían implementar mediante una tabla hash una lista de trucos como en los videojuegos en los que a través de una clave podamos acceder a ellos.

La tabla hash se basa en que a cada elemento que vas insertando en la tabla se le puede asociar una clave, para que luego, mediante la utilización de esta clave vamos a poder acceder al elemento que tiene esa clave y así que sea más rápido ( recordemos que con las clases Stack y Vector para encontrar un elemento hay que recorrer todos los elementos, cosa que es mucho más lenta).

Para ellos están los métodos :

1. put(clave,objeto): Inserta en la tabla el objeto que se le pasa por parámetro asociado a la clave.
2. get(clave): Devuelve el objeto asociado a esa clave.

Para usar esta clase tenemos que hacer: import java.util.Hashtable;

El código es muy sencillo y basta con hacer en el main:

Hashtable trucos = new Hashtable(); // creamos una tabla llamada trucos

trucos.put(“Truco1″,”Nuevo personaje”); // metemos en la tabla el truco Nuevo personaje asociado a la //clave Truco1

String truco1 = (String)trucos.get(“Truco1″); // recuperamos el truco1, para ello tenemos que hacer un //casting a String, ya que el método get nos devuelve objetos de tipo Object ( como todas las clases //hechas en java: Stack, Vector…)

System.out.println(truco1); // lo imprimimos

y esto lo puedes hacer tantas veces como trucos quieras introducir

Ejercicio 2:

Este ejercicio se basa en analizar unos programas hechos con recursividad.

Nos han parecido bastante sencillo, por lo que no creemos necesario decir por aquí lo que hace cada uno, si alguien tiene algún problema que nos lo diga y lo intentamos resolver.

Ejercicio 3:

Este es en el que hay más dificultad. Tenemos que determinar como si fuera el juego del tetris si hay linea usando recursividad.

No hemos podido hacerlo, pero vamos a intentarlo en estos días, esperamos que para la semana que viene ya lo tengamos y lo colgaremos.

PRÁCTICA 7

•4 Mayo, 2008 • Dejar un comentario

En esta práctica tenemos que crear una cola (como la de la práctica anterior) pero que sea dinámica. Por eso de que no haya máximo a la hora de encolar, y también porque si solo utilizamos 3 objetos es tontería tener una cola de 10.000 objetos.

Se trata de hacerla, pero sin utlizar cosas avanzadas, es decir, imaginar que somos los primeros en hacer una cola dinámica. En un principio pensamos en usar la clase Vector, pero nos dijeron que no teníamos que usar nada que ya estuviera hecho, así que al final recurriendo a las clases de teoría nos acercamos a la idea de crear Nodos.

Los nodos son clases muy sencillas que básicamente tienen 2 atributos: Pieza pieza y Nodo sig_pieza. Pieza tiene la propia pieza, sig_pieza tiene una referencia a la siguiente pieza (si hay, si no hay que apunte a null). Además tiene el constructor normal y los métodos pon() y dame() de cada uno de ellos.

Además tenemos otra clase Lista que tiene también dos atributos: Primero ( que nos va a apuntar al primer elemento que metamos, ya que recordemos que queremos crear una ) y Recorrido ( que va a ir apuntando al siguiente elemento que vayamos insertando); los dos van a ser de tipo Nodo. En esta clase están los métodos:

  • El constructor que inicializa los dos atributos a null
  • vacía() que devuelve un boolean que dice si primero == null
  • llena() no estará debido a que al ser una cola dinámica nunca nos vamos a tener que preocupar de si está llena o no.
  • encolar ( Pieza p):

public void encolar(Pieza p) {
Nodo nodo = new Nodo(p,null);
// crea un nuevo nodo poniendo como Pieza la q le metes y que el atributo sig_pieza apunte a null
if (primero == null) {
primero = nodo;
// si todavía no hay ninguna pieza que el atributo primero apunte a este nodo ( a partir de aquí este siempre será el primero, a no ser que lo saquemos que entonces será el siguiente…)
}
else {

ultimo.ponSig_Pieza(nodo); // si no, llamo a ponSig_Pieza de la clase nodo y le digo que sig_pieza sea ahora el nodo que acabo de crear
}
recorrido = nodo; // y digo que el atributo recorrido me apunte a nodo ( que es el ultimo nodo que he metido)
}

  • desencolar(): que si está vacía diremos que no se puede, y si no, sacaremos el primer elemento que haya y por lo tanto, tenemos que decir que el atributo primero apunte al siguiente que había de primero…este método no nos ha llegado a salir del todo, creemos que sabemos lo que tenemos que hacer, pero el código en sí nos resulta un poco lioso…si alguien puede ayudar…nosotros lo seguiremos intentando, o si no esperaremos a que cuelgen las soluciones y a ver si así ya lo vemos claro.

No hemos puesto ningún método más aunque pensamos que lo mismo para hacer el de desencolar necesitamos otro método que nos haga lo de que el segundo elemento que teníamos ( es decir, el nodo al que apunta el atributo sig_pieza del primer nodo) sea ahora el primero…

Bueno y esto es todo, si conseguimos hacer el desencolar lo pondremos aqui por si ayuda a alguien.

Un saludo.

PRÁCTICA 6

•27 Abril, 2008 • Dejar un comentario

Empezamos con las prácticas que tienen que ver con la algoritmia ( prometemos que para después del puente de Mayo ya estará todo al día).

En esta práctica nos asustamos un poco, por eso de que fuera un tetris, porque claro nosotros oímos tetris y se nos viene a la cabeza el juego, y nos agobiamos… ¿vamos a tener que hacer que caigan ? ¿ y que al darle se muevan?pero no (y menos mal!) “simplemente” teníamos que crear piezas del tetris y meterlas en una estructura de datos que en este caso es una cola.

Ejercicio 1:

Para empezar teníamos unas cuantas dudas…usábamos 1 índice o 2? como se vería en realidad cuándo está llena la cola si usamos 2 índices?… esta última pregunta no la conseguiamos resolver, porque cada vez que pensamos una cosa, por ejemplo : si los dos son iguales… nos surgía algún pero : si son iguales pero apuntan al 0 ( que es como lo pensábamos inicializar en el constructor, ya que así el índice primero no se movía) no está llena, si no que está vacía… total que dijimos mira, pues con 1 índice que es menos complicado ( y el tiempo iba pasando y aún no habíamos ni empezado)

Bueno en este apartado lo único que hicimos era un método random() que me rellenara aleatoriamente la cola con char, estos char son los que luego encolábamos y desencolábamos. Los métodos llena, vacía, encolar y desencolar no tienen nada de especial :

  • encolar() : a este método le paso por parámetro un char y lo meto en la posición del índice + 1 ( el índice lo inicializamos a -1)
  • desencolar() : en este no se le pasa nada por parámetro, si no simplemente cada vez que se le llama te devuelve el elemento que se metió primero ( el más viejo). Además cada vez que quitamos un elemento movemos todos los elementos una posición ( después nos dimos cuenta de que si hay muchos elementos, esto no va a ser muy eficiente)
  • llena() : la cola está llena si el índice apunta a la última posición – 1 ( siempre hay que tener en cuenta que la primera posición del array es la 0)
  • vacía() : el índice apunta a la posición -1

Ejercicio 2 :

En este apartado teníamos que coger el código anterior y cambiar el objeto de tipo char por un objeto de la clase Pieza.

Para ello tenemos que hacer una clase Pieza, en la que están los métodos:

  • mover() : en la que se pasa por parámetro la posición x e y a la que quieras que la pieza vaya.

public void mover(int x, int y){

this.x = x;
this.y = y;

}

  • quienSoy() : en el que se le asigna al nombre que le he pasado en el constructor, un char :

public char quienSoy(){

if (nombre == “L” )
tipo = ‘L’;
else if (nombre == “cuadrado”)
tipo = ‘C’;
else if (nombre == “T”)
tipo = ‘T’;
else if (nombre == “palo”)
tipo = ‘I’;
else
System.out.println(“Error, mete un valor de pieza valido : L, cuadrado, T o palo”);

return tipo;
}

  • toString() : en el que devuelvo un String con el nombre, el tipo y la posición en la que se encuentra la pieza.

La clase Cola tiene como atributo un array de tipo Pieza, además de un índice ( lo podríamos haber hecho con 2, pero nos pareció así mas sencillo).

En el constructor le metemos por parámetro el número de elementos que va a tener nuestro array e inicializamos y creamos el array.

Todos los métodos serán iguales, además hemos añadido un método imprimir () que simplemente sirve para comprobar que la pila está bien implementada.

Nota: Hemos mirado las soluciones y hemos visto que lo han hecho con dos índices, uno apuntando al inicio y otro al final, y no entendemos muy bien lo que hacen.Nuestro problema sobre todo está en el método siguiente(), este método sabemos lo que hace, pero no vemos muy claro como a partir de él podemos saber por ejemplo si está llena o el de encolar… Así que si alguien lo entiende y nos puede ayudar estaríamos muy agradecidos.

JUEGO

•18 Abril, 2008 • 6 comentarios

Mientras avanzamos algo más con la práctica 6, haremos caso a Pablo y hablaremos del juego.

Nosotros estamos haciendo la ruleta de la suerte ( si, el famoso concurso que ahora sale en antena 3), y la verdad es que hemos tenido algunos problemillas pero más o menos los hemos ido sacando.

Básicamente el juego consiste en:

  • Se puede elegir entre un máximo de 3 jugadores.
  • Hay dos opciones de juego : el modo normal ( con una frase que ya esté en un fichero) y el modo ahorcado ( que uno de los jugadores pueda meter la frase y los otros adivinarla).Este último no sabemos si al final sobrevivirá o lo quitaremos.
  • En el modo normal tenemos 4 tipos de paneles : películas, frases célebres, monumentos y ciudad y platos típicos.
  • A cada jugador se le pregunta si quiere : tirar la ruleta, comprar vocal ( solo puede si tiene más de 50 euros) o resolver.
  • Cada vez que se tira la ruleta hay un método random() que hace que salgan las diferentes cifras de dinero por las que puede optar, además de quiebras ( si cae aquí además de que le toca al siguiente jugador, pierde el dinero que llevaba acumulado) y pierde turnos ( simplemente pasa la partida al siguiente)
  • Cada vez que compra vocal se le quitan 50 euros del dinero que tenía. Y si aciertas alguna consonante multiplicas las veces que esa consonante esté en la palabra por el dinero que te había salido al tirar la ruleta.Bueno y claro está que si eliges una consonante o vocal que no está en la frase se pasa el turno al siguiente jugador.
  • Además hay un método que imprime asteriscos y cada vez que aciertas una letra te la va sustituyendo ( quita el asterisco de la posición y pone la letra).

Y eso es todo, por ahora lo tenemos en modo consola, ya que no tenemos mucha idea de usar swing…De todas formas algo hemos hecho mirándo un poco en google, pero sin añadirselo al juego, si no que son pruebas que ya se meteran. Hemos hecho una ruleta que gira, una pantalla en la que el salir ya va ( si, es poco, pero muy gratificante cuando sale :D ) y otra en la que arriba pone bienvenidos, en el centro la ruleta y abajo el comenzar.

Con esto últmo hemos tenido un problema, ya que nos hemos dado cuenta de que si pones varias cosas, el rectángulo te lo divide en partes iguales, y por lo tanto se nos corta la ruleta, si alguien sabe como hacer esto pues nos sería de gran ayuda ( sabemos que todo esto ya lo daremos, pero nos gustaría avanzar algo más, así que no creemos que esté mal preguntar… si no pues seguiremos investigando)

Por ahora nos tomamos un poco de descanso con el juego y haremos más caso al blog.

¿ Y vosotr@s que tal lleváis el juego?

Pd: El martes a las 11:30 hay una manifestación contra el plan Bolonia en el campus de Getafe, lo decimos por si alguien se anima a venir.

Un saludo

PRÁCTICA 5

•17 Abril, 2008 • 1 comentario

Si, ya lo sabemos, vamos por la 7 y aún no hemos comentado ni la 5…hemos estado muy liados con otras prácticas y con el JUEGO, por lo que no teníamos tiempo de seguir con ellas en casa y no nos parecía muy bien poner solo lo que habíamos hecho en clase…pero bueno excusas a parte, empezamos

Primero nos explicaron un poco en que consistía el polimorfismo, y las maneras en las que puede aparecer:

  • Sobrecarga: Que según entendimos consiste en tener métodos con el mismo nombre, pero con distintos tipos de parámetros o número ( si tienen los mismos parámetros sería un poco tonto hacer algo dos veces…).

Por ejemplo: metodoEjemplo(int i ) ; metodoEjemplo ( float i) ; metodoEjemplo ( int a, int i)

  • Sobreescritura: Que se utiliza básicamente para reutilizar código ya existente. Es utilizar en las clases derivadas el mismo método ( nombre,retorno, etc) que tenía en la clase base pero implementando un código diferente dependiendo del comportamiento que quiero para los objetos de las distintas clases. Cualquier método se puede sobreescribir, a no ser que sea final. El ejemplo que a todos se nos viene a la cabeza es el de obtenerArea( ) de las distintas figuras; también está el toString ( ) de la práctica anterior, que si recordáis queríamos que cada vez devolviera distintas cadenas, por lo que cogíamos el toString( ) de Miembro y le añadíamos lo que nos pedían.

También nos hablaron un poco de los métodos y clases abstractas.

  • Un método abstracto es aquel que no tiene implementación ( no tiene el bloque entre las llaves { } ) y son las subclases las que deben añadirle su propia implementación según lo que quieres que haga.
  • Una clase abstracta es simplemente aquella que tiene algún método abstracto

Para declarar un método o una clase abstracta se usa la palabra abstract.

IMPORTANTE: Cuando en una clase derivada no se implementa un método abstracto, debemos poner que esa clase también es abstracta. Además no podemos crear objetos de clases abstractas !!! (mucho cuidado con esto último)

Y para acabar nos explicaron las interfaces. Una Interface es una clase abstracta pura, es decir una clase donde todos los métodos son abstractos (no se implementa ninguno); a estos metódos no hace falta que les pongamos que son abstractos, ya que se sabe que todos lo son.

Para crear una Interface, se utiliza la palabra interface en lugar de class, poniendola como interface estamos obligando a las clases a implementar un complortamiento que yo he definido ( tienen que implementar TODOS los métodos) . También hay que recordar que todos los métodos que declara una interface son siempre public.

Para indicar que una clase implementa los métodos de una interface se utiliza la palabra implements.

IMPORTANTE : Una clase puede implementar a más de una interface ( al contrario que heredar, que solo puede tener una clase base)

Ejercicio 1:

Consiste en sobreescribir los métodos toString( ) que hemos hecho en la anterior práctica y hacerlas llamando a super. Este ejercicio para nosotros fue muy rápido, porque en la anterior entendimos que también había que llamar a super, por lo que ya lo teníamos hecho.

Luego en la clase Clase nos pedían que observaramos que pasaba si poníamos en el toString

str += miembros[i].toString();

El array de miembros tiene como elementos a objetos de tipo método , atributo y constructor, y por lo tanto al llamar al método toString( ) este irá a la clase a la que pertenezca el elemento de la posición desde el que llamo y ese será el método que realice. Es decir, si en miembros [0] hay un objeto de la clase Atributo, realizará el toString que esté hecho en esa clase.

Ejercicio 2:

En este ejercicio nos pedían implementar un método que está en la interface Almacenable, y que ( al ser una interface), el método no tiene implementación y es en la clase Clase donde tengo que hacerlo. Por lo tanto, en la clase Clase nosotros pusimos:

public void guarda(java.io.FileWriter out) {
  try
  {
   out.write(this.toString());
  }
  catch (Exception e) {
   System.out.println(“Error: fichero vacío”);
  }
 }

El write() es un método que está en la clase FileWriter del fichero java.io y que permite guardar el parámetro que se le pasa ( en este caso usamos el write al que se le pasa un String) . El try y catch es debido a que tengo que capturar la excepción, ya que el método que está en Almacenable me la lanza.

Ejercicio 3:

Empezamos con aplicaciones gráficas, y la verdad es que al principio nos asustó bastante, porque no lo habíamos visto nunca ( en clase de teoría aún no lo hemos dado), así que no sabíamos como hacerlo. Pero la verdad es que luego no fue tan tan difícil como pensábamos.

Apartado 3.1:

Teníamos que rellenar el código que faltaba de la clase ComponenteGrafico:

  • El constructor: esto no tenía complicación pues es como siempre. Ejemplo :this.posX = x; 
  • Método paint: sólo tenemos que llamar los métodos pintaFondo y pintaBorde respectivamente.
  • Método pintaFondo: para rellenar este método ya nos tuvimos que meter en el API ( cosa que no nos gusta demasiado…) y buscar y buscar. Después de mucho buscar vimos que estaban los famosos pon y dame ( aunque en inglés, claro) y ya caímos en que para establecer algo necesitamos el setColor ( si queremos poner el nombre a alguien diríamos ponNombre (Juanito), pues esto es lo mismo, aunque no lo parezca y cueste más verlo). Lo de rellenar un rectángulo con ese color nos costó muuuucho más, ya que se necesita tener más nivel de inglés para buscar cosas que no conoces de antes. Al final encontramos el fillRect() al que le tienes que meter (x, y, ancho, alto) y bueno…parece que funcionó.
  • Metodo pintaBorde: para establecer el color de borde ya lo teníamos chupado, pues era igual que el anterior ( con el setColor()) . Y el de dibujar la verdad esque tampoco nos costó mucho, pues al buscar el de rellenar el rectángulo habíamos visto algo que era drawRect(x,y,ancho,alto).

Apartado 3.2:

Aquí ya llegan nuestros problemas.Tenemos dos clases Menú y Boton:

Sabemos hacer el constructor ( igual que antes), pintar el componente gráfico : super.paint(g) –> llamo al de la clase ComponenteGrafico, pues heredan de ella y también sabemos establecer el color de texto,pero :

  • Creamos un String concatenando las opciones del menu separadas por un espacio –> no tenemos ni idea de a que se refiere.
  • Se pinta para que quede más o menos centrado y ajustado al borde izquierdo ( o el de: Dibujamos el texto aproximádamente para que quede centrado ) –> tenemos una ligera idea ( que sería usando : drawString(String str, int x, int y) en el String ponemos lo que quiero que saque, y en los otros algo para que salga centrado…) bueno que no sabemos como hacerlo.

Asi que si alguien es tan amable de ayudarnos estaríamos muy agradecidos.

Aquí nos hemos quedado, como nos quedamos atascados en este apartado no seguimos con los demás, así que no sabemos si sabemos hacerlo o no, pero ya retrasar mas el escribir esta práctica nos parecía pasarse, así que nos apañaremos con esto.

Dentro de muy poco pondremos la 6 que ya está más o menos…

Mientras haber si nos ayudais, y a ver si podemos nosotros también ayudar a alguien.

Un saludo
 

 

PRÁCTICA 4

•18 Marzo, 2008 • 3 comentarios

Y seguimos con las prácticas…

Bueno pues esta práctica va orientada a la herencia,básicamente es hacer lo de la práctica anterior pero con herencia.

Si eres un poco avispado te habrás dado cuenta de que todas las clases hechas en la práctica 3 tienen algunos atributos comunes, por lo que al hacerlas por herencia nos ahorraremos código.

Bueno, empezamos:

Ejercicio 1:

Te dan la clase Miembro que va a ser la clase base, y ya está implementada y todo eso.

Cuestión: ¿Qué pasaría si se cambiara protected por private en nuestra jerarquía de clases?

Lo que pasaría es que luego al ser heredada, no podríamos usar los atributos de esta clase, ya que (recordamos) el modificador de acceso private solo es accesible desde la clase en la que se declara. Siempre podemos arreglar esto poniendo métodos de acceso (los famosos pon() y dame()) y llamarlos desde las clases derivadas ( o si no ponerlo protected, claro)

Ejercicio 2:

Hay que implementar el constructor y el método toString() de la clase Atributo ( usando herencia…) Antes de nada contestamos a la cuestión:

Cuestion: ¿Cual es la palabra reservada de Java que se usa para hacer referencia a la clase base desde una clase derivada?

La palabra reservada es extends, como demostramos en el código:

public class Atributo extends Miembro {

String tipo = null;

public Atributo(String nombre, int modificadores, String tipo ) {
super(nombre, modificadores);
this.tipo=tipo;
}

public String toString() {
String resultado= “Atributo “+super.toString()+ “TIPO = ” +tipo;

return resultado;

// esto último se puede hacer en una línea:

// return “Atributo “+super.toString()+ “TIPO = ” +tipo;}
}

Explicamos un poco el código:

  • En la primera línea estamos diciendo que la clase Atributo hereda de la clase Miembro.
  • En el constructor usamos la palabra reservada super para heredar los parámetros de la clase base que también están en la derivada.
  • En el método toString() usamos también super para heredar dicho método, ya que hay cosas comúnes en los dos toString, y así no hace falta repetir código

Se puede hacer una clase PruebaAtributo para ver como sale, pero eso ya lo dejamos para que lo haga quien quiera…

Ejercicio 2:

La clase Parámetro no hay que implementarla, si no que ya esta hecha, es para que la usemos…

En la clase Método hay que implementar de nuevo el constructor y el toString(). El toString() debe devolver algo como:

METODO NOMBRE = <nombre>, MODIFICADOR = <modificadores> TIPO RETORNO = <tipoRetorno> PARAMETRO(0) TIPO= <tipo> PARAMETRO(1) TIPO= <tipo1>……PARAMETRO(n) TIPO= <tipoN>

En este apartado nos surgieron algunas dudas:

  1. No sabíamos si se podía hacer un return con un bucle dentro ( para sacar el número de Parámetro y el valor de tipo para cada uno de estos)…total que se lo preguntamos al profe y nos dijo que si, el problema es que quedaba muy raro todo ahí metido en el return ( es más no sabíamos muy bien como hacerlo…) así que creamos una variable para luego devolverla en el return, y la verdad es que las cosas se ven muuucho mas sencillas…
  2. ¿ Cómo lo añadimos todo?… porque claro tiene que salir todo seguido…por lo que nos acordamos el famoso a+=b (a = a+b), es decir primero te creas la variable asignándole los valores que no van a cambiar y luego después de recorrer el array, le añades los valores que dependen del array, y así al final en el return ya tienes todo junto…

Total, que nos quedó algo así:

public class Metodo extends Miembro {

String tipoRetorno = null;
Parametro[] parametros = null;

public Metodo(String nombre, int modificadores, String tipoRetorno, Parametro[] parametros) {
super(nombre, modificadores);
this.tipoRetorno=tipoRetorno;
this.parametros=parametros;
}

public String toString() {

String resultado=”"; // String resultado =null;

resultado += “Metodo “+ super.toString()+ ” TIPO RETORNO = “+tipoRetorno;

for(int i=0; i<parametros.length; i++){
resultado=”Parametro(“+i+”)”+parametros[i].toString();}
return resultado;
}

}
En el constructor se hace lo mismo que en la clase Atributo.

Ejercicio 3:Se pide implementar el constructor y el toString() de la clase Constructor.El método toString debe devolver algo parecido a:

CONSTRUCTOR NOMBRE = <nombre>, MODIFICADOR = <modificadores> TIPO RETORNO = <tipoRetorno> PARAMETRO(0) TIPO= <tipo> PARAMETRO(1) TIPO= <tipo1>……PARAMETRO(n) TIPO= <tipoN>

Como “ayuda ” nos dicen que tipoRetorno lo consideremos una cadena vacía…bueno así lo hemos hecho:

import java.lang.reflect.*;

public class Constructor extends Metodo {

public Constructor(String nombre, int modificadores, Parametro[] parametros ) {
super(nombre, modificadores,”",parametros);

}

public String toString() {
String resultado = “CONSTRUCTOR” + super.toString();
return resultado;
}

}

como podéis ver en el código, a la hora de heredar el tipoRetorno lo que hacemos es poner una cadena vacía “”, y todo lo demas lo hereda de Metodo…el toString() es totalmente igual así que con una llamada a super vale.

Aqui nos hemos quedado, ya se intentará hacer lo demás, que es lo mas dificil…y a ver si sabemos hacerlo…

CONSEJO:   después de hacer esta práctica nos hemos dado cuenta de que cuando tienes que hacer un método que devuelva algo, es mucho mejor crearse una variable, hacer todo  lo que tengas que hacer, y luego devolver solo la variable que intentar hacerlo todo de golpe en el return. A nosotros por lo menos nos ha servido de mucho hacerlo así, si los demás preferís de la otra forma,pues nada, pero aquí queda nuestro consejo por experiencia propia :D

 

PRÁCTICA 3

•17 Marzo, 2008 • 1 comentario

Seguimos trabajando en el ahorcado ( bueno para ser sinceros lo tenemos un poco olvidado…) pero cuando lo consigamos, que lo haremos, lo pondremos aqui. Mientras tanto vamos a comentar la práctica 3 ( si, debería ser la 4, pero tranquilos que está al caer).

Ejercicio 0:

Ejercicio en el que simplemente hay que localizar el nombre de la clase, los atributos… bastante sencillito por lo que no vamos a responder aqui cada pregunta ( claro que si alguien quiere que le ayudemos que nos lo pida). Os ponemos nuestra clase de Prueba:

public class PruebaObjeto{
public static void main(String []args){

Punto p1 = new Punto(2.5, 4.3);
Punto p2 = new Punto(1.2, 3.3);
System.out.println(p1.toString());
System.out.println(“(” + p1.getX () + “,”+ p1.getY() + “)”);
System.out.println(“La distancia al orígen es: ” +p1.distanciaAlOrigen());
System.out.println(“La distancia entre p1 y p2 es: ” +p1.calcularDistancia(p2));
System.out.println(“Número de objetos creados: ” + Punto.contador);

}

}

Hacer:

  1. Imprime por pantalla la cadena de caracteres con la representación del objeto p1.
  2. Imprime por pantalla las coordenadas del punto p1.

Equivale a lo mismo.Tiene sentido, ya que lo que devuelve el método toString son las coordenadas del objeto con el que llames al método. Es repetitivo hacer estas dos cosas, pero suponemos que lo pondrían para que te dieras cuenta de que es lo mismo, o quizá para que solo lo hicieras una vez…pero bueno, así lo hicimos.

Ejercicio 1:

En  los ejercicios para hacer en casa dudamos un poco bastante, entonces si alguien fuera tan amable…estaríamos bastante agradecidos.

Ejercicio 2:

Hay que implementar el constructor y el método toString() de una clase Atributo. Nuestro código:

public class Atributo {

public String nombre = null;
public String tipo = null;
public int modificadores = 0;

public Atributo(String nombre, String tipo, int modificadores ) {
this.nombre = nombre;
this.tipo = tipo;
this.modificadores = modificadores;

}

public String toString() {

return “ATRIBUTO : NOMBRE = ” + nombre+” TIPO = ” + tipo + “MODIFICADOR ACCESO = ” + Modificador.toString(modificadores);

}

// Hacemos el main para comprobar lo que hace nuestro método

public static void main (String []args){

Atributo atributo = new Atributo( “atributo”, “String”, 10 );

System.out.println( atributo.toString());

}
}

Primero hemos rellenado el constructor como siempre, es decir como parámetros le pongo los que quiero que me metan al crearlo y luego digo que los atributos de antes sean los parámetros que le meto ( no sabemos muy bien como explicar esto, esperamos que se nos entienda :S). Luego rellenamos el método toString() que es un método que no imprime nada, simplemente devuelve algo ( lo que quieras) de ahí el return, en el que hemos puesto lo que dicen en el enunciado que devuelve.

El problema de este ejercicio ( por lo menos para nosotros ) estaba al imprimir el nombre del modificador de acceso… pero vamos que al final lo sacamos más bien por sentido común, ya que para algo tenía que estar la clase Modificador; lo único que haces es llamar al método toString ( int modificador) de la clase Modificador, que es el que está implementado para que te devuelva el modificador asociado al entero que le metes como parámetro.

Ejercicio 3:

Este ejercicio es un poco repetitivo, si sacas el anterior, sacas este. No vamos a poner el código porque es más de lo mismo ( volvemos a decir, si alguien tiene algún problema que lo pida)

Ejercicio 4:

Empiezan los problemas… Con lo contentos que estábamos porque nos salía todo, y no sólo eso, si no que no nos parecía complicado y llega esto y nos hace bajar de las nubes ( esque ni siquiera estábamos seguros de lo que nos pedían).Así que aquí nos quedamos.

Os aseguramos que esta práctica tendrá continuación cuando la acabemos, pero no podemos decir cuando será eso, ya que estamos muy liados con todo : el juego ( que también está un poco olvidado), otras prácticas, y todo hay que decirlo, las ganas de descansar, que también cuentan.

Aquí dejamos esta práctica, ahora continuamos con la 4, que ya que nos hemos puesto hay que aprovechar…

Una queja

•13 Marzo, 2008 • Dejar un comentario

Bueno, yo no sé si es que nosotros somos así de torpes, o realmente es un problema generalizado. Pero desde este blog quiero decir que las practicas de OCA son MUY LARGAS. No muy largas, interminables. Algunos tenemos más asignaturas (dificiles o no, como Lineales, estadistica, mates, y gente de 2º) Y no puede ser que dediquemos nuestra vida a la programación, así pasa, que suspendemos.

De los 5 ejercicios que pueda tener una práctica, en clase de prácticas se resuelve 1, quedando 4 para casa. Teniendo en cuenta la desorientación que nos caracteriza son muchos ejercicios y poco tiempo. Además hay que hacer el blog (que eso mal que bien lo llevamos) y además un juego, que dentro de 1 mes hay que hacer la primera entrega…

Al margen de eso las clases de teoria me parecen demasiado teóricas, pero eso supongo que nos da una visión más general de la programación, y menos orientada a java como lenguaje.

Que conste que esta opinión es solo de Oscar Leal Díaz (por lo que pueda acarrear) y sin el consentimiento de mi compañera.