Ir a contenido principal

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. Cierta información de su perfil de developerWorks será mostrada públicamente, pero usted puede editar la información en cualquier momento. Su nombre, apellido (a menos que usted elija ocultarlo) y nombre de usuario acompañarán el contenido que usted publique.

Toda la información enviada es segura.

  • Cerrar [x]

La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

Toda la información enviada es segura.

  • Cerrar [x]

Introducción a la programación Java, parte 2: Construcciones para aplicaciones del mundo real

Funciones más avanzadas del lenguaje Java

J. Steven Perry, Consultor Director, Makoto Consulting Group, Inc.
J. Steven Perry
J. Steven Perry es desarrollador de software, arquitecto y fanático general de Java que ha estado desarrollando software profesionalmente desde 1991. Sus intereses profesionales abarcan desde el funcionamiento interno de la JVM hasta el modelo UML y todo lo que está en el medio. Steve tiene una pasión por escribir y ser mentor. Es el autor de Java Management Extensions (O'Reilly), Log4j (O'Reilly) y los artículos de developerWorks de IBM "Joda-Time" y OpenID for Java Web applications". Pasa tiempo libre con sus tres hijos, anda en bicicleta y enseña yoga.

Resumen:  En la Parte 1 de este tutorial, el programador Java™ profesional J. Steven Perry presentó la sintaxis del lenguaje Java y las bibliotecas que usted necesita para escribir aplicaciones Java simples. La Parte 2, todavía orientada a desarrolladores nuevos en el desarrollo de aplicaciones Java, presenta las construcciones de programación más sofisticadas requeridas para crear complejas aplicaciones Java del mundo real. Los temas que se cubren incluyen manejo de excepciones, herencia y abstracción, expresiones regulares, genéricos, E/S Java y serialización Java.

Ver más contenido de esta serie

Fecha:  10-12-2012
Nivel:  Introductoria PDF:  A4 and Letter (927 KB | 54 páginas)Get Adobe® Reader®

Comentario:  

Pasos siguientes con los objetos

La Parte 1 de este tutorial terminó con un objeto Person que fue razonablemente útil pero no tan útil como podría serlo. Aquí comenzará a aprender sobre las técnicas para mejorar un objeto como Person, comenzando con las siguientes técnicas:

  • Sobrecarga de métodos
  • Alteración temporal de métodos
  • Comparación de un objeto con otro
  • Hacer que su código sea más fácil de depurar

Sobrecarga de métodos

Cuando usted crea dos métodos con el mismo nombre pero con diferentes listas de argumentos (es decir, diferentes números o tipos de parámetros), tiene un método sobrecargado. Los métodos sobrecargados siempre están en la misma clase. Al tiempo de ejecución, el Java Runtime Environment (JRE, también conocido como el tiempo de ejecución Java) decide qué variación de su método sobrecargado llamar en base a los argumentos que se han pasado.

Suponga que Person necesita un par de métodos para imprimir una auditoría de su estado actual. Llamaré a esos métodos printAudit(). Pegue el método sobrecargado en el Listado 1 en la vista de edición de Eclipse:


Listado 1. printAudit(): Un método sobrecargado


public void printAudit(StringBuilder buffer) {
  buffer.append("Name="); buffer.append(getName());
  buffer.append(","); buffer.append("Age="); buffer.append(getAge());
  buffer.append(","); buffer.append("Height="); buffer.append(getHeight());
  buffer.append(","); buffer.append("Weight="); buffer.append(getWeight());
  buffer.append(","); buffer.append("EyeColor="); buffer.append(getEyeColor());
  buffer.append(","); buffer.append("Gender="); buffer.append(getGender());
}
public void printAudit(Logger l) {
  StringBuilder sb = new StringBuilder();
  printAudit(sb);
  l.info(sb.toString());
}

En este caso, usted tiene dos versiones sobrecargadas de printAudit() y en realidad una usa a la otra. Al proveer dos versiones, le da al interlocutor la elección sobre cómo imprimir una auditoría de la clase. Dependiendo de los parámetros que se pasen, el tiempo de ejecución Java llamará el método correcto.

Dos reglas de sobrecarga de métodos

Recuerde estas dos reglas importantes cuando use métodos sobrecargados:

  • No puede sobrecargar un método solo al cambiar su tipo de retorno.
  • No puede tener dos métodos con la misma lista de parámetros.

Si usted viola estas reglas, el compilador le dará un error.


Alteración temporal de métodos

