Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos
Repaso de conceptos Clases, objetos, métodos Autor: Andrés Montano Pellegrini Definición de una Clase Simple class Saludos { public Saludos() { } public void saludo() { System.out.println("Hola mundo!"); } } Esto define una clase Saludos con un constructor y un solo método saludo que despliega el mensaje "Hola mundo!". Usando esta definición podemos crear un objeto de la siguiente forma: Saludos x; x = new Saludos(); Podemos mandarle un mensaje de la siguiente forma: x.saludo(); En general todos los métodos llevan la palabra reservada public al principio. Un método simple tiene la estructura: public valor-retorno nombre-metodo () { // cuerpo del metodo } La palabra reservada void es usada con aquellos métodos que no devolverán nada. Definicion de Metodos con Parametros Supongamos que queremos diseñar un método saludo mas genérico, en donde al mandar el mensaje podamos escoger a quien saludar. Esta información adicional, la tendría que incluir el que llama al método como argumento, de la siguiente forma: x.saludo("alumnos") para desplegar "Hola alumnos!". Para poder implementar esto necesitamos incluir parámetros en el encabezado del método, para que el método tenga acceso a esta información. La nueva clase quedaría entonces así: class Saludos { public Saludos() { } public void saludo() { System.out.println("Hola mundo!"); }
http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
1
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos public void saludo(String alguien) { System.out.println("Hola ".concat(alguien).concat("!")); } } Al incluir dos métodos con el mismo nombre, pero diferente firma: public void saludo() public void saludo(String alguien) estamos sobrecargando el método saludo. Por lo tanto cuando el usuario quiere saludar a todo el mundo, hace la llamada: x.saludo(); pero cuando quiere saludar a alguien en especial, hace la llamada: x.saludo("Colegio"); Como podemos saludar a todo el mundo sin especificarlo explícitamente, se dice que el saludo al mundo es el saludo default. Uso de Atributos Supongamos que queramos darle la opción al creador del objeto Saludos que escoja el saludo default, para que no necesariamente sea al "mundo". Esta información debería de ser proveída en el constructor del objeto. Así, con las siguientes instrucciones desplegarían un saludo a la universidad: Saludos x; x = new Saludos("Universidad"); x.saludos(); Para poder implementar esto, debemos de incluir un constructor que reciba una hilera de argumento. Es decir, que se debe incluir un constructor con un parámetro String. Para que tenga el método saludo acceso a la hilera recibida en el constructor, necesitamos almacenarla en un atributo. Esto lo hacemos porque un método no puede acceder a las variables o parámetros de los otros métodos. Los atributos pueden ser accedidos por todos los métodos de dentro de la clase. La declaración de estos es la misma que las variables, con la diferencia que comienzan con la palabra reservada private. La nueva clase quedaría así: class Saludos { private String quien; public Saludos() { quien = "mundo"; } public Saludos(String s) { quien = s; } public void saludo() { System.out.println("Hola ".concat(quien).concat("!")); } public void saludo(String alguien) http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
2
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos { System.out.println("Hola ".concat(alguien).concat("!")); } } Observaciones El orden de declaración entre los atributos y los métodos es irrelevante. Cualquier orden el legal. Como un convenio para la clase, declararemos todas los atributos antes de los métodos. Los miembros (atributos y métodos de la clase) pueden ser públicos, privados o amigables (default). Los miembros públicos (public) pueden ser accedidos por todos. Los miembros amigables (friendly) pueden ser accedidos por miembros del mismo paquete (conjunto de clases). Los miembros privados (private) solo pueden ser accedidos por miembros de la misma clase. Uso de la Definicion de Clase El primer paso que tenemos que hacer es escribir nuestra clase Saludos en un archivo que tiene que llamarse Saludos.java. Como esta clase utiliza el PrintStream, asegúrese de incluir la línea: import java.io.*; Después compilamos este archivo para producir Saludos.class. Una vez hecho esto, ya podemos utilizar nuestra clase en un programa. Por ejemplo, podríamos tener: import java.io.*; class SaludandoUnPoco { public static void main(String args[]) { System.out.println("Saludando un poco a todos!"); Saludos s1, s2; s1 = new Saludos(); s2 = new Saludos("CRUV-FIEC"); s1.saludo(); s2.saludo(); s1.saludo("Suger Montano"); } }Ya el programa SaludandoUnPoco se compila y se corre de la manera usual. Diseño e Implementación de Clases La definición de la clase trabajada anteriormente fue extremadamente casual. Empezamos con una clase muy simple y le fuimos agregando funcionalidad mientras lo íbamos necesitando. Dicho enfoque fue útil para explicar la definición de las clases, pero es poco funcional para escribir clases de alguna significancia. Es como construir una casa, cuarto por cuarto. Necesitamos un enfoque más sistemático. Podemos seguir los siguientes pasos: Diseño de la clase Decida el comportamiento que la clase deberá proveer. Como el comportamiento de un objeto es proveído a través de sus métodos, determine claramente que métodos debe proveer la clase. Determine la interfase de la clase La interfase de la clase es la forma en que podemos usar un objeto de esta clase. En este paso ya es necesario determinar los prototipos de los métodos. Escriba un programa de prueba que utilice la clase. Esta http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
3
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos es una forma de revisar si lo que tenemos hasta ahora tiene sentido. Escriba un esqueleto de la clase. Este es la declaración de la clase con los prototipos de todos los métodos, pero con el cuerpo de los métodos vacío. Implementación de la clase Consiste en escribir los cuerpos de los métodos y declarar los atributos mientras se vayan necesitando. Tenga en mente lo siguiente: Puede empezar a trabajar en cualquiera de los métodos. Puede dejar de trabajar en cualquiera de los métodos antes de completarlo e ir trabajar en otro método. Mejora de la Implementación Por lo general cualquier código escrito, a pesar de que funcione puede ser mejorado. La interfase se debe mantener intacta. Primer Ejemplo Completo: Clase para Entrada/Salida Interactiva (InteractiveIO) Para ilustrar este enfoque de diseño e implementación de clases, vamos a comenzar resolviendo el problema de entrada y salida interactiva. Queremos diseñar una clase que me provea de una manera sencilla de leer y desplegar información. Diseño de la Clase Comportamiento que la clase deberá proveer. Si tuviéramos una clase InteractiveIO quisiéramos que esta me ofreciera el siguiente comportamiento: Escribir a la pantalla, asegurándome que se vaya a desplegar inmediatamente. Preguntar al usuario por información, desplegándole un mensaje y leyendo una hilera del teclado, asegurándome de que el mensaje se despliegue antes de que la computadora espere la entrada. Interfase y Prototipos de los métodos A partir del comportamiento deseado de InteractiveIO, quisiéramos estar en la capacidad de hacer lo siguiente: Declarar una referencia a la clase InteractiveIO de la siguiente forma: InteractiveIO; Esto me dice simplemente que la clase se debe llamar InteractiveIO. Crear objetos que sean instancias de InteractiveIO, sin hacer referencia a System.in o System.out de la siguiente forma: interIO = new InteractiveIO(); De esto podemos deducir que necesitaremos un constructor sin parámetros. Mandar un mensaje al objeto para escribir a pantalla de la siguiente forma: interIO.write("Por favor conteste cada pregunta."); Debemos proveer un método write que reciba una hilera como parámetro, sin devolver nada. Mandar un mensaje al objeto para preguntar una hilera, desplegando una frase descriptiva de lo que queremos leer, de la siguiente forma: String s; s = interIO.promptAndRead("Cual es su nombre?"); Debemos proveer un método promptAndRead que reciba una hilera como parámetro, y que devuelva una hilera. Aquí ya tenemos una idea clara del prototipo de los métodos que incluirá la clase InteractiveIO. Estos son: public InteractiveIO() public void write(String s) public String promptAndRead(String s) http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
4
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos Programa de prueba que utilice la clase. Para usar la clase, el programa de prueba mas simple que podemos escribir es uno que lee una palabra y a continuación la despliega. Si nuestra clase InteractiveIO funcionara como nosotros quisiéramos este quedaría así: import java.io.*; class ProbandoInteractiveIO { public static void main(String args[]) { InteractiveIO interIO; String line; interIO = new InteractiveIO(); line = interIO.promptAndRead("Ingrese una palabra: "); interIO.write(line); } } Concluimos que una clase InteractiveIO diseñada tal y como la tenemos, lleva a cabo bien la tarea. Provee de una entrada y salida interactiva simple, despreocupándonos de System.in, System.out y flush. Esta clase haría todo esto por nosotros. Esqueleto de la clase. class InteractiveIO { // aqui irian los atributos si necesitaramos public InteractiveIO() { // enunciados } /** despliega s*/ public void write(String s) { // enunciados } /** despliega s, lee una hilera del teclado y devuelve una referencia a esta */ public String promptAndRead(String s) { // enunciados } } Implementación de la clase Completamos los métodos de la clase. class InteractiveIO { http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
5
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos // aparentemente no necesitamos atributos public InteractiveIO() { // parece que necesitamos nada! } /** despliega s*/ public void write(String s) { System.out.print(s); System.out.flush(); } /** despliega s, lee una hilera del teclado y devuelve una referencia a esta */ public String promptAndRead(String s) throws Exception { System.out.print(s); System.out.flush(); BufferedReader br = new BufferedRead(new InputSteamReader(System.in)); String line; line = br.readLine(); return line; } } Nota: La palabra reservada return se utiliza para dos operaciones en Java: Para retornar un valor. Su sintaxis es: return expresion; Para forzar la salida de de un método. No se ejecutara ninguna instrucción después del return. Incluso si tengo un método que no retorna ningún valor, pero deseo salirme del método lo puedo hacer mediante el enunciado: return; Mejora de la implementación Observamos que podemos optimizar el programa en los siguientes aspectos: No tiene sentido crear en cada llamada a el método write una instancia del BufferedReader. En vez de esto podemos crearlo una sola vez en el constructor y almacenar una referencia a éste como atributo (para que sea accesible desde el método write). Las primeras instrucciones del método promptAndRead son iguales al las del método write. Podemos ahorrar esta repetición de código llamando al método write desde el método promptAndRead. No necesitamos almacenar la referencia al objeto String en el método promptAndRead. Podemos obviar este paso devolviendo la referencia leída en composición. La nueva implementación de la clase InteractiveIO entonces me queda así: class InteractiveIO { private BufferedReader br; public InteractiveIO() throws Exception { br = new BufferedReader(new InputStreamReader(System.in)); http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
6
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos } /** despliega s*/ public void write(String s) { System.out.print(s); System.out.flush(); } /** despliega s, lee una hilera del teclado y devuelve una referencia a esta */ public String promptAndRead(String s) { this.write(s); return keyb.readLine(); } } Observaciones Aquí trabajamos con tres tipos de variables: Parámetros: son creadas cuando el método al cual pertenecen es invocado. Su valor inicial corresponde a la información enviada como argumento. Son destruidas cuando termina el método. Solo pueden ser accedidas solo por el método al cual pertenecen. Variables Locales: al igual que los parámetros, estas son creadas cuando el método se invoca y destruidas cuando termina el método y solo pueden ser accedidas solo por el método al cual pertenecen. A diferencia de los parámetros estas deben ser inicializadas dentro del método. Atributos: tienen el mismo largo de vida que el objeto al cual pertenecen. Son creadas cuando el objeto es creado y destruidas cuando el objeto es destruido. Pueden ser accedidas por todos los métodos de la misma clase. Se acostumbra a declararlas private, ya que no deberían de poder ser accedidas por métodos de otras clases. Recordemos que cuando mandamos mensajes (a través de llamar a los métodos) necesitamos un receptor de dicho mensaje. En el método promptAndRead cuando invocamos al mensaje write el receptor de este mensaje debe ser el mismo objeto al cual promptAndRead pertenece. Usamos la palabra reservada this para hacer referencia al objeto al cual le pertenece el método. Podemos utilizar también la palabra reservada this para diferenciar entre variables locales y atributos que tengan el mismo nombre. Tarea Agregue un método writeln a la clase InteractiveIO que reciba una hilera de caracteres, que la despliegue y que garantice que el siguiente carácter a desplegarse aparecerá en una nueva línea. Agregue un segundo método writeln (sobrecargado) en la clase InteractiveIO que no reciba argumentos, pero garantice que el siguiente carácter a desplegarse aparecerá en una nueva línea.
http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
7
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos Para parcial #2 Segundo Ejemplo Completo: Clase Nombre Diseñamos la clase InteractiveIO motivados por el deseo de un uso mas conveniente del PrintStream y del BufferedReader. Por lo general nuestro punto de partida no son las clases existentes de Java sino problema de la vida real que deseamos resolver modelándolos de alguna forma. Las clases predefinidas que Java nos provee ni siquiera se acercan a modelar el comportamiento de los elementos de nuestro mundo. El ejemplo que vamos a trabajar ahora es modelar el nombre de una persona. Podemos estar tentados a utilizar la clase String, pero este no nos provee el comportamiento que nosotros quisiéramos de una clase Nombre
Diseño de la Clase Comportamiento que la clase deberá proveer. Si tuviera una clase Nombre quisiera que esta me ofreciera el comportamiento para: Obtener las iniciales como una hilera. Obtener el nombre como una hilera; en el orden apellido, primer nombre Obtener el nombre como una hilera; en el orden primer nombre, apellido Agregar o reemplazar un titulo Interfase y Prototipos de los métodos Apartir del comportamiento deseado de la clase Nombre, quisiéramos estar en la capacidad de hacer lo siguiente: Declarar una referencia a la clase Nombre de la siguiente forma: Nombre alumno;Esto me dice simplemente que la clase se debe llamar Nombre. Crear objetos que sean instancias de Nombre, basados en el primer nombre y el apellido de la siguiente forma: alumno = new Nombre("Juan", "Perez");De esto podemos deducir que necesitaremos un constructor con dos parámetros String. Mandar un mensaje al objeto para obtener las iniciales como una hilera, de la siguiente forma: String s; s = alumno.getInitials();Debemos proveer un método getInitials que devuelva una hilera. Mandar un mensaje al objeto para obtener el nombre completo, en la forma Apellido, primer nombre; como una hilera, de la siguiente forma: String s; s = alumno.getLastFirst();Debemos proveer un método getLastFirst que devuelva una hilera. Mandar un mensaje al objeto para obtener el nombre completo, en la forma primer nombre apellido precedido de un titulo opcional; como una hilera, de la siguiente forma: String s; s = alumno.getFirstLast();Debemos proveer un método getFirstLast que devuelva una hilera. Mandar un mensaje al objeto para agregar o reemplazar el titulo de la siguiente forma: alumno.setTitle("Ingeniero");Debemos proveer un método setTitle que reciba como parámetro una hilera. Aquí ya tenemos una idea clara de el prototipo de los métodos que incluirá la clase Nombre. Estos son: http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
8
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos public Nombre(String pnom, String ap) public String getInitials() public String getLastFirst() public String getFirstLast() public void setTitle(String newTitle)Observe que el constructor no incluye al titulo. Esta fue nuestra opción (como diseñadores de la clase). Nuestro razonamiento fue que: No todos tienen titulo. En contraste con el nombre y apellido el titulo no es permanente, por lo que permitimos que se pudiera agregar un titulo o modificarlo. Programa de prueba que utilice la clase. Para usar la clase, el programa de prueba mas simple que podemos escribir es uno que lea el primer nombre y apellido y el titulo. Después el programa deberá desplegar las iniciales, el nombre completo en la forma apellido, primer nombre, el nombre completo en la forma primer nombre apellido. Una vez tenemos funcionando nuestra clase InteractiveIO la utilizaremos en el programa de prueba. Si nuestra clase Nombre funcionara como nosotros quisiéramos este quedaría así: import java.io.*; class ProbandoNombre { public static void main(String args[]) { Nombre n; String primer, apellido, titulo; InteractiveIO io; io = new InteractiveIO(); primer = io.promptAndRead("Ingrese primer nombre: "); apellido = io.promptAndRead("Ingrese apellido: "); titulo = io.promptAndRead("Ingrese apellido:"); n = new Nombre(primer, apellido); n.setTitle(titulo); io.writeln(n.getInitials()); io.writeln(n.getFirstLast()); io.writeln(n.getLastFirst()); } }Concluimos que una clase Nombre diseñada tal y como la tenemos, lleva a cabo bien la tarea. Provee forma simple de manipular los nombres. Esqueleto de la clase. class Nombre { // aqui van los atributos si las necesitaramos public Nombre(String pnom, String ap) { http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
9
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos // enunciados } public String getInitials() { // enunciados } public String getLastFirst() { // enunciados } public String getFirstLast() { // enunciados } public void setTitle(String newTitle) { // enunciados } } Implementación de la clase Completamos los métodos de la clase. Razonamos que: Los métodos getFirstLast y getLastFirst necesitan ambos acceso al primer nombre y al apellido. De la misma forma getFirstLast y setTitle necesitan ambos acceso el titulo. Por lo tanto, necesitamos hacer del primer nombre, apellido y titulo atributos. Asumiremos que mientras no se especifique un titulo la persona no tiene class Nombre { private String primerNombre, apellido, titulo; public Nombre(String pnom, String ap) { primerNombre = pnom; apellido = ap; titulo = ""; } public String getInitials() { String inicNom, inicAp; inicNom = primerNombre.substring(0,1); inicAp = apellido.substring(0,1); return inicNom.concat(".").concat(apellido).concat("."); } public String getLastFirst() { return apellido.concat(", ").concat(primerNombre); } public String getFirstLast() http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
10
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos { return titulo.concat(" ").concat(primerNombre).concat(" ").concat(apellido); } public void setTitle(String newTitle) { titulo = newTitle; } } Observaciones El objetivo del constructor es garantizar que el objeto comience con valores validos en sus atributos. Dejamos la mejora de la clase a discreción del alumno. Para la clase InteractiveIO, es poco probable que se declaren mas de un objeto de esta clase. Sin embargo, para el caso de la clase Nombre, es muy probable que se declaren muchas instancias de esta clase. Cada una de estas compartirá los mismos métodos pero tendrán su propio conjunto de atributos: primerNombre, apellido y titulo. Esto tiene sentido ya que cada objeto instancia de Nombre tendrá su propio primer nombre, apellido y titulo. A pesar de que todas las instancias de la clase Nombre vayan a tener el mismo comportamiento (proveído por sus métodos), las llamadas devolverán resultados distintos. Esto es porque los atributos tendrán distintos valores. Los valores de sus atributos constituyen su estado. Puedo mandarle un mensaje getLastFirst a dos objetos distintos, y se comportaran igual y pero pueden devolver distinto resultado ya que sus estados son distintos. Ejercicios de clase Escriba un programa que lea tres pares de primer nombre, apellido y a continuación despliegue sus iniciales. El programa deberá usar la clase Nombre. Agregue un método IlustrateName a la clase Nombre que despliegue el nombre a pantalla. Diseñe e implemente una clase NombreLargo, que tome en consideración (además del primer nombre y apellido como lo hizo la clase Nombre) el segundo nombre. Diseñe e implemente una clase Direccion. Diseñando la Salida para los Objetos En el diseño original de la clase Nombre, la clase no leía ni desplegaba objetos Nombre. La entrada y salida era la responsabilidad del usuario de la clase. Algunas veces es deseable que la clase se haga responsable de la entrada y la salida. Para ilustrar como esto se podría implementar le agregaremos este comportamiento a la clase Nombre, comenzando con la salida. Podemos diseñar un método print para la clase nombre que provea el comportamiento de producir como salida el nombre completo. Hay que considerar dos aspectos en este punto: En que forma se debe producir el nombre completo? La salida, hacia donde debería de ir? La primera cuestión, es algo de diseño arbitrariamente podemos escoger producir el nombre completo en el orden titulo primer-nombre apellido. Podemos de una forma arbitraria escoger hacia donde debería ir la salida, ya sea al monitor o a algún archivo en especial. Sin embargo, si nos vamos a tomar la molestia de agregar un método extra a la clase, podríamos diseñarlo para que lo mas general posible sin limitarlo a ninguna salida especifica. Podríamos hacer responsabilidad del que invoca el método, hacia donde debería producirse la salida. Hasta ahora, hemos manejado la salida a través del print y println ha instancias del PrintStream. Como diseñadores de la clase Nombre, podríamos insistir que la salida se maneje a través del PrintStream. http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
11
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos Podríamos pedirle al invocador del método print que incluya como argumento el objeto PrintStream a donde desea que se mande la salida. El método quedaría así: void print (PrintStream destino)De esta manera, si el que llama al método print desea desplegar el nombre a pantalla, en la llamada incluiría como argumento System.out. Por otro lado si desearía mandar el nombre a un archivo incluiría como argumento alguna instancia del FileOutputStream. Un ejemplo de uso podría ser: Nombre n; PrintStream p; n = new Nombre("Jodie","Foster"); n.setTitle("Licenciada"); p = new PrintStream (new FileOutputStream ("actrices.txt")); n.print(System.out); // despliega Licenciada Jodie Foster en la pantalla n.print(p); escribe Licenciada Jodie Foster en el archivoLa implementacion quedaria asi: void print (PrintStream destino) { destino.print(this.getLastFirst()); }Ejercicio de clase: implemente una clase llamada SalidaConBitacora. El constructor recibe un solo argumento: una hilera que representa el nombre de un archivo. La clase debe proveer dos métodos: print y println, ambos de los cuales deben recibir una hilera de argumento. Estos métodos deben mandar la hilera a desplegar a pantalla y a escribirla al archivo. Diseñando la Entrada para los Objetos Desearíamos tener la capacidad de mandarle un mensaje pidiendo que se cree un objeto Nombre desde cierta entrada. Nos topamos con un problema: los mensajes los mandamos a objetos y no tenemos un objeto a quien mandarle el mensaje. De hecho, el envió del mensaje debería de crear el objeto. En realidad no deseamos mandarle el mensaje a un objeto instancia de la clase Nombre, sino a la clase Nombre. Esto en Java se lleva a cabo a través de un tipo de método conocido como método estático. Estos métodos son definidos de la misma forma que los otros métodos, excepto que estos llevan la palabra reservada static antes del tipo de retorno. Los métodos estáticos no están asociados a ningún objeto. Tienen las siguientes características: Deben de ser invocados independientemente de cualquier instancia de la clase. Se utiliza el nombre de la clase como receptor del mensaje. No pueden acceder ningún atributo. Al igual que con el método print nos debemos de preguntar dos cosas: En que forma se debe leer el nombre? La entrada, de donde debería provenir? Requeriremos como diseñadores de la clase, que el primer nombre aparezca en una línea de por si solo y el apellido en la siguiente línea. De nuevo, esta decisión es arbitraria. Además diseñaremos el método de tal forma que la fuente de entrada sea responsabilidad del que invoque el método. Requeriremos que como argumento se pase una referencia a un BufferedReader, de donde será leído el nombre. El prototipo seria así: public static Nombre read(BufferedReader fuente)Podemos utilizar la clase nombre para leer un nombre desde el teclado y desde un archivo de la siguiente forma: http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
12
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos Nombre n; FileInputStream f; BufferedReader brFile, brKeyb; InputStreamReader isrFile, isrKeyb; isrKeyb = new InputStreamReader(System.in) brKeyb = new BufferedReader(isrKeyb); f = new FileInputStream(new File("nombres.txt")); isrFile = new InputStreamReader(f); brFile = new BufferedReader(isrFile); n = Nombre.read(brKeyb); n.print(System.out); n = Nombre.read(brFile); n.print(System.out);La implementacion quedaria asi: public static Nombre read(BufferedReader fuente) { String primer, apellido; primer = fuente.readLine(); apellido = fuente.readLine(); return new Nombre(primer, apellido); }Anteriormente vimos que cuando se esta ingresando la información desde el teclado, es aconsejable desplegar un mensaje para decirle al usuario que información es la que se desea que ingrese. Podemos incluir otro método de entrada readi que utilice la clase InteractiveIO que ya hemos diseñado para llevar a cabo esto. La implementación quedaría así: public static Nombre readi(Interactive io) { String primer, apellido; primer = io.promptAndRead("Ingrese primer nombre:"); apellido = io.promptAndRead("Ingrese apellido:"); return new Nombre(primer, apellido); }Ejercicio de clase: agregue los métodos read, readi y print a las clases que usted desarrollo anteriormente en ejercicios: NombreLargo y Direccion.
Hello world ! Revisitado Con lo que hemos explicado hasta ahora, podemos explicar un poco mas el primer programa que escribimos: import java.io.*; class HelloApp { public static void main (String args[]) { System.out.println ("Hello world !"); } }Vemos que el programa HelloApp es una clase. Toda clase que existe como programa necesita un método main. El método main es static, es decir no esta asociado a ningún objeto HelloApp. La razón de esto es que
http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
13
Centro Regional Universitario de Veraguas Facultad de Informática, Electrónica y Comunicación Programación Orientada a Objetos la ejecución de nuestro programa debe de comenzar en algún lado. El interprete de Java en algún sentido, invoca el método main. Pero esto lo hace antes de que cualquier objeto de nuestro código haya sido creado. Además vemos que esta declarado como public. La razón de esto es que necesita ser llamado desde afuera de la clase (desde el interprete de Java).
http://www.gaugeus.com/ramblings/2006/12/26/definiendo-clases-en-java-class-definition-in-java#Definición_de_Clases
14