Más sobre los objetos (creación de clases propias) Nadjet Bouayad-Agha Programación 2007-2008 La semana pasada • Un objeto de una clase se crea mediante un constructor. Por ejemplo: StringTokenizer st = new StringTokenizer(“Good morning”,” ”); • Un constructor devuelve la referencia de este objeto (i.e., su dirección en memoria). • Esta referencia se almacena en una variable de objeto (st). • Si declaramos una variable de objeto, pero sin asignarle la referencia de un objeto, entonces su valor es null. Por ejemplo: String cadena; int longitud = cadena.length(); Se produce una excepción a la ejecución (NullPointerException). La semana pasada • • • • La API estándar (API = Application Programming Interface) de Java proporciona todo una serie de clases organizadas en paquetes (package) según sus funcionalidades y organizadas entre sí de forma jerárquica. Aparte de java.lang que contiene algunas clases fundamentales (como String o System), para usar una clase de un paquete, lo más fácil es importarlo. Por ejemplo StringTokenizer pertenece al paquete java.util. Entonces, tenemos que declarar al principio de la clase donde lo utilizamos: import java.util.*; La API da la especificación de los datos y métodos disponibles para los objetos de cada clase. La documentación de la API (javadoc) proporciona breves descripciones e información adicional. Podemos usar las clases y métodos de la API de Java (por ejemplo, el método ToUpperCase() de String) sin preocuparnos de su implementación interna. Hoy • • Hasta ahora, una clase se utiliza como un programa para resolver un problema de manera procedural (programación procedural). Hoy, veremos que una clase se utiliza sobre todo para describir un tipo de objeto con datos y comportamiento propio (programación orientada a objetos). Ejemplo Pedir al usuario el nombre y apellido del alumno, su nota final de practica, su nota de examen y si entregó los quizzes, y devuelve la nota total y la apreciación según los criterios de la asignatura de fundamentos de programación (50% practica, 40% examen, 10% quizz, hay que aprobar la practica y el examen para aprobar). Ejemplos de sesiones: > java Nota Nombre: Harry Apellido: Potter Practica: 8.5 Examen: 5 Quizz: no Harry Potter tiene como nota final 6,6 con lo cual tiene un aprobado. Solución procedural 1) 2) 3) 4) Recoger del usuario: nombre, apellido, notaExamen, notaPractica, quizz (“si” o “no”) Calculo de la nota final “Calculo” de la apreciación Impresión del resultado final Solución procedural (1) Programa Nota.java: Un solo main Desventaja: la solución no es muy modular. Solución procedural (2) NotaModular.java: Un método para cada procedimiento: float notaFinal = calcularNotaFinal(notaPractica,notaExamen,quizz); String apreciacion = calcularApreciacion(notaPractica,notaExamen,notaFinal); imprimir(nombre,apellido,notaPractica,notaExamen,notaFinal,apreciacion); Desventaja: métodos con muchos argumentos de entrada Solución procedural (3) NotaModularGlobal.java Los datos están declarados como variables globales (de clase, estáticas): static float notaPractica; Desventaja: no hay control sobre los datos. ¿Como hacer si queremos más de un alumno? Solución basada en objetos: Alumno.java • • • Tenemos un objeto de tipo Alumno. Este alumno tiene como características (datos): nombre, apellido, nota del examen, nota de la practica, si hizo o no los quizzes, nota final y apreciación. Podemos pedirle a este objeto que haga lo siguiente (comportamiento): – Calcular su nota final – “Calcular” su apreciación – Imprimir sus resultados Solución basada en objetos Objeto: (clase Alumno) variable de objeto myAlumno métodos de instancia nombre: apellido: notaExamen: notaPractica: quizz: notaFinal: apreciacion: [ setNotaFinal(), setApreciacion(), imprimir() ] variables de instancia Terminología • Método de clase, variable de clase (o variable global, accesible desde cualquier punto del programa). No pertenece a ningún objeto en particular, es un método procedural. Por ejemplo: TextIO.putln(); Definidos con la palabra clave static (también se llaman método estático y variable estática). • Método de instancia (define el comportamiento de un objeto), variable de instancia (define uno de los datos de un objeto). Por ejemplo: cadena.length(); myAlumno.nombre; Una parentésis: Modificadores de accesibilidad • Podemos esconder los detalles de la implementación (encapsulación) utilizando modificadores de accesibilidad sobre las variables y los métodos de instancia: – – – – public: accesible sin restricciones private: accesible solo dentro de la clase protected: accesible dentro de la clase y de sus subclases sin especificar: accesible dentro de la clase y del paquete de esta clase Ejemplo Alumno más avanzado Student.java y StudentMain.java • Tenemos un constructor con 3 argumentos. A menudo, el constructor sirve para inicializar las variables de instancia a la creación del objeto. • Las variables de instancia no son public. No les asignamos un valor directamente, usamos el constructor y métodos de tipo set. • Tenemos una variable de instancia nacimiento que es de tipo Fecha. Véase Fecha.java. El constructor de esta clase es: Fecha(int d,int m,int a). • El método setNacimiento dentro de Student.java sirve para procesar el String entrado por el usuario y extraer el dia, mes y año de nacimiento que coge el constructor de Fecha. • El método calcularPromedio que calcula la nota final es de uso interno y por eso es private. Es llamado por el método setNotaFinal. Resumen • Hemos aprendido como crear una clase que define un tipo de objeto con sus datos y comportamiento propio. • El comportamiento de cada objeto se describe con los métodos de instancia. • Los datos de un objeto descritos mediante variables de instancia pueden ser de tipo básico o objeto. • Las variables de clase (o estáticas, o globales) son comunes a todos los objetos de la clase. • Los métodos de clase describen código procedural para llevar a cabo una tarea sin consideración de los objetos.