Cuando una subclase de otra clase proporciona su propia implementación de un método definido en una clase padre, eso se llama alteración temporal de un método. Para ver cómo la alteración temporal de métodos es útil, necesita trabajar un poco en su clase Employee. Una vez que la haya establecido, podré mostrarle dónde la alteración temporal de métodos es de ayuda.

Employee: Una subclase de Person

Recuerde de la Parte 1 de este tutorial que Employee puede ser una subclase (o hijo) de Person que tiene algunos atributos adicionales:

  • Número de identificación del contribuyente
  • Número de empleado
  • Fecha de contratación
  • Salario

Para declarar tal clase en un archivo llamado Employee.java, haga clic derecho en el paquete com.makotogroup.intro en Eclipse. Elija New > Class... y se abrirá el recuadro de diálogo de Clase Java nueva, como se muestra en la Ilustración 1:


Ilustración 1. Diálogo Clase Java nueva
New Java Class dialog in Project Explorer.

Escriba Employee como el nombre de la clase y Person como su superclase, luego haga clic en Finish. Verá la clase Employee en una ventana de edición. No necesita explícitamente declarar un constructor pero continúe e implemente ambos constructores de todos modos. Primero, asegúrese de que la ventana de edición de la clase Employee tenga el foco, luego vaya a Source > Generate Constructors from Superclass... y verá un diálogo que se parece a la Ilustración 2:


Ilustración 2. Genere constructores desde el diálogo de superclase
The project path to create a constructor.

Verifique ambos constructores (como se muestra en la Ilustración 2) y haga clic en OK. Eclipse generará los constructores por usted. Ahora debería tener una clase Employee como la del Listado 2:


Listado 2. La nueva y mejorada clase Employee

package com.makotogroup.intro;

public class Employee extends Person {

  public Employee() {
    super();
    // TODO Auto-generated constructor stub
  }

  public Employee(String name, int age, int height, int weight,
                  String eyeColor, String gender) {
    super(name, age, height, weight, eyeColor, gender);
    // TODO Auto-generated constructor stub
  }

}

Employee recibe hereda de Person

Employee hereda los atributos y el comportamiento de su padre, Person, y también tiene algo por su propia cuenta, como puede ver en el Listado 3:


Listado 3. La clase Employee con los atributos de Person

package com.makotogroup.intro;


import java.math.BigDecimal;

public class Employee extends Person {

  private String taxpayerIdentificationNumber;
  private String employeeNumber;
  private BigDecimal salary;

  public Employee() {
    super();
  }
  public String getTaxpayerIdentificationNumber() {
    return taxpayerIdentificationNumber;
  }
  public void setTaxpayerIdentificationNumber(String taxpayerIdentificationNumber) {
    this.taxpayerIdentificationNumber = taxpayerIdentificationNumber;
  }
  // Other getter/setters...
}

Alteración temporal de métodos: printAudit()

Ahora, como prometí, usted está listo para un ejercicio de alteración temporal de métodos. Hará una alteración temporal del método printAudit() (vea el Listado 1) que usó para formatear el estado actual de una instancia de Person. Employee hereda ese comportamiento de Person y si usted crea una instancia de Employee, establece sus atributos e invoca a una de las sobrecargas de printAudit(), la llamada tendrá éxito. Sin embargo, la auditoría que se produce no representará totalmente a una Employee. El problema es que no puede formatear los atributos específicos de una Employee porque Person no los conoce.

La solución es alterar temporalmente la sobrecarga de printAudit() que toma un StringBuilder como un parámetro y agregar códigos para imprimir los atributos específicos de Employee.

Para hacer esto en su IDE Eclipse, vaya a Source > Override/Implement Methods... y verá un recuadro de diálogo que se parece a la Ilustración 3:


Ilustración 3. Diálogo de alteración temporal/implementación de métodos
Override/Implement Methods dialog box.

Seleccione la sobrecarga StringBuilder de printAudit, como se muestra en la Ilustración 3 y haga clic en OK. Eclipse generará el resguardo de método por usted y luego usted puede simplemente rellenar el resto del siguiente modo:

@Override
public void printAudit(StringBuilder buffer) {
  // Call the superclass version of this method first to get its attribute values
  super.printAudit(buffer);
  // Now format this instance's values
  buffer.append("TaxpayerIdentificationNumber=");
    buffer.append(getTaxpayerIdentificationNumber());
  buffer.append(","); buffer.append("EmployeeNumber=");
    buffer.append(getEmployeeNumber());
  buffer.append(","); buffer.append("Salary=");
    buffer.append(getSalary().setScale(2).toPlainString());
}

