Está en la página 1de 6

Práctica 9-1: Resumen de atributos de encapsulación

En esta práctica, utiliza la función de refactor de NetBeans para encapsular todas las clases en su
aplicación.

Tareas

1. Abra el proyecto 09-EncapConstructors-Practice1.

2. Encapsule la clase Player y asegúrese de que el código en League ahora acceda a la clase
encapsulada correctamente.

a. Haga clic con el botón derecho en Player y seleccione Refactor> Encapsular campos.

b. En el cuadro de diálogo Campos de encapsulación, seleccione playerName como el campo para


encapsular (se seleccionará de manera predeterminada) y marque las casillas para crear el método
getPlayerName y el método setPlayerName. Las opciones deben ser las siguientes (estos son los
valores predeterminados).

Option Choices or Values


Insert Point Default
Sort By Getter / Setter pairs
Javadoc Create default commands
Fields Visibility private
Accessor´s Visibility public

c. Haga clic en Refactor (aceptando las otras opciones).

d. Ejecuta el proyecto unas cuantas veces. Debería correr como antes.

Discusión técnica:

Mira el código de la clase Player. Debería ver que el atributo playerName ahora está marcado
como privado y que se han agregado dos nuevos métodos, getPlayerName y setPlayerName. Pero
si el atributo playerName ahora es privado (no se puede acceder a él de otra forma que no sea la
clase Player), ¿cómo funcionará el método createTeams de la League?

Examina el método createTeams de League. Verá que todo el código en este método que
anteriormente accedió directamente a playerName de Player, ahora lo hace usando el método
setPlayerName. NetBeans no solo puede modificar Player para encapsular sus campos, sino
también cualquier código que use Player para asegurarse de que ahora cumple con la nueva
versión encapsulada de Player.

3. Use la función de refactor de NetBeans para encapsular las clases restantes; Team, Game y
Goal.

a. Como hiciste para la clase Player, encapsula la clase Team. Encapsule ambos campos, creando
métodos setter y getter.
b. Examine la clase Team para ver si los campos se han hecho privados y que se han creado los
métodos de obtención y establecimiento.

c. Prueba que la aplicación se está ejecutando como antes.

d. Encapsula la clase Game. Encapsule los tres campos, creando métodos setter y getter (puede
usar Seleccionar todo para esto).

e. Haga clic en Guardar todo para guardar los cambios.

f. Examine los cambios que se han producido y asegúrese de que la aplicación aún se ejecute
correctamente.

g. Encapsula la clase Goal. Encapsule los tres campos, creando métodos setter y getter (puede usar
Seleccionar todo para esto).

h. Examine los cambios que se han producido y asegúrese de que la aplicación aún se ejecute
correctamente.

Este es el final de esta práctica. Cierre todas las pestañas de NetBeans que contengan código Java.
Práctica 9-2: Agregar constructores

Visión general

En esta práctica, agrega constructores a las clases para que se pueda crear una instancia de los
objetos y para que sus datos se completen en una sola línea.

Tareas

1. Abra el proyecto 09-EncapConstructors-Practice2.

2. Agregue un constructor a la clase de Player que acepte un parámetro String para el nombre del
jugador.

a. Después del atributo playerName, agregue un constructor que devuelva void y acepte un
nombre de parámetro String. (Verás que aparece un error en League. Ignóralo por ahora).

