Posteado por: albalba | Marzo 21, 2008

Práctica 4

HI!!!QUE HAY DE NUEVO VIEJO!!

Aunque parezca que tenemos complejo de Bugs Bunny no lo tenemos ni todavía hemos pisado la Warner. Esperaremos al calorcito, como el que pasamos en el aula con tantos “bichos cuadrados”, comúnmente denominados ordenadores, pero una ventana abierta por la que entraba aire fresco ayudó a nuestras neuronas a ponerse manos a la obra ese viernes 14 de Marzo de 2008, empezando con la herencia en Java.

Al principio de la clase Alberto estuvo explicándola utilizando ejemplos parecidos a estos: 


ÏÕÖ×class Persona
Ïϧ{
ÏϧÏíÏString nombre;
ÏϧÏíÏint edad;
ÏϧÏÞßàPersona()
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïedad=18;
ÏϧÏÏ©}
ÏϧÏÞßàPersona(String n, int e)
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïnombre=n;
ÏϧÏϨ¹¹Ïedad=e;
ÏϧÏÏ©}
ÏϧÏÞßàvoid setEdad(int e)
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïedad=e;
ÏϧÏÏ©}
ÏϧÏÞßàvoid mostrar()
ÏϧÏϧ{
ÏϧÏϨ¹¹ÏSystem.out.print(nombre+” “+edad);
ÏϧÏÏ©}
ÏÏ©}ÏÕÖ×class Alumno extends Persona
Ïϧ{
ÏϧÏíÏint nAsig;
ÏϧÏÞßàAlumno()
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïsuper(); //se le llama por defecto
ÏϧÏϨ¹¹ÏsetNasig(2);
ÏϧÏÏ©}
ÏϧÏÞßàAlumno(String n, int e, int num)
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïsuper(n,e);
ÏϧÏϨ¹¹ÏnAsig=num;
ÏϧÏÏ©}
ÏϧÏÞßàvoid setNasig(int n)
ÏϧÏϧ{
ÏϧÏϨ¹¹ÏnAsig=n;
ÏϧÏÏ©}
ÏϧÏÞßàvoid mostrar()
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïsuper.mostrar();
ÏϧÏϨ¹¹ÏSystem.out.print(” “+nAsig);
ÏϧÏÏ©}
ÏÏ©}

   Ahora, directamente recolectado de nuestra cosecha propia, algunas explicaciones sobre la herencia. Siiiiiiiiii, y con la ayuda de algún que otro libro jeje, que le vamos a hacer. PERFECTOS NO SOMOS J Si tenemos una clase y queremos hacer otra parecida usamos la herencia, por lo que haríamos que la segunda herede de la primera. La que hereda se llama subclase y de la que heredan, superclase. La subclase tendrá todo de la superclase MENOS los constructores y lo que sea privado. Es decir, que la herencia permite crear una o más clases a partir de otra que ya existe, así podemos reutilizar el código.En código para que una clase herede de otra se sigue el siguiente esquema:Class + (el nombre de la clase) + extends + (la clase de la que se quiera heredar)Ejemplo: class Alumno extends Persona Así la superclase tendrá sus atributos y métodos, y en la subclase puede escribirse los mismos atributos que los de la superclase MÁS los propios, lo mismo sucede con los métodos. En resumen, cuando una subclase extiende(o hereda) de una superclase, obtiene todos los atributos (si son public en lugar de private) y métodos de la superclase (y todos los miembros de los antecesores de la superclase). Además puede añadir los suyos propios e incluso modificar los heredados.Volver a escribir un método exactamente igual en todo de la superclase en la subclase sería SOBRESCRIBIRLO. ¡¡CUIDADO COMPAÑEROS!! No es lo mismo que escribir el método CASI  idéntico, entonces SOBRECARGAMOS.Al sobrescribir un método hay que tener en cuenta que si el método de la superclase es static, también debe serlo en las subclases. Una subclase puede cambiar un modificador de acceso pero sólo para ampliarlo (por ejemplo, private en la superclase a public en la clase extendida o subclase).Si se declara un campo en la subclase con el mismo nombre que el de la superclase, los dos campos existen. Para acceder al de la superclase, usar super. En herencia se puede crear referencias de la superclase e instancias de la subclase:Superclase ref;ref= new Subclase( ); Una referencia de la subclase no puede apuntar jamás a una instancia de la superclase. Sería herencia múltiple, la cual no está permitida en Java.¡NO! Subclase x = new Superclase();En realidad, todas las clases heredan de Object, es la raíz de la jerarquía, ya sea directa o indirectamente. Por lo que todas las clases heredan los métodos de Object que son: public boolean equals(Object obj)pubic String toString( )public Object clone( )protected void finalize( ) Si se quiere hacer una clase de la que no se pueda heredar, hay que añadir antes de class, final. 

Una vez dejado claro todo esto, nos introdujimos en la PRÁCTICA 4 para la cual había que usar….lo adivináis? HERENCIA!! Siguiendo el esquema.