Observe la llamada a super.printAudit(). Lo que está haciendo aquí es pedirle a la superclase (Person) que exponga su comportamiento para printAudit() y luego usted lo aumenta con el comportamiento de printAudit() de tipo Employee.

La llamada a super.printAudit() no necesita ser la primera; solo pareció una buena idea imprimir primero esos atributos. De hecho, no necesita llamar para nada a super.printAudit(). Si usted no lo llama, debe formatear usted mismo los atributos desde Person (en el método Employee.printAudit()) o excluirlos completamente. Hacer la llamada a super.printAudit(), en este caso, es más fácil.


Miembros de clases

Las variables y los métodos que usted tiene en Person y Employee son variables y métodos de instancia. Para usarlos, usted debe crear instancias de la clase que necesita o tener una referencia a la instancia. Cada instancia de objetos tiene variables y métodos y, para cada uno, el comportamiento exacto (por ejemplo, lo que se genera al llamar a printAudit()) será diferente porque se basa en el estado de la instancia de los objetos.

Las clases mismas también pueden tener variables y métodos, que se llaman miembros de clases. Usted declara miembros de clases con la palabra clave static introducida en la Parte 1 de este tutorial. Las diferencias entre los miembros de clases y los miembros de instancias son las siguientes:

  • Cada instancia de una clase comparte una sola copia de una variable de clase.
  • Puede llamar a los métodos de clases en la clase misma, sin tener una instancia.
  • Los métodos de instancias pueden acceder a las variables de clases pero los métodos de clases no pueden acceder a variables de instancias.
  • Los métodos de clases pueden acceder solo a las variables de clases.

Incorporación de variables y métodos de clases

¿Cuándo tiene sentido agregar variables y métodos de clases? La mejor regla general es hacerlo raras veces, para que no las use excesivamente. Dicho eso, es una buena idea usar variables y métodos de clases:

  • para declarar constantes que cualquier instancia de la clase pueda usar (y cuyo valor esté fijo al momento del desarrollo).
  • para realizar un seguimiento de "contadores" de instancias de la clase.
  • en una clase con métodos de utilidad que nunca necesitan una instancia de la clase (como Logger.getLogger()).

Variables de clases

Para crear una variable de clase, use la palabra clave static cuando la declare:

accessSpecifier static variableName [= initialValue];

Nota: Los corchetes aquí indican que sus contenidos son opcionales. No son parte de la sintaxis de declaración.

El JRE crea espacio en la memoria para almacenar cada una de las variables de instancias de una clase para cada instancia de esa clase. En cambio, el JRE crea sólo una copia de cada variable de clase, a pesar de la cantidad de instancias. Lo hace de eso modo la primera vez que se carga la clase (es decir, la primera vez que encuentra la clase en un programa). Todas las instancias de la clase compartirán esa sola copia de la variable. Eso hace que las variables de clases sean una buena elección para las constantes que todas las instancias deberían poder usar.

Por ejemplo, usted declaró el atributo de Género de Person para que sea una String pero no puso ninguna restricción para ella. El Listado 4 muestra un uso común de las variables de clases:


Listado 4. Uso de variables de clases

public class Person {
//. . .
 public static final String GENDER_MALE = "MALE";
 public static final String GENDER_FEMALE = "FEMALE";
// . . .
 public static void main(String[] args) {
   Person p = new Person("Joe Q Author", 42, 173, 82, "Brown", GENDER_MALE);
 // . . .
 }
//. . .
}

Declaración de constantes

Normalmente, las constantes:

  • se nombran con todas las letras en mayúsculas.
  • se nombran como palabras múltiples, separadas por subrayados.
  • se declaran como finales (para que sus valores no se puedan modificar).
  • se declaran con un especificador de acceso público (para que otras clases que necesitan hacer referencia a sus valores por nombre puedan acceder a ellas).

En el Listado 4, para usar la constante para MALE en la llamada del constructor Person, usted simplemente haría referencia a su nombre. Para usar una constante fuera de la clase, usted la prologaría con el nombre de la clase donde se la declaró, de este modo:

String genderValue = Person.GENDER_MALE;


Métodos de clases