public Player (String playerName) {

b. Agregue una línea a este método de construcción que establece el atributo playerName al String
que se ha pasado. Observe que el nombre del parámetro pasado es el mismo que el nombre del
atributo, pero siga adelante y agregue el siguiente código de todos modos. (Esto causará un
problema más adelante, pero déjalo así por ahora para que veas lo que puede pasar).

playerName = playerName;

3. Arregla los errores que aparecen en la clase League. (La solución podría no ser para la clase de la
League).

a. Examine el método createTeams. Verás algunos errores. ¿Por qué el código ya no funciona?
Después de todo, no eliminó ningún código del Player; solo agregaste un constructor que toma un
parámetro String. Si observa más detenidamente, verá que el problema ahora es la declaración
que crea un nuevo Player.

Discusión técnica:

Como anteriormente no había un constructor explícito en la clase Player, Java asumió que se
requería un constructor predeterminado sin argumentos, y la clase Player se comportó como si
estuviera allí. Es por eso que anteriormente la nueva palabra clave funcionaba correctamente
cuando no se pasaban argumentos.

Sin embargo, ahora que ha agregado un constructor con un parámetro, Java ya no asume que
necesita un constructor predeterminado sin argumentos. Por lo tanto, todo el código que requiere
un constructor sin argumentos falla.
b. Debajo del constructor que acaba de agregar, agregue un constructor explícito sin argumentos a
la clase Player. Puedes hacer esto en una línea.

Jugador público () {}

c. Haga clic en Guardar todo.

d. Examina el método createTeams de League. Verá que ahora no hay problemas y que la
aplicación se ejecuta correctamente.

4. Modifica la clase de League para usar el constructor del Player.

a. Modifique la primera línea del método createTeams para trabajar con el nuevo constructor
parametrizado de Player. La línea actual es:

b. Eliminar la siguiente línea. Ya no debería ser necesario establecer explícitamente el nombre del
jugador.

c. Ejecute la aplicación varias veces y busque a George Eliot para asegurarse de que el nombre del
jugador se está configurando correctamente.

d. ¿Viste a George Eliot como goleador alguna vez? ¿No? ¿Qué hay de nulo? ¿El nombre del
jugador apareció como nulo? Si es así, debe sospechar que hay algún problema con el constructor
que creó.

e. Ir al constructor en Player. Observe que NetBeans ha marcado la línea que establece


playerName con una advertencia. Pase el cursor sobre la línea para ver lo que NetBeans informa.
El valor nunca se usa, porque se asigna a sí mismo. Cualquier uso de playerName dentro del
método constructor significa la variable local del método constructor. Por lo tanto, la referencia de
playerName que se pasa al constructor se asigna a sí misma. ¿Cómo puede asignar este valor al
atributo playerName del objeto que se está ejecutando actualmente?

Necesita una referencia a este objeto: ¿recuerda cuál es la palabra clave? Es this. Así que lo
siguiente funcionará correctamente. Haz esta modificación ahora.

Discusión técnica:

this es una referencia al objeto Player y, por lo tanto, this.playerName se refiere al atributo
playerName del objeto creado por este constructor. playerName se refiere a la variable local
playerName que se pasa al método. Solo dentro del método playerName se refiere a la variable
local. Fuera del método (y, por lo tanto, fuera del alcance de la variable local playerName), el
nombre playerName vuelve al atributo del objeto.

Puede ver esto claramente mirando los métodos de getter and setter (creados automáticamente).
En el método setPlayerName, donde se pasa un parámetro playerName, playerName se convierte
en una variable local y, por lo tanto, el atributo playerName se debe calificar con la referencia this.
Sin embargo, en el método getPlayerName, playerName se refiere al atributo de objeto
playerName.

Tenga en cuenta que también es posible solucionar este problema de alcance asegurándose de
que el nombre del parámetro en la firma del método sea diferente al nombre del atributo.

F. Modifique el resto del método createTeams para que todos los objetos del Player tengan una
instancia del nombre del jugador y elimine todos los métodos setPlayerName (ahora innecesarios).
Observe cómo se acorta y simplifica el código.

g. Prueba para asegurarte de que todo sigue funcionando correctamente.

5. Agregue dos constructores a la clase Equipo: el primero para configurar el nombre del equipo y
el segundo para pasar a la lista de jugadores.

a. Abra la clase Equipo y agregue un constructor que establezca el nombre del Equipo (tal como lo
hizo con Player).

b. Debajo de este constructor, agregue otro constructor que reciba el nombre del equipo y una
matriz de objetos Player.

c. Agregue una línea para establecer el atributo playerArray en la matriz del reproductor que se ha
pasado. Tenga en cuenta que esta palabra clave no es necesaria en este caso, porque los nombres
son diferentes, pero ayudan a la legibilidad.

d. Agregue otra línea para establecer el atributo teamName, pero espere, ¿podría simplemente
llamar al constructor escrito anteriormente? ¡Sí! De nuevo, esto ayuda a garantizar que no haya
duplicación de código y que sea común en los constructores. Observe cómo se realiza la llamada,
de nuevo utilizando esto. Observe también que debe ser la primera línea del constructor.

e. Agregue un constructor predeterminado sin argumentos debajo de este constructor.

f. Modifique el método createTeams de League para que, para el primer equipo (team1), el
nombre del equipo y la matriz player se transfieran al constructor del team. Actualmente el código
se ve así:

g. Quite las siguientes dos líneas, porque ya no son necesarias.

h. team2 se crea de forma un poco diferente, pero, como hay un constructor sin argumentos en
Team, puede dejarlo como está.

i. Pruebe la aplicación para asegurarse de que todavía funciona como antes. Fíjate en lo mucho
más ordenado que está el código para crear team1.
6. Agregue constructores para la clase Game.

a. Agrega un constructor que recibe dos parámetros de Equipo.

b. Modifique el código en el método createGames de League para usar este constructor. Todo el
método ahora será mucho más corto.

c. Ejecute la aplicación para asegurarse de que todavía funciona correctamente.

7. Modifique el método createGames para agregar algunos juegos más a la matriz de Game para
que se jueguen cuatro juegos en total. Como solo hay dos equipos, los equipos jugarán entre sí
cuatro veces.

a. Copia la línea de código que crea una instancia de un nuevo Game. Péguelo inmediatamente
debajo. Verás errores porque theGame ahora se repite.

b. Corrija los errores usando el nombre theGame2 en la nueva línea de código. Además, invierta el
orden de los parámetros para revertir qué equipo está en casa y cuál está ausente.

c. Agrega el nuevo Game a la matriz de Game. El método entero createGames ahora tendrá este
aspecto (con las nuevas líneas y modificaciones que se muestran en negrita):

d. Copia y pega las dos líneas que instancian los objetos de Game y modifica los nombres a
theGame3 y theGame4. Añade estos nuevos juegos a la matriz Game. El método ahora se ve así.

Tenga en cuenta que repetir el código como este no es una buena práctica; Tendría mucho más
sentido utilizar un bucle, y lo hará en la Práctica 11-1.

8. Modifica el método principal de League para jugar todos los juegos.

a. Elimine la línea que actualmente configura currGame y agregue un bucle for alrededor de
currGame.playGame () y la declaración System.out.println para que se jueguen todos los juegos.
Se verá así:

b. Ejecute la aplicación un par de veces. Verás algo como lo siguiente. Cada bloque de código
representa un juego diferente. (¿Qué crees que significa si hay menos de cuatro bloques? ¡La
respuesta está en la siguiente práctica!)

También podría gustarte