esquema_v1.jpg  Reutilizando los programas de la anterior práctica.Tras empollarnos la “breve” introducción, modelamos nuestros programas de la práctica 3. Lo primero era programar la clase Miembro ya que es la superclase, todas van a heredar de ella, por tanto había que ponerle esmero.Nos planteaban la pregunta ¿Qué pasaría si se cambiara protected por private en nuestra jerarquía de clases? Y nos pareció interesante. Como expusimos anteriormente, no se pueden heredar los miembros de una clase que sean private. El modificador de acceso private es mucho más restrictivo a la hora de realizar herencia que el protected. Un miembro declarado como private sólo puede ser accedido desde su propia clase. En cambio, un miembro declarado con protected no solo puede ser accedido desde su misma clase, sino que también desde cualquier otra clase o subclase del mismo paquete, o cualquier subclase de otro paquete.Pues siguiendo con el esmero de nuestro “Miembro” (a buen entendedor pocas palabras bastan jaja)  implementamos el constructor de la clase Miembro y el método toString( ). En el constructor, como siempre, igualamos los atributos a los valores pasados por parámetro.Para entender el método toString( ) deberéis echarle un ojo a la clase Modificador. Creamos un objeto modificador para invocar al método toString() de esa clase, pasándole por parámetro el valor int del modificador de acceso, es decir, el atributo modificadores. Si observáis ese método en la clase Modificador, veréis que se devuelve el String del modificador de acceso correspondiente al int.El getNombre() lo necesitamos mas adelante, de todas formas los get y set de los atributos no sobran en ninguna clase.  