Si usted ha estado siguiendo lo establecido desde la Parte 1, ya ha llamado al método estático Logger.getLogger() varias veces, — cada vez que haya recuperado una instancia de Logger para escribir alguna salida a la consola. Observe de todos modos que usted no necesitaba una instancia de Logger para hacer esto; en cambio, hizo referencia a la clase Logger misma. Esta es la sintaxis para hacer una llamada de método de clase. Como con las variables de clases, la palabra clave static identifica a Logger (en este ejemplo) como un método de clase. Los métodos de clases también se llaman a veces métodos estáticos por este motivo.

Uso de métodos de clases

Ahora combinará lo que ha aprendido sobre variables y métodos estáticos para crear un método estático de Employee. Declarará una variable private static final para tener un Logger, que todas las instancias compartirán y que serán accesibles al llamar a getLogger() en la clase Employee. El Listado 5 muestra cómo:


Listado 5. Creación de un método de clase (o estático)

public class Employee extends Person {
 private static final Logger logger = Logger.getLogger(Employee.class.getName());
//. . .
 public static Logger getLogger() {
   return logger;

 }

}

Están sucediendo dos cosas importantes en el Listado 5:

  • La instancia Logger se declara con acceso private, por lo que ninguna clase fuera de Employee puede acceder a la referencia de forma directa.
  • El Logger se inicializa cuando se carga la clase. Esto sucede porque usted usa la sintaxis del inicializador Java para darle un valor.

Para recuperar el objeto del Logger de la clase Employee, haga la siguiente llamada:

Logger employeeLogger = Employee.getLogger();


Comparación de objetos

El lenguaje Java proporciona dos maneras para comparar objetos:

  • El operador ==
  • El método equals()

Comparación de objetos con ==

La sintaxis == compara objetos por la igualdad para que a == b retorne verdadero solo si a y b tienen el mismo valor. Para los objetos, esto significa que los dos se refieren a la misma instancia de objeto. Para los primitivos, significa que los valores son idénticos. Considere el ejemplo en el Listado 6:


Listado 6. Comparación de objetos con ==

int int1 = 1;
int int2 = 1;
l.info("Q: int1 == int2?           A: " + (int1 == int2));

Integer integer1 = Integer.valueOf(int1);
Integer integer2 = Integer.valueOf(int2);
l.info("Q: Integer1 == Integer2?   A: " + (integer1 == integer2));

integer1 = new Integer(int1);
integer2 = new Integer(int2);
l.info("Q: Integer1 == Integer2?   A: " + (integer1 == integer2));

Employee employee1 = new Employee();
Employee employee2 = new Employee();
l.info("Q: Employee1 == Employee2? A: " + (employee1 == employee2));

Si ejecuta el código del Listado 6 dentro de Eclipse, la salida debería ser:

Apr 19, 2010 5:30:10 AM com.makotogroup.intro.Employee main
INFO: Q: int1 == int2?           A: true
Apr 19, 2010 5:30:10 AM com.makotogroup.intro.Employee main
INFO: Q: Integer1 == Integer2?   A: true
Apr 19, 2010 5:30:10 AM com.makotogroup.intro.Employee main
INFO: Q: Integer1 == Integer2?   A: false
Apr 19, 2010 5:30:10 AM com.makotogroup.intro.Employee main
INFO: Q: Employee1 == Employee2? A: false

En el primer caso del Listado 6, los valores de los primitivos son los mismos, por lo tanto el operador == retorna verdadero. En el segundo caso, los objetos Integer se refieren a la misma instancia, por lo tanto de nuevo == retorna verdadero. En el tercer caso, aun cuando los objetos Integer envuelven el mismo valor, == retorna falso porque integer1 e integer2 se refieren a objetos diferentes. En base a esto, debería estar claro por qué employee1 == employee2 retorna falso.

Comparación de objetos con equals()

equals() es un método que cada objeto del lenguaje Java obtiene gratis porque se define como un método de instancia de java.lang.Object (del que cada objeto Java hereda).

Usted llama equals() exactamente como lo haría con cualquier otro método:

a.equals(b);

Esta sentencia invoca al método equals() del objeto a, pasándole una referencia al objeto b. De modo predeterminado, un programa Java simplemente verificaría para ver que los dos objetos fueran los mismos al usar la sintaxis ==. Sin embargo, debido a que equals() es un método, se puede alterar temporalmente. Considere el ejemplo del Listado 6, modificado en el Listado 7 para comparar los dos objetos que usan equals():


Listado 7. Comparación de objetos con equals()

Logger l = Logger.getLogger(Employee.class.getName());

Integer integer1 = Integer.valueOf(1);
Integer integer2 = Integer.valueOf(1);
l.info("Q: integer1 == integer2?        A: " + (integer1 == integer2));
l.info("Q: integer1.equals(integer2)?   A: " + integer1.equals(integer2));

