Temas:
Motivación
La clase Tiempo permite construir objetos para la manipulación de instantes de tiempo. La clase tiene los siguientes métodos:
Ejemplo | Significado | Declaración |
---|---|---|
Tiempo t= new Tiempo(12,30); | Construye el instante 12h30min | Tiempo(int horas, int min) |
t.escribir(); | Escribe t en la forma hh:mm | void escribir() |
t.sumar(t2); | suma el instante t2 al instante t | void sumar(Tiempo t2) |
if (t.comparar(t2)<0) ... | compara t con t2 entregando -1, 0 o 1 | int comparar(Tiempo t2) |
Esta clase se puede usar para sumar tiempos en horas y minutos. Por ejemplo, si se desea un programa que entable el siguiente diálogo con el usuario:
Horas 1 ? 10
Minutos 1 ? 15
Horas 2 ? 1
Minutos 2 ? 30
Suma= 11:45
Observe que el tiempo t1 fue modificado cuando se le sumó t2.
En cambio t2 no fue alterado.
print("Horas 1 ? ");
int horas1= readInt();
print("Minutos 1 ? ");
int min1= readInt();
Tiempo t1= new Tiempo(horas1, minutos1);
print("Horas 2 ? ");
int horas2= readInt();
print("Minutos 2 ? ");
int min2= readInt();
Tiempo t2= new Tiempo(horas2, minutos2);
t1.sumar(t2);
print("Suma= ");
t1.escribir();
Ejercicio en clases:
Un enfermo debe tomar sus medicamentos a intervalos separados por una hora y 25 minutos a partir de las 8:00 y hasta las 22:00. Escriba un programa que utilice la clase Tiempo para desplegar las horas a las que el enfermo debe tomar sus medicamentos. El programa debe desplegar en pantalla:
8:00
9:25
10:50
...
Solución:
Observación: ¿Por qué sería un error si la última línea fuese
periodo.sumar(t)? ¿O t=t.sumar(periodo)?
Tiempo t= new Tiempo(8,0);
Tiempo tfin= new Tiempo(22,0);
Tiempo periodo= new Tiempo(1,25);
while (t.comparar(tfin)<=0) {
t.imprimir();
t.sumar(periodo);
}
class Tiempo extends Program {
// Variables de instancia
int horas;
int min;
// constructor de instantes de tiempo
Tiempo(int h, int m) {
this.horas= h;
this.min= m;
}
// Métodos para sumar, escribir y comparar
void sumar(Tiempo t2) {
this.horas= this.horas+t2.horas + (this.min+t2.min)/60;
this.min= (this.min+t2.min)%60;
}
void escribir() {
println(this.horas+":"+this.min);
}
int comparar(Tiempo t2) {
int min1= this.horas*60+this.min;
int min2= t2.horas*60+t2.min;
if (min1==min2)
return 0;
if (min1<min2)
return -1;
return 1;
}
}
Explicaciones:Observe que los métodos para sumar, escribir y comparar se ven como funciones o procedimientos. Esto no es coincidencia. Más adelante veremos que en realidad ¡las funciones y procedimientos son métodos!
Al comienzo de la clase se declaran variables que no están dentro de ningún método. Estas variables se denominan variables de instancia.
Si estudia detenidamente el programa se dará cuenta que existe una definición extraña: la del pseudo método Tiempo. Es extraña porque no lleva tipo de retorno y porque lleva el mismo nombre de la clase. No se trata de un error sintáctico. Se trata del constructor de la clase. Este es un método especial, pues nunca se invoca explícitamente, si no que se invoca automáticamente cada vez que se construye un nuevo objeto. En él se inicializan las características del objeto.
Se dice que el objeto construido es una instancia de la clase Tiempo. Una
clase puede tener innumerables instancias de sus objetos. Cada instancia
se representa mediante variables que describen las características de
ese objeto. Estas variables se denominan variables de instancia.
Para la clase Tiempo las variables de instancia son horas y min.
Representaremos un objeto mediante una figura que indique el contenido
de sus variables de instancia:
new Tiempo(1, 25)
Los objetos son referenciados por variables. Para indicar que una determinada variable referencia un objeto se coloca una flecha desde la variable hacia el objeto:
Nunca olvide la metáfora que visualiza los objetos como robots y que las variables almacenan el teléfono celular del robot. Por lo tanto, la flecha indica que la variable periodo contiene el celular del robot al que apunta la flecha.
Cada instancia de la clase Tiempo tiene su propio juego de variables. Si hay tres objetos existirán 3 variables horas y 3 variables min:
En la figura cada objeto es referenciado por alguna variable. Las variables de instancia se crean al construir un objeto con el operador new. Las variables que hemos usado hasta al momento y que se crean al ejecutar funciones, procedimientos o métodos se denominan variables locales, porque ellas son locales a los métodos en donde se definen, o en otras palabras no son visibles desde otros métodos. En cambio las variables de instancia sí son visibles desde cualquier método que tenga una referencia al objeto al que pertencen.
int h= t.horas; // 8
Para cambiar su valor:
Esta asignación sólo modificará la variable horas del objeto referenciado
por t. Los demás objetos no serán modificados:
t.horas= 10;
En la definición de un método se indican las instrucciones que llevan a cabo la acción asociada a ese método.
Un método se invoca por ejemplo mediante:
Lo que hace que se ejecute el código especificado en la definición del
método sumar, de la misma forma como se ejecuta el código de funciones
o procedimientos. En esta invocación diremos que el objeto referenciado
por la variable t es el objeto de la invocación.
t.sumar(periodo);
El enlace que se hace entre argumentos de la invocación y parámetros en la definición del método es el siguiente:
Como en las funciones y procedimientos, los parámetros se inicializan con los valores de los argumentos de la invocación. Pero durante la invocación de un método existe un argumento adicional: el objeto de la invocación. Este objeto es accesible por medio de la variable this, que no es necesario declarar. Ella está siempre presente dentro de la definición de un método.
La siguiente figura muestra el contenido de las variables en tiempo de ejecución, al invocarse el método anterior:
El código del método sumar es:
Observe que dentro del método se obtienen los valores de las variables
de instancia del objeto de la invocación y del objeto referenciado
por t2. Además se modifican las variables del objeto de la invocación,
pero no se alteran las variables de t2. Cuando el método sumar retorna,
estas modificaciones serán apreciables desde la variable t, porque t
referencia el mismo objeto que fue modificado.
void sumar(Tiempo t2) {
this.horas= this.horas+t2.horas + (this.min+t2.min)/60;
this.min= (this.min+t2.min)%60;
}
Estudie cuidadosamente la definición de los métodos comparar y escribir.
Propuesto: definición de la clase Fecha
Defina la clase Fecha que fue presentanda en clases anteriores. Simplifique el problema suponiendo que no hay años bisiestos.