ÏÕÖ×public class Miembro
Ïϧ{
Ïϧ
ÏϧÏíÏprotected String nombre = null;
ÏϧÏíÏprotected int modificadores = 0;
Ïϧ
ÏϧÏÞßàpublic Miembro(String nombre, int modificadores )
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïthis.nombre=nombre;
ÏϧÏϨ¹¹Ïthis.modificadores=modificadores;
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic String toString()
ÏϧÏϧ{
ÏϧÏϨ¹íÏModificador modif=new Modificador();
ÏϧÏϨ¹¹
ÏϧÏϧ
Ïϧ¹Ĺ¹Ïreturn “NOMBRE: “+nombre+“, MODIFICADOR DE ACCESO: “+ Ïmodif.toString(modificadores);
ÏϧÏϧ
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic String getNombre()
ÏϧÏϧ{
Ïϧ¹Ĺ¹Ïreturn nombre;
ÏϧÏÏ©}
ÏÏ©}

  

A continuación seguimos con la clase Atributo que hereda de Miembro, de ahí el extends Miembro. Al igual que antes, implementamos el constructor de esta clase y su método toString( ).

En esta ocasión, en el constructor utilizamos el super(nombre,modificadores) para llamar al constructor que los utiliza en la clase Miembro, de esta forma tan solo hay que igualar el atributo tipo al que nos dan por parámetro ya que ese no está en el constructor de Miembro. Es un atributo que añadimos en esta clase.

Para el toString( ) de nuevo volvemos a utilizar el super para invocar al método toString( ) de la superclase Miembro. Si os fijáis en el toString() de Miembro, se observa que la incluye el nombre y el modificador de acceso, por lo que nos aprovechamos de la herencia y tan solo nos queda añadir el tipo del atributo para completar el formato de la cadena de caracteres que tiene que devolver en esta clase.

/**
 * Clase Atributo.
 *
 * @author DIT-UC3M
 */
ÏÕÖ×public class Atributo extends Miembro
Ïϧ{
ÏϧÏíÏpublic String  tipo= null;
Ïϧ
Ïϧ /**   Crea una instancia de Atributo   */
ÏϧÏÞßàpublic Atributo(String nombre, String tipo, int modificadores )
ÏϧÏϧ{
ÏϧÏϧ
ÏϧÏϨ¹¹Ïsuper(nombre,modificadores);
ÏϧÏϨ¹¹Ïthis.tipo=tipo;
ÏϧÏϧ
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic String toString()
ÏϧÏϧ{
Ïϧ¹Ĺ¹Ïreturn “ATRIBUTO: “+super.toString()+“, TIPO: “+tipo;
ÏϧÏÏ©}
ÏÏ©}

  

Seguimos con la clase Método para la que necesitamos la clase Parámetro, que nos dan ya implementada. De nuevo a rellenar sus respectivos constructor y toString().

En el primero se soluciona igual que el anterior.

El toString() varía de los anteriores pero sólo un poquito. Creamos un objeto de tipo String llamado temp (temporal) que tiene como cadena de caracteres: METODO, llamando super.toString() se une a la cadena el nombre y el modificador de acceso del método, seguido del tipo de retorno. Como disponemos de un array de parámetros, recorremos el array a la vez que vamos concatenando los valores de cada parámetro a temp. Seguimos el esquema, de esta manera, que nos indican, con los parámetros:

Parámetro (0) tipo= (tipo0)

Parámetro (1) tipo= (tipo1) …

 y así sucesivamente, con la ayuda del omnipresente … como era… es imposible olvidar al….TOSTRING()!! Juajuajuaaaa!! (risa malvada del toString() por estar omnipresente, y la siguiente fase será ser omnipotente jaja). Pensad que es bueno tener momentos de “pirada de pinza” como éste para que nos sea mas ameno el escrito al cual bien se le puede denominar testamento. J

En definitiva, todo va concatenado en temp el cual devuelvemos.

Al mirar la clase Parámetro dimos un brinco en la silla con ruedas del aula de ordenadores que a poco nos estampamos contra las ventanas, todo por la impresión de ver un StringBuffer. Es una de esas cosas que siempre te dicen que existe pero que nunca ves, hasta que llega el momento de verlo claro esta.

String es una cadena de caracteres (alfanumérica) y no se puede cambiar una vez creada. Esto no ocurre con el StringBuffer (siempre escribo buffar en lugar de buffer, son los efectos secundarios de tener perro jaja).

StringBuffer representa una cadena cuya tamaño puede cambiar, es variable.

La siguiente información proviene de la página http://www.ulpgc.es/otros/tutoriales/java/Cap3/sbuffer.html

La clase StringBuffer dispone de muchos métodos para modificar el contenido de los objetos StringBuffer. Si el contenido de una cadena va a ser modificado en un programa, habrá que sacrificar el uso de objetos String en beneficio de StringBuffer, que aunque consumen más recursos del sistema, permiten ese tipo de manipulaciones.

Al estar la mayoría de las características de los StringBuffers basadas en su tamaño variable, se necesita un nuevo método de creación:

     StringBuffer();    StringBuffer( int len );    StringBuffer( String str );

Se puede crear un StringBuffer vacío de cualquier longitud y también se puede utilizar un String como punto de partida para un StringBuffer.

    StringBuffer Dos = new StringBuffer( 20 );    StringBuffer Uno = new StringBuffer( “Hola Mundo” ); 

El cambio de tamaño de un StringBuffer necesita varias funciones específicas para manipular el tamaño de las cadenas:

    int length();    char charAt( int index );    void getChars( int srcBegin,int srcEnd,char dst[],int dstBegin );    String toString();    void setLength( int newlength );    void setCharAt( int index,char ch );    int capacity();    void ensureCapacity( int minimum );

    void copyWhenShared();

Obervar que una de las funciones devuelve una cadena constante normal de tipo String. Este objeto se puede usar con cualquier función String, como por ejemplo, en las funciones de comparación.

Para cambiar el contenido de un StringBuffer, se pueden utilizar dos métodos: append() e insert().

En el ejemplo CadAppend.java, vemos el uso de estos dos métodos:

  

ÕÖ×class CadAppend
Ïϧ{
ÏϧÏÞßàpublic static void main( String args[] )
ÏϧÏϧ{
ÏϧÏϨ¹íÏStringBuffer str = new StringBuffer( “Hola” );
ÏϧÏϨ¹¹Ïstr.append( ” Mundo” );
ÏϧÏϨ¹¹ÏSystem.out.println( str );
ÏϧÏÏ©}
ÏÏ©}//En este otro ejemplo, CadInversa.java, mostramos un método muy simple que le da la vuelta a una cadena: ÏÕÖ×class CadInversa
Ïϧ{
ÏϧÏÞßàpublic static String cadenaInversa( String fuente )
ÏϧÏϧ{
ÏϧÏϨ¹íÏint longitud = fuente.length();
ÏϧÏϧ
ÏϧÏϨ¹íÏStringBuffer destino = new StringBuffer( longitud );
ÏϧÏϨ¹¹±for( int i=(longitud-1); i >= 0; i– )
ÏϧÏϧÏÏй¹Ïdestino.append( fuente.charAt( i ) );
ÏϧÏϧ
Ïϧ¹Ĺ¹Ïreturn( destino.toString() );
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic static void main( String args[] ) {
ÏϧÏϨ¹¹ÏSystem.out.println( cadenaInversa( “Hola Mundo” ) );
ÏϧÏÏ©}
Ïϧ   
Ïϧ   
Ïϧ   
Ïϧ
Ïϧ//Las funciones que cambian el tamaño son pues:
ÏϧÏÞßàStringBuffer append( Object obj );
ÏϧÏÞßàStringBuffer append( String str );
ÏϧÏÞßàStringBuffer append( char str[] );
ÏϧÏÞßàStringBuffer append( char str[],int offset,int len );
ÏϧÏÞßàStringBuffer append( boolean b );
ÏϧÏÞßàStringBuffer append( int i );
ÏϧÏÞßàStringBuffer append( long l );
ÏϧÏÞßàStringBuffer append( float f );
ÏϧÏÞßàStringBuffer append( double d );
ÏϧÏÞßàStringBuffer append( char ch );
ÏϧÏÞßàStringBuffer insert( int offset,Object obj );
ÏϧÏÞßàStringBuffer insert( int offset,String str );
ÏϧÏÞßàStringBuffer insert( int offset,char str[] );
ÏϧÏÞßàStringBuffer insert( int offset,boolean b );
ÏϧÏÞßàStringBuffer insert( int offset,int i );
ÏϧÏÞßàStringBuffer insert( int offset,long l );
ÏϧÏÞßàStringBuffer insert( int offset,float f );
ÏϧÏÞßàStringBuffer insert( int offset,double d );
ÏϧÏÞßàStringBuffer insert( int offset,char ch );
ÏÏ©}

   

Hay que recordar que los operadores “+” y “+=” también se pueden aplicar a cadenas. Ambos realizan una concatenación y están implementados con objetos StringBuffer.

Por ejemplo, la sentencia:

    String s = “¿Qué” + ” tal ?”;

es interpretada por el compilador como:

    String s = new StringBuffer().append( “¿Qué” ).append( ” tal ?” ).toString();

y se marcaría el StringBuffer para borrarlo ya que el contenido pasa al objeto String. También, la sentencia:

    s += ” por ahí!”;

sería interpretada por el sistema como:

    String s =

        new StringBuffer().append( s ).append( ” por ahí!” ).toString();

y volvería a marcar para borrar el nuevo StringBuffer.

Así pues, nuestro Metodo:

ÏÕÖ×public class Metodo extends Miembro
Ïϧ{
Ïϧ
ÏϧÏíÏprotected String tipoRetorno = null;
ÏϧÏíÏprotected 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 temp=“METODO “+super.toString()+” ,TIPO DE RETORNO: “+tipoRetorno;
ÏϧÏϧ
ÏϧÏϨ¹¹±for(int i=0;i<parametros.length;i++)
ÏϧÏϧÏÏ5{
ÏϧÏϧÏÏ7¹¹Ïtemp+=” \nPARAMETRO (”+i+“) TIPO= “+parametros[i].toString();
ÏϧÏϧÏϰ}
Ïϧ¹Ĺ¹Ïreturn temp;
ÏϧÏÏ©}
ÏÏ©}/*
 * Parametro.java
 *
 * (c) DIT-UC3M 2007
 *
 */
/**
 * Esta clase almacena la información de un parámetro. Solo nos interesa su tipo.
 *
 * @author (c) DIT-UC3M 2007
 */
ÏÕÖ×public class Parametro {
Ïϧ
ÏϧÏíÏString tipo;
Ïϧ
Ïϧ /** Constructor */
ÏϧÏÞßàpublic Parametro( String tipo) {
ÏϧÏϨ¹¹Ïthis.tipo = tipo;  
ÏϧÏÏ©}
Ïϧ
Ïϧ /**
Ïϧ  * Devuelve una cadena de caracteres (String) con una descripción
Ïϧ  * literal del objeto y los valores de sus atributos.
Ïϧ  *
Ïϧ  */
ÏϧÏÞßàpublic String toString() {
ÏϧÏϨ¹íÏStringBuffer ret=new StringBuffer();
ÏϧÏϨ¹¹Ïret.append(” TIPO = “+ tipo);
Ïϧ¹Ĺ¹Ïreturn ret.toString();
ÏϧÏÏ©}   
Ïϧ
ÏÏ©}

Continuamos andando por la senda de la herencia con Constructor del cual hay que implementar EL CONSTRUCTOR Y EL TOSTRING, QUE SORPRESA!!

La única diferencia es que Constructor hereda de Método no de Miembro.

Para el constructor con llamar a super lo tenemos todo resuelto, porque invocamos al constructor de Método que tiene todo lo que necesitamos.

Con toString(), tanto de lo mismo. Lo invocamos de su superclase con super.

// NOTA: Estos imports son SOLO necesarios para los metodos que que YA ESTÁN IMPLEMENTADOS.
ÏÏÏimport java.lang.reflect.*;/**
 *  Clase Constructor.
 *
 * @author DIT-UC3M
 */
ÏÕÖ×public class Constructor extends Metodo
Ïϧ{
Ïϧ
ÏϧÏÞßàpublic Constructor(String nombre, int modificadores, Parametro[] parametros )
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïsuper(nombre,modificadores,“”,parametros);
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic String toString()
ÏϧÏϧ{
Ïϧ¹Ĺ¹Ïreturn “CONSTRUCTOR “+super.toString();
ÏϧÏÏ©}
ÏÏ©}

Aquí llegó el horror. En las prácticas nos quedamos investigando como terminar esta clase. Ha sido muy complicado de hacer. Las anteriores clases eran muy fáciles comparadas a ésta. Nos era imposible comprender si quiera el código. Por lo que nos dedicamos a implementar, en la medida de lo posible lo que nos pedían, pero nos daban bastantes errores, sobretodo la excepción ArrayIndexOutOfBoundsException.  

Lo primero era el getAtributos() en el cual tenemos que recorrer el array de miembros, separando los atributos, ahora el problema era como diferenciamos un método de un atributo……….., pues la solución era con el instanceof. Con él, como pone en el enunciado de la práctica, si se hace una comparación entre lo que tiene miembros y la instancia de la clase que queremos buscar, nos dará un true en el caso afirmativo. De esta manera hacemos la comparación:

if(miembros[i] instanceof Atributo==true)
 {
 
//asignamos a un array de Atributos los atributos encontrados
 }

En el interior de la condición, como pone en el comentario, tenemos que asignar a un array de Atributos los atributos encontrados, entonces todos pensamos que sería algo así:

if(miembros[i] instanceof Atributo==true)
 {
 
atributos=miembros[i];
 }

Pero al compilar nos daría un error porque Atributos hereda de Miembro, y como ya dijimos en la explicación sobre la herencia, se puede crear una referencia de la superclase con una instancia de la subclase pero jamás al contrario:

Superclase referencia = new Subclase( );

De igual modo:

Superclase referencia = new Superclase( );

Subclase referencia = new Subclase( );

Por lo que tenemos que hacer un casting de Miembros a Atributos, quedando:

if(miembros[i] instanceof Atributo==true)
 {
 
atributos=(Atributos) miembros[i];
 }

Como hay que repetir esta acción hasta llegar al final del array de miembros, colocamos un for para recorrer todo el array, y para poder guardar todos los valores en atributo, creamos un array de atributos. Operación que seguimos con todos los get.

Para el esEjecutable( ), seguimos el mismo sistema que con los get, buscamos los métodos de entre todos los miembros, una vez que encontramos uno vemos que su nombre sea main (condición necesaria para que sea un método ejecutable)  usando el getNombre( ), siiiiiiiii, aquel de la clase Miembro que dijimos que emplearíamos más tarde, pues para esto era señoras y señores!!

El método toString() nos da algunos problemas, es por él por lo que nos salta la excepción ArrayIndexOutOfBoundsException.  Sabíamos que esta excepción nos salía porque en algún bucle nos salíamos de las dimensiones del array, pero no sabíamos el por qué, de modo que utilizamos los famosos try y catch para capturar la excepción.

/*
 * Clase.java
 *
 * (c) DIT-UC3M 2007
 *
 */
ÏÏÏimport java.lang.reflect.Field;
ÏÏÏimport java.lang.reflect.Method;
ÏÏÏimport java.io.*; /**
 * Una clase contiene la información de la clase de un objeto o instancia de Java.
 * Dicha información es el nombre y el conjunto de Miembros de la misma.
 *
 * @author (c) DIT-UC3M 2007
 */
ÏÕÖ×public class Clase {
Ïϧ
ÏϧÏíÏString nombre = null;
ÏϧÏíÏprivate Miembro[] miembros = null;
Ïϧ
ÏϧÏíÏprivate int numAtributos = 0;
ÏϧÏíÏprivate int numConstructores = 0;
ÏϧÏíÏprivate int numMetodos = 0;
Ïϧ
Ïϧ /** Constructor de la clase a partir de una instancia de un objeto de Java */
ÏϧÏÞßàpublic Clase( Object o)
ÏϧÏϧ  {
ÏϧÏϧ// ESTE MÉTODO YA ESTÁ IMPLEMENTADO      
ÏϧÏϨ¹íÏint i=0, j=0;
ÏϧÏϧ  // Se obtiene el nombre de la clase del objeto accediendo a la clase de “o”
ÏϧÏϧ  // para ello, se usa el método correspondiente de la clase java.lang.Object
ÏϧÏϨ¹¹Ïthis.nombre = o.getClass().getName();
ÏϧÏϧ
ÏϧÏϧ  // Se calcula el número de miembros de la clase, teniendo en cuenta que
ÏϧÏϧ  // los miembros son los atributos, constructores y métodos de la clase.
ÏϧÏϨ¹¹ÏnumAtributos = o.getClass().getDeclaredFields().length;
ÏϧÏϨ¹¹ÏnumConstructores = o.getClass().getConstructors().length;
ÏϧÏϨ¹¹ÏnumMetodos = o.getClass().getDeclaredMethods().length; 
ÏϧÏϧ
ÏϧÏϨ¹¹ÏSystem.out.print(“\nnombre= “+nombre+” -> “+numAtributos+” atributos, “+numConstructores+ ” costructores, “+numMetodos+” metodos.\n”);
ÏϧÏϧ
ÏϧÏϧ  // Se crea el array de miembros con el numero total de ellos
ÏϧÏϨ¹¹Ïmiembros = new Miembro[numAtributos+numConstructores+numMetodos];
ÏϧÏϧ
ÏϧÏϧ  // Se añaden los atributos al array de miembros
ÏϧÏϨ¹¹±for ( i=0, j=0; i<numAtributos ; i++)
ÏϧÏϧÏÏ5{
ÏϧÏϧÏÏ7¹íÏField f = o.getClass().getDeclaredFields()[j++];
ÏϧÏϧÏÏ7¹¹ÏSystem.out.print(“\nAñadiendo ATRIBUTO “+i+“, nombre “+f.getName()+” modif=”+f.getModifiers());
ÏϧÏϧÏÏ7¹¹Ïmiembros[i] = new Atributo(f.getName(),f.getType().getName(),f.getModifiers());
ÏϧÏϧÏϰ}
ÏϧÏϧ
ÏϧÏϧ  // Se añaden los constructores al array de miembros
ÏϧÏϨ¹¹±for ( i=numAtributos, j=0; i<numAtributos+numConstructores ; i++) {
ÏϧÏϧÏÏ7¹íÏjava.lang.reflect.Constructor c = o.getClass().getConstructors()[j++];
ÏϧÏϧÏÏ7¹¹ÏSystem.out.print(“\nAñadiendo CONSTRUCTOR “+i+“, nombre “+c.getName()+” modif=”+c.getModifiers());
ÏϧÏϧÏÏ7¹¹Ïmiembros[i] = new Constructor(c.getName(),c.getModifiers(), dameParametros(c));
ÏϧÏϧÏϰ}
ÏϧÏϧ
ÏϧÏϧ  // Se añaden los métodos al array de miembros
ÏϧÏϨ¹¹±for ( i=numAtributos+numConstructores, j=0; i<numAtributos+numConstructores+numMetodos ; i++) {
ÏϧÏϧÏÏ7¹íÏMethod m =  o.getClass().getDeclaredMethods()[j++];
ÏϧÏϧÏÏ7¹¹ÏSystem.out.print(“\nAñadiendo METODO “+i+“, nombre “+m.getName()+” modif=”+m.getModifiers()+” retorno=”+m.getReturnType().getName());
ÏϧÏϧÏÏ7¹¹Ïmiembros[i] = new Metodo(m.getName(), m.getModifiers(),m.getReturnType().getName(),dameParametros(m));
ÏϧÏϧÏϰ}
ÏϧÏÏ©}
Ïϧ
Ïϧ /** Método auxiliar privado para conseguir los parámetros de un Método */
ÏϧÏÞßàprivate Parametro[] dameParametros( java.lang.reflect.Method m )
ÏϧÏϧ {
ÏϧÏϧ// ESTE MÉTODO YA ESTÁ IMPLEMENTADO      
ÏϧÏϨ¹íÏint numParam = m.getParameterTypes().length;
ÏϧÏϧ
ÏϧÏϨ¹íÏParametro[] param = new Parametro[numParam];
ÏϧÏϧ
ÏϧÏϨ¹¹±for (int i=0; i<numParam; i++ ){
ÏϧÏϧÏÏ7¹¹Ïparam[i] = new Parametro(m.getParameterTypes()[i].getName());
ÏϧÏϧÏϰ}
ÏϧÏϧ
Ïϧ¹Ĺ¹Ïreturn param;
ÏϧÏÏ©}
Ïϧ
Ïϧ /** Método auxiliar privado para conseguir los parámetros de un Constructor */
ÏϧÏÞßàprivate Parametro[] dameParametros( java.lang.reflect.Constructor c )
ÏϧÏϧ {
ÏϧÏϧ// ESTE MÉTODO YA ESTÁ IMPLEMENTADO       
ÏϧÏϨ¹íÏint numParam = c.getParameterTypes().length;
ÏϧÏϧ
ÏϧÏϨ¹íÏParametro[] param = new Parametro[numParam];
ÏϧÏϧ
ÏϧÏϨ¹¹±for (int i=0; i<numParam; i++ ){
ÏϧÏϧÏÏ7¹¹Ïparam[i] = new Parametro(c.getParameterTypes()[i].getName());
ÏϧÏϧÏϰ}
ÏϧÏϧ
Ïϧ¹Ĺ¹Ïreturn param;
ÏϧÏÏ©}
Ïϧ
Ïϧ /** Obtiene el array de Atributos de la clase */
ÏϧÏÞßàpublic Atributo[] getAtributos()
ÏϧÏϧ{
ÏϧÏϨ¹íÏAtributo[] regresa=new Atributo[numAtributos];
ÏϧÏϨ¹íÏint j=0;
ÏϧÏϨ¹¹±for(int i=0;i<miembros.length;i++)
ÏϧÏϧÏÏ5{
ÏϧÏϧÏÏ7¹³´if(miembros[i]instanceof Atributo==true)
ÏϧÏϧÏÏ5Ï6§{
ÏϧÏϧÏÏ5Ï6§  
ÏϧÏϧÏÏ5Ï6¨¹¹Ïregresa[j]= (Atributo) miembros[i];
ÏϧÏϧÏÏ5Ï6§  
ÏϧÏϧÏÏ5Ï6¾¹¹Ïj++;
ÏϧÏϧÏÏ5϶Ï}
ÏϧÏϧÏÏ5  
ÏϧÏϧÏϰ}
ÏϧÏϧ  
Ïϧ¹Ĺ¹Ïreturn regresa;
ÏϧÏÏ©}
Ïϧ
Ïϧ /** Obtiene el array de Constructores de la clase */
ÏϧÏÞßàpublic Constructor[] getConstructores()
ÏϧÏϧ{
ÏϧÏϨ¹íÏConstructor[] regresa=new Constructor[numConstructores];
ÏϧÏϨ¹íÏint j=0;
ÏϧÏϧ  
ÏϧÏϧ  
ÏϧÏϨ¹¹±for(int i=0;i<miembros.length;i++)
ÏϧÏϧÏÏ5{
ÏϧÏϧÏÏ7¹³´if(miembros[i]instanceof Constructor==true)
ÏϧÏϧÏÏ5Ï6§{
ÏϧÏϧÏÏ5Ï6§  
ÏϧÏϧÏÏ5Ï6¨¹¹Ïregresa[j]= (Constructor) miembros[i];
ÏϧÏϧÏÏ5Ï6§  
ÏϧÏϧÏÏ5Ï6¾¹¹Ïj++;
ÏϧÏϧÏÏ5Ï6Ï  
ÏϧÏϧÏÏ5Ï6Ï     
ÏϧÏϧÏÏ5϶Ï}
ÏϧÏϧÏÏ5  
ÏϧÏϧÏϰ}
Ïϧ¹Ĺ¹Ïreturn regresa;
ÏϧÏÏ©}
Ïϧ
Ïϧ /** Obtiene el array de Metodos de la clase */
ÏϧÏÞßàpublic Metodo[] getMetodos()
ÏϧÏϧ{
ÏϧÏϧ 
ÏϧÏϨ¹íÏMetodo[] regresa=new Metodo[numMetodos];
ÏϧÏϨ¹íÏint j=0;
ÏϧÏϨ¹¹´try
ÏϧÏϧÏϧ{
ÏϧÏϧÏϨ¹¹±for(int i=0;i<miembros.length;i++)
ÏϧÏϧÏϧÏÏ5{
ÏϧÏϧÏϧÏÏ7¹³´if(miembros[i]instanceof Metodo==true)
ÏϧÏϧÏϧÏÏ5Ï6§{
ÏϧÏϧÏϧÏÏ5Ï6§ 
ÏϧÏϧÏϧÏÏ5Ï6¨¹¹Ïregresa[j]= (Metodo) miembros[i];
ÏϧÏϧÏϧÏÏ5Ï6¾¹¹Ïj++;
ÏϧÏϧÏϧÏÏ5Ï6Ï
ÏϧÏϧÏϧÏÏ5Ï6Ï 
ÏϧÏϧÏϧÏÏ5϶Ï}
ÏϧÏϧÏϧÏÏ5  
ÏϧÏϧÏϧÏϰ}
ÏϧÏϧÏϧ}
ÏϧÏϧÏϧÏðîìcatch(ArrayIndexOutOfBoundsException e)
ÏϧÏϧÏϧÏϧ{
ÏϧÏϧÏÏ©ÏÏ©}
Ïϧ¹Ĺ¹Ïreturn regresa;
ÏϧÏÏ©}
Ïϧ
Ïϧ /** Comprueba si la clase es ejecutable. Para ello hay que comprobar
Ïϧ * que tiene el método main */
ÏϧÏÞßàprivate boolean esEjecutable()
ÏϧÏϧ{
ÏϧÏϨ¹íÏboolean ok=false;
ÏϧÏϨ¹íÏMetodo[] nuevo=new Metodo[numMetodos];
ÏϧÏϨ¹íÏint j=-1;
ÏϧÏϧ
ÏϧÏϨ¹¹±for(int i=0;i<miembros.length;i++)
ÏϧÏϧÏÏ5{
ÏϧÏϧÏÏ7¹³´if(miembros[i]instanceof Metodo==true)
ÏϧÏϧÏÏ5Ï6§{
ÏϧÏϧÏÏ5Ï6¨¹¹Ïj++;
ÏϧÏϧÏÏ5Ï6¨¹¹Ïnuevo[j]=(Metodo)miembros[i] ;
ÏϧÏϧÏÏ5Ï6§
ÏϧÏϧÏÏ5Ï6¾¹³´if(nuevo[j].getNombre()==“main”)
ÏϧÏϧÏÏ5Ï6ÏÏ6§{
ÏϧÏϧÏÏ5Ï6ÏÏ6¨¹¹Ïok=true;
ÏϧÏϧ¹ÇÏ6ÏÏ6¾¹¹Ïbreak;
ÏϧÏϧÏÏ5Ï6Ï϶Ï}
ÏϧÏϧÏÏ5Ï6Ï 
ÏϧÏϧÏÏ5϶Ï}
ÏϧÏϧÏϰ}
ÏϧÏϧ
Ïϧ¹Ĺ¹Ïreturn ok;
ÏϧÏÏ©}
Ïϧ
Ïϧ/**
Ïϧ  * Devuelve una cadena de caracteres (String) con una descripción
Ïϧ  * literal del objeto y los valores de sus atributos.
Ïϧ  *
Ïϧ  */
ÏϧÏÞßàpublic String toString()
ÏϧÏϧ{
ÏϧÏϨ¹íÏString regresa=“”;
ÏϧÏϨ¹íÏAtributo[] presentaAtributo=new Atributo[numAtributos];
ÏϧÏϨ¹íÏConstructor[] presentaConstructor=new Constructor[numConstructores];
ÏϧÏϨ¹íÏMetodo[] presentaMetodo=new Metodo[numMetodos];
ÏϧÏϧ
ÏϧÏϨ¹¹ÏpresentaAtributo=getAtributos();
ÏϧÏϨ¹¹ÏpresentaConstructor=getConstructores();
ÏϧÏϨ¹¹ÏpresentaMetodo=getMetodos();
ÏϧÏϨ¹¹´try
ÏϧÏϧÏϧ{
ÏϧÏϧÏϧ
ÏϧÏϧÏϨ¹¹±for(int i=0;i<numAtributos;i++)
ÏϧÏϧÏϧÏÏй¹Ïregresa+=presentaAtributo[i].toString();
ÏϧÏϧÏϨ¹¹±for(int i=0;i<numConstructores;i++)
ÏϧÏϧÏϧÏÏй¹Ïregresa+=presentaConstructor[i].toString();
ÏϧÏϧÏϨ¹¹±for(int i=0;i<numMetodos;i++)
ÏϧÏϧÏϧÏÏй¹Ïregresa+=presentaMetodo[i].toString();
ÏϧÏϧÏϧ  
ÏϧÏϧÏϧ
ÏϧÏϧÏϧ}
ÏϧÏϧÏϧÏðîìcatch(IndexOutOfBoundsException e)
ÏϧÏϧÏϧÏϧ{
ÏϧÏϧÏÏ©ÏÏ©}
ÏϧÏϧ
ÏϧÏϧ
Ïϧ¹Ĺ¹Ïreturn regresa;
ÏϧÏϧ
ÏϧÏÏ©}
Ïϧ
ÏÏ©}

 Y hasta aquí nuestra cuarta sesión de laboratorio de OCA.

Esperamos haberos servido de ayuda. En cuanto soluciones el toString() y acabemos el resto de la práctica la colgaremos.

Hasta la próxima ¡!

  A partir de aquí el resto de la práctica 4 que hemos realizado:

ÕÖ×public class AnalizadorObjeto {
Ïϧ
ÏϧÏíÏprivate Clase clase;
ÏϧÏíÏpublic String alias = “no tiene”;
ÏϧÏíÏpublic static int contador;
Ïϧ
Ïϧ
ÏϧÏÞßàpublic AnalizadorObjeto(Object o) {
ÏϧÏϨ¹¹Ïclase = new Clase(o);
ÏϧÏϨ¹¹Ïcontador++;
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic AnalizadorObjeto( Object o, String alias ) {
ÏϧÏϨ¹¹Ïthis(o);
ÏϧÏϨ¹¹Ïthis.alias = alias;
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic Clase getClase() {
Ïϧ¹Ĺ¹Ïreturn clase;
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic String toString() {
ÏϧÏϨ¹íÏStringBuffer str = new StringBuffer();
ÏϧÏϧ 
ÏϧÏϨ¹¹Ïstr.append(“\nOBJETO:  alias=”+alias);
ÏϧÏϨ¹¹Ïstr.append(clase.toString());
ÏϧÏϧ 
Ïϧ¹Ĺ¹Ïreturn str.toString();
ÏϧÏÏ©}
Ïϧ
Ïϧ
ÏÏ©}

/*
 * ClasePrueba.java
 *
 * Created on 13 de febrero de 2007, 12:28
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 *//**
 *
 * @author JR6081
 */
ÏÕÖ×public class ClasePrueba {
Ïϧ
ÏϧÏíÏpublic String atributoPublico=“publico”;
Ïϧ
ÏϧÏíÏprotected int atributoProtegido = 0;
Ïϧ
ÏϧÏíÏprivate char atributoPrivao=‘a’;
Ïϧ
Ïϧ /** Creates a new instance of ClasePrueba */
ÏϧÏÞßàpublic ClasePrueba() {
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic ClasePrueba( String param1, int param2 ) {
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic void metodoPublico() {
ÏϧÏϧ 
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàprotected void metodoProtegido(float param1, int param2, String param3 ) {
ÏϧÏϧ 
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàprivate void metodoPrivado() {
ÏϧÏϧ 
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic static void main ( String[] args ){
ÏϧÏϧ 
ÏϧÏÏ©}
ÏÏ©}

  

/*
 * OtraClasePrueba.java
 *
 * Created on 13 de febrero de 2007, 13:03
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
/**
 *
 * @author JR6081
 */
ÏÕÖ×public class OtraClasePrueba {
Ïϧ
ÏϧÏíÏpublic String otroAtributoPublico=“publico”;
Ïϧ
ÏϧÏíÏprotected char otroAtributoProtegido = ‘b’;
Ïϧ
ÏϧÏíÏprivate int otroAtributoPrivao=0;
Ïϧ
Ïϧ /** Creates a new instance of ClasePrueba */
ÏϧÏÞßàpublic OtraClasePrueba() {
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic OtraClasePrueba( String param1, int param2 ) {
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic void otroMetodoPublico1() {
ÏϧÏϧ 
ÏϧÏÏ©}
ÏϧÏÞßàpublic void otroMetodoPublico2() {
ÏϧÏϧ 
ÏϧÏÏ©}
Ïϧ    
ÏϧÏÞßàprotected void otroMetodoProtegido1() {
ÏϧÏϧ 
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàprivate void otroMetodoPrivado1() {
ÏϧÏϧ 
ÏϧÏÏ©}
ÏÏ©}

ÏÕÖ×public class AnalizadorObjeto
Ïϧ{
Ïϧ
ÏϧÏíÏprivate Clase clase;
ÏϧÏíÏpublic String alias = “no tiene”;
ÏϧÏíÏpublic static int contador;
Ïϧ
Ïϧ
ÏϧÏÞßàpublic AnalizadorObjeto(Object o)
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïclase = new Clase(o);
ÏϧÏϨ¹¹Ïcontador++;
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic AnalizadorObjeto( Object o, String alias )
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïthis(o);
ÏϧÏϨ¹¹Ïthis.alias = alias;
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic Clase getClase()
ÏϧÏϧ{
Ïϧ¹Ĺ¹Ïreturn clase;
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic String toString()
ÏϧÏϧ{
ÏϧÏϨ¹íÏStringBuffer str = new StringBuffer();
ÏϧÏϧ 
ÏϧÏϨ¹¹Ïstr.append(“\nOBJETO:  alias=”+alias);
ÏϧÏϨ¹¹Ïstr.append(clase.toString());
ÏϧÏϧ 
Ïϧ¹Ĺ¹Ïreturn str.toString();
ÏϧÏÏ©}
Ïϧ
Ïϧ
ÏÏ©}

ÏÕÖ×public class AnalizadorObjeto
Ïϧ{
Ïϧ
ÏϧÏíÏprivate Clase clase;
ÏϧÏíÏpublic String alias = “no tiene”;
ÏϧÏíÏpublic static int contador;
Ïϧ
Ïϧ
ÏϧÏÞßàpublic AnalizadorObjeto(Object o)
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïclase = new Clase(o);
ÏϧÏϨ¹¹Ïcontador++;
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic AnalizadorObjeto( Object o, String alias )
ÏϧÏϧ{
ÏϧÏϨ¹¹Ïthis(o);
ÏϧÏϨ¹¹Ïthis.alias = alias;
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic Clase getClase()
ÏϧÏϧ{
Ïϧ¹Ĺ¹Ïreturn clase;
ÏϧÏÏ©}
Ïϧ
ÏϧÏÞßàpublic String toString()
ÏϧÏϧ{
ÏϧÏϨ¹íÏStringBuffer str = new StringBuffer();
ÏϧÏϧ 
ÏϧÏϨ¹¹Ïstr.append(“\nOBJETO:  alias=”+alias);
ÏϧÏϨ¹¹Ïstr.append(clase.toString());
ÏϧÏϧ 
Ïϧ¹Ĺ¹Ïreturn str.toString();
ÏϧÏÏ©}
Ïϧ
Ïϧ
ÏÏ©}

ÏÕÖ×public class PruebaObjetos
Ïϧ{
ÏϧÏÞßàpublic static void main(String[] args)
ÏϧÏϧ{
ÏϧÏϨ¹íÏClasePrueba una=new ClasePrueba();
ÏϧÏϨ¹íÏOtraClasePrueba dos=new OtraClasePrueba();
ÏϧÏϧ
ÏϧÏϨ¹íÏAnalizadorObjeto uno_=new AnalizadorObjeto(una);
ÏϧÏϨ¹íÏAnalizadorObjeto dos_=new AnalizadorObjeto(dos);
ÏϧÏϧ
ÏϧÏϨ¹¹ÏSystem.out.println(“\n\n”+uno_);
ÏϧÏϨ¹¹ÏSystem.out.println(“\n\n”+dos_);
ÏϧÏϧ
ÏϧÏϨ¹¹ÏSystem.out.println(“\n\n————————\nObjetos analizados: “+dos_.contador+“\n————————”);
ÏϧÏϧ
ÏϧÏϧ
ÏϧÏÏ©}
ÏÏ©}

No hemos puesto los cuadros de ejecución porque son los mismo que la Practica 3.


Respuestas

  1. ¿Habéis pensado en escribir un libro de texto o algo? ;-)


Dejar una respuesta

Su respuesta:

Categorías