integer1 = new Integer(integer1);
integer2 = new Integer(integer2);
l.info("Q: integer1 == integer2?        A: " + (integer1 == integer2));
l.info("Q: integer1.equals(integer2)?   A: " + integer1.equals(integer2));

Employee employee1 = new Employee();
Employee employee2 = new Employee();
l.info("Q: employee1 == employee2 ? A: " + (employee1 == employee2));
*l.info("Q: employee1.equals(employee2) ? A : " + 
employee1.equals(employee2));*
Running this code produces:

Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main
INFO: Q: integer1 == integer2?        A: true
Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main
INFO: Q: integer1.equals(integer2)?   A: true
Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main
INFO: Q: integer1 == integer2?        A: false
Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main
INFO: Q: integer1.equals(integer2)?   A: true
Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main
INFO: Q: employee1 == employee2?      A: false
Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main
INFO: Q: employee1.equals(employee2)? A: false

Una observación sobre la comparación de Integers

En el Listado 7, no debería ser una sorpresa que el método equals() del Integer retorne verdadero si == retorna verdadero. Pero observe lo que sucede en el segundo caso, donde usted crea objetos separados que ambos envuelven el valor 1: == retorna falso porque integer1 e integer2 se refieren a diferentes objetos, pero equals() retorna verdadero.

Los escritores del JDK decidieron que para Integer, el significado de equals() sería diferente del predeterminado (que es comparar las referencias del objeto para ver si se refieren al mismo objeto) y, en cambio, retornarían verdadero en casos en los que el valor int subyacente es el mismo.

Para Employee, no alteró temporalmente equals(), por lo tanto el comportamiento predeterminado (de usar ==) retorna lo que usted esperaría, dado que employee1 y employee2 de hecho sí se refieren a objetos diferentes.

Básicamente, esto significa que para cualquier objeto que usted escribe, puede definir lo que equals() significa como adecuado para la aplicación que está escribiendo.

Alteración temporal de equals()

Puede definir lo que equals() significa para los objetos de su aplicación al alterar temporalmente el comportamiento predeterminado de Object.equals(). De nuevo, puede usar Eclipse para hacer esto. Asegúrese de que Employee tenga el foco en la ventana de origen de su IDE Eclipse, luego vaya a Source > Override/Implement Methods. Aparecerá el recuadro de diálogo de la Ilustración 4:


Ilustración 4. Diálogo de alteración temporal/implementación de métodos
The Override/Implement Methods dialog box in Eclipse.

Ha usado este diálogo antes pero, en este caso, usted quiere implementar el método de superclase Object.equals(). Así que, encuentre Object en la lista, verifique el método equals(Object) y haga clic en OK. Eclipse generará el código correcto y lo ubicará en su archivo de origen.

Tiene sentido que los dos objetos Employee sean iguales si los estados de esos objetos son iguales. Es decir, son iguales si sus valores, — apellido, nombre, edad, — son iguales.

Generación automática de equals()

Eclipse puede generar un método equals() por usted en base a las variables de instancias (atributos) que usted ha definido para una clase. Debido a que Employee es una subclase de Person, usted primero generará equals() para Person. En la vista Project Explorer de Eclipse, haga clic derecho en Person y elija Generate hashCode() and equals() para acceder al recuadro de diálogo que se muestra en la Ilustración 5:


Ilustración 5. Diálogo de generación de hashCode() y equals()
The dialog to auto-generate equals()

Seleccione todos los atributos (como se muestra en la Ilustración 5) y haga clic en OK. Eclipse generará un método equals() que se parece al del Listado 8:


Listado 8. Un método equals() generado por Eclipse

@Override
public boolean equals(Object obj) {
 if (this == obj)
   return true;
 if (obj == null)
   return false;
 if (getClass() != obj.getClass())
   return false;
 Person other = (Person) obj;
 if (age != other.age)
  return false;
 if (eyeColor == null) {
   if (other.eyeColor != null)
     return false;
 } else if (!eyeColor.equals(other.eyeColor))
   return false;
 if (gender == null) {
   if (other.gender != null)
     return false;
 } else if (!gender.equals(other.gender))
   return false;
 if (height != other.height)
   return false;
 if (name == null) {
   if (other.name != null)
     return false;
 } else if (!name.equals(other.name))
   return false;
 if (weight != other.weight)
   return false;
 return true;
}

