Temas:
Resumen de la clase anterior
Los objetos de una misma clase poseen, en general, atributos o propiedades distintas. Esta diferenciación hace que realicen acciones distintas. Por ejemplo, dos colas pueden almacenar elementos distintos y por lo tanto al extraer el primer elemento de ambas colas, se obtendrán valores distintos, aún cuando pertenecen a la misma clase.
Las propiedades de los objetos se almacenan en las variables de instancias. Estas se crean al construir el objeto y se inicializan en el constructor. Las variables de instancia se destruyen junto con el objeto, cuando éste pierde su utilidad.
Al definir una clase es necesario indicar cuales serán las variables de las instancias (i.e. los objetos). Por ejemplo:
Las variables de una instancia se puede obtener o modificar teniendo
una referencia de esa instancia. Por ejemplo:
class Tiempo {
int horas;
int min;
...
}
Al definir una clase también se especifican sus métodos, que son los que
se encargan de manipular las variables de instancia. Los métodos son en
esencia funciones o procedimientos como los que hemos visto hasta ahora.
La diferencia está en que los métodos se invocan adjuntando un objeto que
constituye el objeto de la invocación. Por ejemplo en:
int h= t.horas; // Obtiene el valor de la variable horas
t.min= 15; // Modifica el valor de la variable min
el objeto de la invocación es el objeto referenciado por t.
t.sumar(periodo);
En la definición de un método, el objeto de la invocación es un parámetro implícito, porque no es necesario declararlo. Este parámetro es accesible por medio de la variable this:
class Tiempo {
...
void sumar(Tiempo t2) {
this.horas= ... this.horas ... t2.horas ...
...
}
}
En él, se asignan los valores iniciales para las variables de instancia
this.horas y this.min. Los valores que se le asignan
se reciben como parámetros.
Tiempo(int h, int m) {
this.horas= h;
this.min= m;
}
El siguiente ejemplo permite visualizar mejor los eventos que ocurren las construir un objeto de la clase Tiempo. Supongamos que se ejecuta la siguiente instrucción:
El operador new Tiempo(...) hace que se construya un nuevo objeto
de la clase Tiempo, creando variables de instancia para él. En seguida
se invoca el constructor, asignando a h el primer argumento especificado
(8) y a m el segundo argumento (0). Luego se ejecutan las instrucciones
del constructor.
Tiempo t= new Tiempo(8, 0);
Una vez terminada la ejecución del constructor, el operador new entrega una referencia del objeto recién construido, que finalmente es asignada a la variable t.
Al trabajar con clases de objetos es importante distinguir entre (i) el empleo de una clase y (ii) la definición o implementación de esa clase. Una clase se emplea al resolver otras partes del problema y por lo tanto, sus objetos se manipulan únicamente invocando sus métodos. Nunca se accesan directamente sus variables de instancia, porque éstas son parte de la implementación de la clase. Accesar las variables de instancia al emplear una clase es una violación del principio de abstracción.
En cambio cuando se define la clase, el programador está precisamente resolviendo el subproblema que se ha delegado a esa clase. Y por lo tanto es necesario accesar sus variables de instancia, pero también se pueden invocar su métodos.
Esta forma de trabajar con las clases es importante porque a menudo uno se encuentra con la necesidad de cambiar la representación de los objetos (es decir, cambiar sus variables de instancia) y los algoritmos que se emplean en la clase, sin cambiar la forma en que se emplean estos objetos.
Por ejemplo, otra otra forma de implementar la clase Tiempo consiste en representar el tiempo en términos de minutos (que pueden exceder la hora):
Los programas que emplean esta nueva definición de la clase Tiempo
no necesitan alterarse. Seguirán funcionando correctamente.
class Tiempo {
// Variables de instancia:
int min;
// El constructor:
Tiempo(int h, int m) {
this.min= h*60+m;
}
// Los métodos:
void sumar(Tiempo t2) {
this.min= this.min+t2.min;
}
void imprimir() {
println((this.min/60)+":"(this.min%60));
}
int comparar(Tiempo t2) {
if (this.min<t2.min)
return -1;
if (this.min==t2.min)
return 0;
return 1;
}
}
Ejercicio: Adivina mi número
Se dispone de una clase que juega al adivina mi número. Los objetos de esta clase pueden adivinar el número del usuario, pero no saben dialogar con el usuario. Los objetos poseen los siguientes métodos:
| Ejemplo | Significado | Declaración |
|---|---|---|
| Adivino a= new Adivino(0, 1023); | Construye un adivino | Adivino(int min, int max) |
| int n= a.jugar(); | Juega el número n | int jugar() |
| a.mayor(n); | se le indica que es mayor que n | void mayor(int n) |
| a.menor(n); | se le indica que es menor que n | void menor(int n) |
| int cont= a.intentos(); | entrega cuantos intentos ha hecho | int intentos() |
El ejercicio consiste en emplear esta clase para escribir un programa que entable el siguiente diálogo con el usuario:
Piense un número entre 0 y 1023 y trataré de adivinarlo.
Esta listo ?
Digame si es menor, mayor o igual que 512 ? menor
Digame si es menor, mayor o igual que 200 ? mayor
Digame si es menor, mayor o igual que 400 ? mayor
...
Digame si es menor, mayor o igual que 415 ? igual
Ok, lo adivine en x intentos
Solución:
Al resolver este problema nos hemos abstraído de la parte difícil
que consite en adivinar el número. La inteligencia para adivinar
el número la hemos puesto en el objeto adivino.
println("Piense un número entre 0 y 1023 y trataré de adivinarlo.");
println("Esta listo ? ");
readLine(); // Espera que el usuario ingrese una línea
Adivino adiv= new Adivino(0, 1023);
while(true) {
int n= adiv.jugar();
println("Digame si es menor, mayor o igual que "+n+" ? ");
String resp= readLine();
if (compare(resp, "igual")==0)
break;
if (compare(resp, "menor")==0)
adiv.menor(n);
else
adiv.mayor(n);
}
println("Ok, lo adivine en "+adiv.intentos()+" intentos");
Tarea
Escriba una versión de la clase Adivino que siga una estrategia de juego trivial: juegue sistemáticamente el mínimo valor posible. Cuando se le diga que el número del usuario es mayor que el número jugado, incremente el mínimo en 1.