No se preocupe por el hashCode() por ahora, — puede dejarlo o suprimirlo. El método equals() generado por Eclipse parece complicado pero lo que hace es muy simple: si el objeto que pasó es el mismo objeto que el del Listado 8, entonces equals() retornará verdadero. Si el objeto que pasó es nulo, retornará falso.

Luego de eso, el método verifica para ver si los objetos de la Class son los mismos (es decir que el objeto que pasó debe ser un objeto Person). Si eso es verdad, entonces cada valor de atributo del objeto que pasó se verifica para ver si coincide valor por valor con el estado de la instancia de Person dada. Si los valores de los atributos son nulos (es decir, que faltan), entonces el equals() verificará tantos como pueda y, si esos coinciden, los objetos se considerarán iguales. Tal vez no quiera este comportamiento para cada programa pero funciona para la mayoría de los propósitos.

Ejercicio: Genere un equals() para Employee

Intente seguir los pasos en Autogenerating equals() para generar un equals() para Employee. Una vez que tiene su equals() generado, agregue el siguiente código arriba de él:

public static void main(String[] args) {
 Logger l = Logger.getLogger(Employee.class.getName());

 Employee employee1 = new Employee();
 employee1.setName("J Smith");
 Employee employee2 = new Employee();
 employee2.setName("J Smith");
 l.info("Q: employee1 == employee2?      A: " + (employee1 == employee2));
 l.info("Q: employee1.equals(employee2)? A: " + employee1.equals(employee2));
}

Si usted ejecuta el código, debería ver la siguiente salida:

Apr 19, 2010 17:26:50 AM com.makotogroup.intro.Employee main
INFO: Q: employee1 == employee2?      A: false
Apr 19, 2010 17:26:50 AM com.makotogroup.intro.Employee main
INFO: Q: employee1.equals(employee2)? A: true

En este caso, una coincidencia solo en el Nombre fue suficiente para convencer a equals() de que los dos objetos eran iguales. Siéntase libre para agregar más atributos a este ejemplo y vea lo que obtiene.

Ejercicio: Altere temporalmente toString()

¿Recuerda el método printAudit() del comienzo de esta sección? Si pensaba que estaba trabajando bastante duro, ¡tenía razón! Formatear el estado de un objeto en una String es un patrón tan común que los diseñadores del lenguaje Java lo desarrollaron justo en el Object mismo, en un método llamado (no es ninguna sorpresa) toString(). La implementación predeterminada de toString() no es muy útil pero cada objeto tiene una. En este ejercicio, usted hará la toString() predeterminada un poco más útil.

Si sospecha que Eclipse puede generar un método toString() por usted, está en lo correcto. Retroceda en su Project Explorer y haga clic derecho en la clase Employee, luego elija Source > Generate toString().... Verá un recuadro de diálogo similar al de la Ilustración 5. Elija todos los atributos y haga clic en OK. El código generado por Eclipse para Employee se muestra en el Listado 9:


Listado 9. Un método toString() generado por Eclipse

@Override
public String toString() {
 return "Employee [employeeNumber=" + employeeNumber + ", salary=" + salary
 + ", taxpayerIdentificationNumber=" + taxpayerIdentificationNumber
 + "]";
}

El código que Eclipse genera para toString no incluye la toString() de la superclase (al ser la superclase de Employee una Person). Puede arreglar eso en solo un momento, usando Eclipse, con esta alteración temporal:

@Override
public String toString() {
 return super.toString() +
   "Employee [employeeNumber=" + employeeNumber + ", salary=" + salary
   + ", taxpayerIdentificationNumber=" + taxpayerIdentificationNumber
   + "]";
}

La incorporación de toString() hace que printAudit() sea mucho más simple:

@Override
public void printAudit(StringBuilder buffer) {
 buffer.append(toString());
}

toString() ahora hace el trabajo pesado de formatear el estado actual del objeto y usted simplemente coloca lo que retorna en el StringBuilder y regresa.

Recomiendo implementar toString() siempre en sus clases, aunque sea solo por propósitos de soporte. Es prácticamente inevitable que, en algún punto, usted quiera ver cuál es el estado de un objeto mientras su aplicación se está ejecutando y toString() es un gran modo para hacer eso.

2 de 14 | Anterior | Siguiente

Comentario



static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=tecnologia Java
ArticleID=850709
TutorialTitle=Introducción a la programación Java, parte 2: Construcciones para aplicaciones del mundo real
publish-date=12102012
author1-email=steve.perry@makotoconsulting.com
author1-email-cc=