Anda di halaman 1dari 176

Conceptos de Programacin Orientada a Objetos

Hctor Adolfo Andrade Gmez

2013

Conceptos de Programacin Orientada a Objetos Derechos reservados: 2013, Hctor Adolfo Andrade Gmez Obra registrada ante el Instituto Nacional del Derecho de Autor. Queda prohibida la reproduccin o transmisin total o parcial del contenido de la presente obra en cualesquiera formas, sean electrnicas o mecnicas, sin el consentimiento previo y por escrito del autor.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

TABLA DE CONTENIDO
Introduccin _____________________________________________________________ 6
Objetivo del libro ______________________________________________________________ 7 Mtodo de enseanza. _________________________________________________________ 7 El lenguaje de programacin. ____________________________________________________ 8 Contenido del libro. ____________________________________________________________ 8

1. Conceptos de Programacin _____________________________________________ 10


Computadora. _______________________________________________________________ 10 Lenguajes de Programacin. ____________________________________________________ 13 Paradigmas de Lenguajes de Programacin. _______________________________________ 13 Programacin imperativa. ______________________________________________________ 13 Programacin Lgica __________________________________________________________ 16 Programacin Orientada a Objetos ______________________________________________ 17 Breve Historia de los Lenguajes de Programacin. __________________________________ 19 Resumen del captulo. _________________________________________________________ 19 Ejercicios y preguntas _________________________________________________________ 19

2. Introduccin a la Programacin Orientada a Objetos _________________________ 22


Programacin Orientada a Objetos. ______________________________________________ 22 Programacin Orientada a Objetos vs Programacin Imperativa. ______________________ 23 Abstraccin. _________________________________________________________________ 24 Ejemplo: Clculo de la Nmina de una Empresa. ____________________________________ 24 Clases y Objetos ______________________________________________________________ 25 Creacin de una clase en Java. __________________________________________________ 26 Creacin de objetos. __________________________________________________________ 28 Uso de Paquetes. _____________________________________________________________ 32 Resumen del Captulo. ________________________________________________________ 38 Ejercicios y preguntas. _________________________________________________________ 38

3. Conceptos Bsicos de Programacin Orientada a Objetos _____________________ 42

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

Mtodos y Atributos de Clase. __________________________________________________ 42 Sobrecarga de Constructores ___________________________________________________ 48 Arreglos ____________________________________________________________________ 50 Declaracin y Creacin de arreglos. ______________________________________________ 51 Permisos de Acceso a los Miembros de los Objetos. _________________________________ 57 Setters y Getters _____________________________________________________________ 61 Resumen del Captulo. ________________________________________________________ 67 Ejercicios y preguntas. _________________________________________________________ 67

4. Herencia y Polimorfismo ________________________________________________ 74


Concepto de herencia. _________________________________________________________ 74 La Herencia como mecanismo de reso de cdigo. __________________________________ 76 Permiso de Acceso Protegido ___________________________________________________ 79 Sobre-escritura de Mtodos. ___________________________________________________ 86 Clases Abstractas. ____________________________________________________________ 88 Interfaces. __________________________________________________________________ 94 Polimorfismo _______________________________________________________________ 104 Retorno Covariante __________________________________________________________ 113 Clases Finales _______________________________________________________________ 114 El Ejemplo de la Nmina Revisitado _____________________________________________ 115 Resumen del Captulo ________________________________________________________ 124 Ejercicios y preguntas. ________________________________________________________ 125

5. Excepciones y Flujos Avanzados de Datos _________________________________ 132


Excepciones ________________________________________________________________ 132 Manejo de Excepciones en Java. ________________________________________________ 133 Clusulas Throws y Throw. _________________________________________________ 134 Clusulas try y catch. _____________________________________________________ 135 Otra forma de manejar las Excepciones __________________________________________ 137 Propagacin de Excepciones. __________________________________________________ 141 Finalmente Finally_______________________________________________________ 144 Flujos Avanzados de Datos. ____________________________________________________ 148
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 4

Flujos de Bytes ______________________________________________________________ 149 Flujos de Caracteres. _________________________________________________________ 151 Otros tipos de Flujos._________________________________________________________ 154 Serializacin de Objetos ______________________________________________________ 154 Serializando objetos que hacen referencia a otros objetos. __________________________ 159 El Ejemplo de la Nomina RevisitadoRevisitado ___________________________________ 160 Utilizando Serializacin de Objetos _____________________________________________ 165 Resumen del Captulo ________________________________________________________ 170 Ejercicios y Preguntas. ________________________________________________________ 172

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

Introduccin
La programacin de computadoras consiste en escribir cdigo en algn lenguaje de programacin para que una computadora realice una tarea especfica. Esta actividad es considerada por muchas personas como arte, para otros una ciencia, para otros una mera actividad econmica, para algunos una actividad divertida, un pasatiempo. Sin embargo, para algunos, es una actividad tediosa, aburrida y muy difcil. Algo que es indiscutible, es que el desarrollo de programas (o de software como se le conoce comnmente) es uno de los factores ms importantes en la conformacin de los grandes cambios econmicos, sociales y polticos de los tiempos recientes. Se han creado grandes fortunas. Se han iniciado movimientos sociales, Algunos de estos movimientos han llegado incluso a derrocar gobiernos! Se ha cambiado la forma en la que la gente se entretiene, comunica y aprende. Aunque es cierto que el software no es el nico factor que ha provocado estos cambios, es un hecho que ha jugado un papel muy importante y seguramente lo seguir haciendo en el futuro. Existen varias formas o paradigmas para escribir programas. Una de las ms utilizadas en la industria y en la academia es la Programacin Orientada a Objetos. La intencin de este libro es que el estudiante construya su conocimiento sobre la Programacin Orientada a Objetos sobre bases firmes, haciendo nfasis en los conceptos y no en la sintaxis del lenguaje de programacin. El libro es el producto de ms de 25 aos de experiencia en la enseanza de programacin, en los cuales, el autor ha notado que aunque muchos estudiantes escriben programas que resuelven problemas, no tienen firmes los conceptos de la programacin e incluso no utilizan correctamente las caractersticas de los lenguajes orientados a objetos. Lo anterior provoca que los programas no cumplan con criterios deseables de mantenibilidad, eficiencia y robustez entre otros. Por lo anterior, el enfoque del libro es hacia los conceptos. Pues es mucho ms importante que el estudiante comprenda y utilice adecuadamente los conceptos de la programacin orientada a objetos a que entienda y memorice la sintaxis de un lenguaje o peor an, que memorice soluciones completas a problemas. A quin va dirigido este libro? Este libro est dirigido primordialmente a personas que desean aprender a programar en un lenguaje orientado a objetos. Aunque los conceptos presentados en este libro se aplican al lenguaje Java, muchos de ellos son aplicables tambin a todos los lenguajes orientados a objetos. Requisitos Se asume que el estudiante conoce algn lenguaje de programacin estructurada, como el lenguaje C o Pascal. Aunque no es necesario, es deseable que se tenga experiencia en el

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

desarrollo estructurado de algoritmos pues en este libro no se explica el funcionamiento de las estructuras de control ni la solucin algortmica de problemas. Objetivo del libro Existen varios tipos de habilidades y conocimientos que un programador que utiliza el paradigma orientado a objetos debe tener. Primero, debe saber resolver problemas algortmicamente. Esta habilidad est relacionada con la aplicacin estructuras de datos simples y estructuras de control iterativas, secuenciales, de lectura/escritura, etc. Generalmente existen cursos y libros dedicados al desarrollo de este tipo de habilidades como son: Fundamentos de Programacin, Lenguajes Algortmicos, Introduccin a la Programacin, etc. En este libro, asumimos que el estudiante posee este tipo de conocimientos y habilidades. Adems de lo anterior, el programador orientado a objetos debe poseer un conocimiento firme sobre los conceptos especficos de este tipo de programacin, los cuales son muy diferentes a los de otros paradigmas de programacin. El objetivo de este libro es contribuir a construir el conocimiento de stos conceptos de una manera simple y haciendo nfasis en el porqu fueron incorporados a este paradigma. Otra habilidad necesaria para desarrollar programas orientados a objetos es precisamente la de crear buenos diseos. Es decir, programas mantenibles (fciles de entender y modificar), eficientes (que no desperdicien recursos) y robustos (que funcione adecuadamente en cualquier situacin). Este tipo de habilidades slo se puede desarrollar con la prctica pues cada problema presenta retos y alternativas diferentes y la experiencia es insustituible para lograr esta habilidad. Mtodo de enseanza. Desde el primer captulo se establece que la gran ventaja del paradigma orientado a objetos con respecto a otros paradigmas es que se modela el mundo real y esto se debe precisamente a que el mundo real est compuesto de objetos. Los conceptos que conforman la POO permiten este modelado y es precisamente en los conceptos en los que se hace nfasis en este libro. Cada concepto se presenta mostrando la situacin del mundo real que se trata de modelar y despus se traslada al dominio de la programacin en el cual se formaliza a travs de ejemplo de cdigos y diagramas. En la gran mayora de los conceptos se utilizan ilustraciones simples e informales realizadas a mano pero no por eso menos exactas. Se repite la explicacin de varias formas pues consideramos que muchas veces una sola forma de explicar no es suficiente. Se trata en todos los casos de presentar los conceptos a travs de ejemplos sencillos y relacionados con la vida cotidiana. Se ha tratado de escoger ejemplos lo suficientemente simples para ilustrar los conceptos pero a la vez lo suficientemente completos para abarcar totalmente la idea que se pretende explicar. Los conceptos son presentados de manera informal para tratar de hacer ms interesante la lectura.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 7

Sin embargo, no se cae en la ambigedad ni en la falta de seriedad rigurosa que el tema amerita. No es el objetivo de este libro explicar la teora que subyace el desarrollo de software, ms bien que el estudiante desarrolle la habilidad para analizar, disear y escribir cdigo que resuelva problemas utilizando la programacin orientada a objetos. Tampoco se incluye el diseo estructurado de algoritmos. Se asume que el lector conoce ya los conceptos bsicos de la programacin estructurada: tipos de datos, variables, operaciones aritmticas, asignacin, estructuras de seleccin, estructuras iterativas, etc. El lenguaje de programacin. El lenguaje de programacin utilizado en este libro es Java. Se escogi Java porque es un lenguaje muy poderoso, utilizado extensivamente en la industria y en las universidades. Java permite desarrollar prcticamente cualquier tipo de aplicacin, desde una simple aplicacin para un dispositivo mvil hasta una aplicacin web con cientos o miles de clientes accediendo a ella de manera simultnea. Contenido del libro. El captulo I presenta una breve historia de los lenguajes de programacin, as como conceptos fundamentales como las partes de una computadora, algoritmo, variables y constantes, tipos de datos, instrucciones de entrada/salida y estructuras de control. El captulo II contiene los conceptos fundamentales de la programacin orientada a objetos como son: abstraccin, tipo de dato abstracto, clase, objeto, mtodos, atributos. Tambin presenta el software requerido para realizar los ejercicios propuestos as como los primeros ejemplos de cdigo. El captulo III contiene algunos conceptos adicionales de la programacin orientada a objetos como son: mtodos y atributos de clase, constructores, arreglos y mtodos de acceso a los miembros de los objetos. El captulo IV contiene conceptos avanzados de programacin orientada a objetos como son: herencia, clases abstractas, interfaces, mtodos abstractos, polimorfismo, covarianza, encajonamiento, clases internas, etc. El captulo V contiene conceptos sobre el manejo de excepciones, su creacin, manejo, excepciones que deben ser atrapadas, excepciones cuyo manejo es opcional, manejo de mltiples excepciones. Tambin se presenta en este captulo el manejo de flujos avanzados de datos y cmo se utilizan estos flujos para almacenar informacin de los objetos de manera permanente. Cada captulo presenta una breve introduccin al tema principal y los conceptos bsicos, posteriormente se presenta una serie de ejemplos explicados profusamente y termina con un resumen del captulo. Finalmente, se proponen una serie de preguntas y ejercicios de autoevaluacin.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

El autor espera que este libro sea de utilidad para los estudiantes que empiezan a construir su base de conocimientos en la programacin de computadoras, de manera especfica en la programacin orientada a objetos. La premisa que ha guiado la escritura de este libro es que es mucho ms efectivo adquirir pocos conocimientos de manera slida al inicio que tratar de abarcar muchos conceptos de manera ms ligera. La experiencia del autor como profesor es que la segunda opcin provoca un total rechazo al material por parte de los estudiantes que recin han empezado sus estudios de programacin.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

1. Conceptos de Programacin
Computadora. Empezaremos por definir el concepto fundamental en la programacin que es precisamente el concepto computadora. Una computadora es una mquina capaz de procesar datos y mostrar resultados tiles (informacin) en muy diversas reas del quehacer humano (Figura 1.1). Desde un videojuego hasta el clculo de la trayectoria de un misil, o las estadsticas del censo de un pas, o prcticamente cualquier actividad que requiera algn procesamiento de datos. Adems de lo anterior, en los aos recientes, se ha utilizado tambin como un dispositivo de comunicacin tan verstil que ha generado cambios fundamentales en la forma en que los seres humanos se comunican. La computadora, junto con los avances en las comunicaciones digitales, ha acortado distancias, provocado movimientos sociales masivos, generado las fortunas ms grandes de la historia y muchos otros cambios sociales y econmicos. Muchos autores coinciden en que la poca actual puede ser llamada la era de la informacin, en la cual las computadoras son parte fundamental.

Figura 1.1 Concepto Abstracto de Computadora Teniendo claro ya el concepto de computadora, el siguiente tema importante sera Cmo funciona una computadora? Esta es una pregunta se puede contestar de muchas formas. Una forma posible sera describir los circuitos, dispositivos y dems piezas fsicas que la forman. Otra forma sera describir su funcionamiento desde el punto de vista terico a travs de definiciones matemticas precisas, teoremas y demostraciones. Otra ms, que es la que nosotros usaremos en este libro, es describir el funcionamiento de la computadora desde el punto de vista de un programador que utiliza el paradigma de orientacin a objetos. Esta ltima sera una definicin prctica. Es decir, lo que debemos saber para poder programarla y as resolver los problemas que se presenten.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

10

Podemos ver una computadora como un dispositivo que contiene los siguientes componentes (ver figura 1.2): Una memoria, o almacn de datos, en donde almacenamos informacin sobre los objetos que estamos representando y en la cual podemos aadir, grabar, eliminar y modificar informacin. Por ejemplo, si estamos representando un automvil, podemos almacenar su marca, modelo, nmero de motor, fotografa, nmero de placas, etc. Esta memoria recibe el nombre de memoria heap porque heap es una palabra inglesa que significa montn en espaol y se refiere a la forma en la cual se almacenan los objetos. Los cuales de amontonan sin seguir una secuencia estructurada. Otra memoria que contiene la computadora es una memoria temporal que slo se utiliza al realizar operaciones y que se limpia al terminar de realizar dichas operaciones. Esta memoria recibe el nombre de stack o pila porque los datos almacenados en esta memoria son accedidos en orden inverso al cual fueron introducidos. El funcionamiento de esta memoria simula el de una pila de platos en un restaurante. Los platos que estn accesibles en la parte superior de la pila son los ltimos platos que se introdujeron a la misma. Por ejemplo, si en un programa queremos calcular la antigedad de un automvil, debemos de restar al ao actual el modelo. En java escribiramos la expresin antiguedad = aoActual modelo; Suponiendo que ao actual es 2012 y el modelo es 2009. Entonces, en la memoria de pila almacenaramos el 2012, 2009 y 3 que es el resultado de la resta. No nos preocupemos ahora por el orden en el que dichos datos son introducidos. El valor del modelo del automvil estar duplicado por un momento porque estara en la pila y en el heap. Sin embargo, al terminar de realizarse la operacin, los valores de la pila son borrados. Adems de las dos memorias descritas anteriormente, las computadoras tienen un cerebro llamado CPU (Central Processor Unit) que es el que interpreta las instrucciones y las ejecuta. Generalmente estas instrucciones cambiarn los datos almacenados en las dos primeras memorias mencionadas. Finalmente, tenemos los dispositivos llamados perifricos que son impresoras, discos duros, la pantalla, teclado (tambin llamado consola por razones histricas), ratn, etc. Estos dispositivos nos permiten comunicarnos con la computadora. Por ejemplo, por medio del teclado podemos introducir el modelo del automvil, por medio de la pantalla podemos conocer la antigedad del mismo. El disco duro se le llama tambin memoria secundaria porque tambin almacena informacin pero esta no es directamente accesible para procesarla, es necesaria cargarla primero en cualquiera de las dos memorias mencionadas anteriormente.

La principal razn por la cual son necesarias dos diferentes memorias es que la computadora necesita almacenar la informacin en diferentes formas. Por ejemplo, los objetos tienen muy diversos tamaos y sera imposible almacenarlos en una memoria que tuviera una estructura muy rgida. Por esta razn los objetos se almacenan en la memoria heap. Por otro lado, el stack es necesario porque es muy comn que la informacin deba ser retribuida en orden inverso al que
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 11

fue introducida. Pensemos en que alguien est haciendo una tarea y recibe una llamada telefnica, decide atender la llamada y en esos momentos suena la alarma de la estufa (Suponemos una estufa muy moderna) avisando que la comida est por quemarse. En el stack (memoria) de la persona se introducen los eventos en el orden: tarea, telfono, estufa. Obviamente, el orden en el cual esta persona atiende a cada uno de ellos es inverso al orden en el cual sucedieron: estufa, telfono, tarea. Es decir, primero apaga la estufa, despus sigue atendiendo la llamada (esperamos que la otra persona no haya colgado) y finalmente continua haciendo su tarea. De manera similar, las computadoras deben interrumpir algn proceso o funcin para efectuar otro y deben guardar toda la informacin del proceso para luego continuar con el primero. Sera algo similar a la famosa frase que usamos los humanos En qu estaba? Una vez que se ha completado la tarea, se elimina la informacin de la misma y se contina con la tarea que se estaba realizando. Loa programas se almacenan en otra memoria llamada memoria del programa, la cual es necesaria porque ah se almacenan las instrucciones que se van a realizar. El motivo por el cual esta memoria no fue incluida en la descripcin abstracta de computadora se debe a que no haremos referencia a ella en este libro. Esta es pues la computadora como la veremos en este libro. En realidad, las computadoras son ms complejas y existen an ms componentes. Sin embargo, por ahora con esto nos basta para escribir nuestros primeros programas. En este libro, trabajaremos directamente con la memoria heap, el stack, la pantalla y el teclado. Al final del libro, en el captulo 7, usaremos la memoria secundaria para almacenar informacin. El uso de la impresora, ratn y otros dispositivos perifricos queda fuera del alcance de este libro.

Figura 1.2 Partes de una Computadora para Programacin Orientada a Objetos


Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 12

Hemos visto de manera muy abstracta las partes y el funcionamiento de la computadora. Estudiaremos a continuacin los lenguajes de programacin, sus orgenes y sus caractersticas. Lenguajes de Programacin. Un lenguaje de programacin nos permite comunicarle a la computadora qu debe hacer para resolver un problema. Constan de una serie de reglas gramaticales y smbolos que las computadoras interpretan de manera exacta y sin ambigedades. Los lenguajes de programacin nos permiten escribir programas. Los programas son las series de smbolos escritos siguiendo las reglas gramaticales de los lenguajes de programacin que instruyen a la computadora lo que debe hacer para resolver un problema. Aunque algunos autores mencionan que los programas son series de instrucciones, eso no es enteramente cierto para todos los lenguajes de programacin. Por ejemplo, los programas escritos en el lenguaje PROLOG no consisten de instrucciones (rdenes) sino de definiciones lgicas. Paradigmas de Lenguajes de Programacin. Existen varios tipos, estilos o paradigmas de los lenguajes de programacin: Programacin secuencial o imperativa, concurrente, funcional, orientada a objetos, simblica, orientada a eventos, entre otros. Estos paradigmas o formas de programar producen lenguajes muy diferentes no slo en su sintaxis sino en la forma como el programador ve a la computadora. Por ejemplo, el paradigma orientado a objetos permite al programador concebir a la computadora como fue descrita anteriormente. Sin embargo, utilizando la programacin lgica el programador concibe a la computadora como un razonador lgico capaz de concluir o inferir resultados basados en las definiciones dadas por l. El estudio de los diferentes lenguajes y paradigmas de programacin es muy fascinante pero queda fuera de los alcances de este libro. Para que el lector pueda contrastar tres diferentes paradigmas de programacin, a continuacin presentamos las ideas principales de la Programacin imperativa, de la programacin Lgica y de la programacin orientada a objetos Programacin imperativa. Este paradigma fue el primero que se utiliz porque est estrechamente ligado al funcionamiento real de las computadoras. En este paradigma, se describe el estado de la computadora y el cambio de estado que va sufriendo la mquina a travs de la ejecucin de instrucciones. La computadora slo tiene un rea de memoria en donde se almacenan datos y programas. A este modelo se le llama Mquina de Von Neumann (Ver figura 1.3) Los tipos de datos que pueden almacenarse son simples: enteros, flotantes, caracteres, etc. No existe la posibilidad de almacenar objetos con sus caractersticas (atributos y mtodos). Lenguajes como C, Pascal, Basic pertenecen a este paradigma.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

13

Figura 1.3 Modelo (muy) Abstracto de la Mquina de Von Neumann Entre los conceptos principales que tiene este tipo de programacin se encuentran los siguientes: Tipos de datos. Un tipo de dato define el conjunto de valores posibles que se pueden almacenar en un rea de la memoria. Por ejemplo, enteros, flotantes, caracteres, etc. Variables. Las variables son reas de la memoria representadas por un identificador que pueden almacenar un dato. Por ejemplo, la variable edad podra ser usada en un programa para almacenar la edad de una persona. Normalmente sera una variable de tipo entero. Lo que significa que slo puede almacenar nmeros enteros (dentro de un rango permitido por los lmites fsicos de la memoria). Estructuras de control. Una variante de la programacin imperativa es la programacin estructurada, en la cual los programas se escriben utilizando una serie de estructuras de control que representan el orden en el que se ejecutarn las instrucciones. Existen estructuras de seleccin como el if-then, el if-then-else y estructuras iterativas como el while, do-while y el for. Instrucciones de Entrada/Salida. Para que el programa pueda interactuar con el usuario, son necesarias las instrucciones de entrada/salida, las cuales permiten introducir informacin a la computadora y mostrar informacin en algn dispositivo como la pantalla o la impresora. Constantes. Existen valores que son conocidos y que no cambian bajo ninguna circunstancia. Por ejemplo, la constante (Pi) cuyo valor aproximado es 3.1415926535897932384626433. Este valor puede ser utilizado directamente en un programa para realizar clculos. Funciones. El concepto de funcin en programacin es muy similar al concepto de funcin matemtica. Es un mapeo entre uno o varios valores de entrada llamados argumentos de la funcin y un valor de salida el cual decimos que es el valor que regresa la funcin. As

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

14

si la funcin f(x)=x+2; entonces f(2)=4 y f(5)=7. En este tipo de lenguajes, el programador puede definir funciones y ejecutarlas cuando sea necesario. A continuacin presentamos un programa escrito en lenguaje C (Figura 1.4) que lee un nmero y calcula e imprime su factorial. Recordemos que el factorial de un nmero es la multiplicacin de todos los nmeros enteros entre 1 y el nmero. As, el factorial de 4 es: 1x2x3x4 = 24. La operacin del factorial se representa por el smbolo de admiracin. Entonces 4! = 24.

Figura 1.4 Programa en C que calcula y muestra el factorial de un nmero. Las lneas 1 y 2 incluyen funciones estndar que son necesarias para la entrada y salida de datos las cuales se realizan en las lneas 8,9 y 14. Las lneas 5,6 y 7 declaran variables enteras. Es decir, variables que slo podrn contener nmeros enteros. La lnea 5 no asigna un valor inicial a la variable numero a diferencia de las lneas 6 y 7 las cuales si asignan valores iniciales a las variables i y factorial respectivamente. Esto es debido a que el valor que tomar la variable numero ser dado por el usuario del programa. Para esto se requiere que el programa lea el valor del teclado de la computadora. La instruccin que realiza esa lectura est en la lnea 9. La lnea 10 corresponde a la estructura iterativa while. Esta estructura indica a la computadora que mientras el valor de la variable i sea menor o igual al valor de la variable numero se ejecutarn las instrucciones de las lneas 11 y 12. La lnea 14 muestra en la pantalla el valor del nmero y de su factorial. La lnea 16 hace una pausa en la ejecucin del programa para que el usuario pueda ver el resultado. La ejecucin del programa se muestra en la figura 1.5.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

15

Figura 1.5 Resultado de la ejecucin del programa en C del clculo del factorial de un nmero Programacin Lgica Este tipo de programacin utiliza definiciones matemticas a travs de predicados lgicos. Este paradigma de programacin se le llama declarativa debido a que el programador no especifica de manera procedural (o sea, instruccin por instruccin) el programa, sino que escribe declaraciones a travs de predicados que le permiten razonar a la computadora y obtener un resultado. Utilizando la definicin matemtica del factorial: es realmente muy simple escribir un programa en el lenguaje PROLOG que calcule el factorial de un nmero. En la figura 1.6 de muestra un listado del programa.

Figura 1.6 Programa en PROLOG para el clculo del factorial de un nmero Como puede observarse fcilmente, el programa en PROLOG est basado en la definicin matemtica del factorial. El programador no tiene que preocuparse por escribir estructuras iterativas, ni pensar en el estado de la computadora ni como las instrucciones afectan dicho estado. El programa de la figura 1.6 es bsicamente la misma definicin matemtica que se mostr anteriormente. La lnea 1 representa la lnea superior de la definicin. La lneas 2 a 5 representan la lnea inferior de la definicin. El smbolo :-representa el si de la definicin. No consideramos que sea necesario explicar a detalle todo el cdigo. Tampoco esperamos que el lector comprenda a detalle el cdigo, es suficiente con comprender de manera general que en este tipo de programas, el programador debe especificar la definicin de un problema sin preocuparse por cmo resolverlo. La salida y ejecucin del programa se muestra en la figura 1.7
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 16

Figura 1.7 Resultado de la ejecucin del programa en PROLOG del clculo del factorial de un nmero Programacin Orientada a Objetos En el siguiente captulo hablaremos extensamente de la programacin orientada a objetos. Sin embargo, como una breve introduccin a este paradigma, presentaremos a continuacin el mismo ejemplo del factorial resuelto en el lenguaje Java, el cual es uno de los lenguajes ms representativos del paradigma orientado a objetos. Como ya se mencion anteriormente en este captulo, el programador que utiliza el paradigma orientado a objetos visualiza a la computadora como una mquina capaz de representar internamente objetos con sus propiedades (atributos y mtodos). Los programas orientados a objetos constan de un grupo de objetos que se comunican a travs del paso de mensajes. La figura 1.8 muestra el cdigo en el lenguaje Java que calcula e imprime el factorial de un nmero. No explicaremos a detalle el cdigo pues lo haremos a lo largo del libro. Slo pedimos al lector observar las lneas 21 y 22. La lnea 21 crea un objeto de la clase Calculador. Este objeto sabe cmo calcular un factorial. Cmo lo sabe? Porqu esto fue establecido en las lneas 5-12 del cdigo. Finalmente, la lnea 22 enva un mensaje al objeto c solicitndole que calcule el factorial del nmero ledo. La figura 1.9 muestra el resultado de la ejecucin del programa. Lo primero que salta a la vista del listado del programa en Java es que es ms complicado que los otros dos ejemplos presentados. Entonces Para qu complicarse la vida? Para qu usar Java si usando C (o PROLOG) podramos resolver el problema de manera ms sencilla? La respuesta es que para muchos problemas ms complejos (que son los que probablemente tengamos que resolver en la vida profesional) es ms adecuado este paradigma. Por ahora, el lector tendr que confiar en la palabra del autor. Espero que al final de la lectura del libro quede convencido de las ventajas del paradigma orientado a objetos. El objetivo de presentar este pequeo ejemplo del clculo del factorial de un nmero utilizando tres diferentes paradigmas de programacin es mostrar al lector tres formas completamente diferentes de resolver un problema y como el programador que utiliza PROLOG debe pensar de manera muy diferente al programador que utiliza C o Java. Mientras que la programacin
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 17

imperativa obliga al programador a pensar en una mquina que obedece instrucciones y que va cambiando su estado de acuerdo a la ejecucin de dichas instrucciones, en la programacin lgica, el programador debe pensar en cmo escribir la definicin matemtica y dejar que la mquina utilice esa definicin para encontrar la solucin al problema. Por otro lado, el programador que utiliza la orientacin a objetos resuelve el problema en trminos de los objetos relevantes al mismo problema, sus atributos, sus mtodos y escribe un programa teniendo en mente la interaccin de los mismos.

Figura 1.8 Programa en Java para el clculo del factorial de un nmero Podramos presentar al lector las diversas soluciones del mismo problema utilizando otros paradigmas de programacin pero consideramos que con eso es suficiente para que se tenga una idea general de la existencia de diferentes formas de programar y que cada paradigma obliga al programador a pensar en trminos de la mquina que ejecutar el programa.

Figura 1.9 Resultado de la ejecucin del programa en Java del clculo del factorial de un nmero

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

18

Breve Historia de los Lenguajes de Programacin. La historia de los lenguajes de programacin es muy larga. Algunos consideran que la historia inicia desde la invencin del telar automtico en 1801. Para generar los patrones en las telas, se utilizaron tarjetas perforadas que contenan un cdigo que se puede considerar como un antecesor de los lenguajes de programacin. Sin embargo, los primeros lenguajes que permitan escribir un programa para que fuera ejecutado por una computadora aparecieron a principios de los aos cuarentas. Estos lenguajes estaban completamente ligados a la computadora para la cual se escriba el programa. El programador tena que escribir el programa en trminos de registros, operaciones aritmticas simples, tipos de datos bsicos, etc. Por esta razn, a este tipo de lenguajes se les llama lenguajes de bajo nivel. No fue sino hasta 1955 que se cre el primer lenguaje de alto nivel (o sea que el programador puede escribir su programa en trminos del problema y no de la computadora). Este lenguaje llamado FORTRAN como acrnimo de FORmula TRANslator. Posteriormente se crearon otros lenguajes de ms alto nivel. Como LISP en 1958, COBOL en 1959. El paradigma de la programacin estructurada naci con el lenguaje Pascal creado por Niklaus Wirth publicado en 1970. El lenguaje C fue creado entre 1969 y 1973. A mediados de los setentas se cre Smalltalk el cual sent las bases para el desarrollo de los lenguajes orientados a objetos. El paradigma de la programacin lgica naci con el lenguaje PROLOG en 1972. Aunque se puede decir que la programacin orientada a objetos naci en los setentas con Smalltalk, no fue sino hasta los noventas cuando fue adoptada masivamente por la industria y la academia. En la actualidad existen registrados ms de 2500 lenguajes de programacin! El lector interesado puede conseguir un poster publicado por Oreilly en http://oreilly.com/news/languageposter_0504.html el cual contiene una grfica de tiempo razonablemente completa de los lenguajes de programacin y sus relaciones. Por cierto, Este poster tiene que ser impreso en varias hojas o en un plotter debido a su tamao! Resumen del captulo. En este captulo describimos de manera muy abstracta el concepto de computadora, sus partes y su funcionamiento tambin de manera muy abstracta. Vimos que dependiendo del paradigma de programacin utilizado, el programador conceptualiza a la computadora de manera diferente, en la programacin procedural o imperativa, el programador considera que la mquina tiene cierto estado (dado por los valores almacenados en su memoria) y debe escribir las instrucciones que cambien el estado para resolver el problema. En el paradigma orientado a objetos, el programador considera que la computadora es capaz de representar los objetos con sus mtodos y atributos en su memoria y escribe el programa de tal forma que los objetos reaccionen a travs de envo de mensajes. En la programacin lgica, el programador visualiza a la computadora como un razonador el cual es capaz de resolver un problema dada una defuncin (que el programador provee) a travs de predicados lgicos. Ejercicios y preguntas 1. Mencione la diferencia principal entre el modelo de computadora de Von Newmann presentado en la figura 1.3 y el modelo de computadora de computadora de la figura 1.2 2. Cul es la diferencia entre dato e informacin?
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 19

3. Mencione un ejemplo de la vida cotidiana que sea anlogo al funcionamiento de un stack, es decir que el ltimo evento que sucede, es el primero en ser procesado. 4. Cul es la relacin entre paradigma de programacin, lenguaje de programacin y programa? 5. De los lenguajes de programacin mencionados en este captulo, cul sera el ms conveniente para calcular el rea de un crculo dado su radio? Justifique su respuesta 6. Cul es la diferencia entre un lenguaje de alto nivel y un lenguaje de bajo nivel? 7. Por qu en la abstraccin de computadora para la programacin orientada a objetos son necesarias dos tipos de memorias? 8. Investigue sobre el paradigma de la programacin funcional y compare este paradigma con respecto a los otros paradigmas vistos en este captulo. 9. Considere las siguientes tareas: Anudar los lazos de los zapatos, realizar una divisin aritmtica, manejar una bicicleta y tocar la guitarra. Cules se podran se descritos ms fcilmente de manera procedural ? 11. Complete el siguiente mapa conceptual etiquetando los arcos con las letras correspondientes

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

20

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

21

2. Introduccin a la Programacin Orientada a Objetos


En este captulo veremos los conceptos fundamentales de la programacin orientada a objetos y empezaremos a escribir los primeros programas utilizando Java. El procedimiento para la instalacin de Java, compilacin y ejecucin de programas no se describe aqu. Toda la informacin y software necesario se puede obtener del sitio web de Oracle: www.oracle.com. Programacin Orientada a Objetos. La programacin de computadoras consiste en solucionar un problema a travs de un cdigo escrito en algn lenguaje de programacin. La Programacin Orientada a Objetos (POO) consiste en identificar objetos que sean relevantes para la solucin de un problema y llevar a cabo una representacin de dichos objetos y de sus relaciones en la computadora a travs de un programa. Se trata de modelar el mundo real, o sea el mundo en donde est el problema que se quiere resolver, en la computadora (ver figura 2.1)

Figura 2.1 La programacin orientada a objetos trata de modelar el mundo real El mundo en el que vivimos est lleno de objetos. Hay objetos en todas partes. Algunos son tangibles, otros intangibles pero de cualquier forma los podemos identificar y describir sus caractersticas. Por esta razn, la POO es el paradigma de programacin que de manera ms natural permite que el mundo real sea modelado a travs de la representacin de los objetos Los objetos tienen atributos y mtodos (ver figura 2.2). Los atributos son las caractersticas que tienen los objetos y los mtodos son las funciones que el objeto puede realizar. Por ejemplo, consideremos la representacin del objeto telfono dentro de la computadora. Los atributos del
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 22

telfono podran ser su tamao, color, nivel de carga de la batera, tamao de la pantalla, etc. Los mtodos o funciones del telfono podran ser llamar, colgar, recibir llamada, etc. Es importante sealar el prrafo anterior se utiliza podran varias veces. Esto es porque los objetos, atributos y mtodos que se determinen dependern completamente del problema a resolver. Para un problema determinado podra ser relevante el color del telfono mientras que para otro problema ese atributo sera completamente irrelevante. Por ejemplo, si queremos escribir un programa que permita registrar y controlar la informacin acadmica de los estudiantes de una universidad, los atributos relevantes seran el nombre, matricula, promedio, carrera, etc. Pero si el objetivo del programa es encontrar afinidades para establecer relaciones de amistad o romnticas entonces los atributos relevantes seran otro tipo de datos personales como religin, pasatiempos, tipo de msica que le gusta, etc.

Figura 2.2 Los objetos tienen atributos y mtodos Programacin Orientada a Objetos vs Programacin Imperativa. En la actualidad existe cierta controversia en cuanto a la relacin entre la programacin orientada a objetos y la programacin imperativa. Algunas personas argumentan que en realidad, no hay una gran diferencia excepto por el hecho de que en la programacin orientada a objetos se pueden definir tipos de abstractos de datos (tambin llamadas clases). Otro punto de controversia es sobre qu debe ensearse primero. Algunos profesores de estas materias creen que es mejor ensear primero la lgica de programacin sin considerar objetos, mientras que otros argumentan que es ms conveniente ensear con objetos desde el principio. Algo que vale la pena comentar es que en la programacin imperativa, el programador normalmente est limitado a cierto tipo de datos, como enteros, reales, etc. Algunos lenguajes
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 23

imperativos permiten crear tipos de datos, pero an as estn muy limitados con respecto a lo que se puede hacer con los lenguajes orientados a objetos. En la programacin orientada a objetos, el programador declara sus propios tipos de datos (a los que se les llama tipos de datos abstractos). Por ejemplo, personas, rboles, estudiantes, etc. Estos tipos de datos abstractos no slo contienen datos sino tambin mtodos. Abstraccin. Lo primero que debe realizar un programador para escribir un programa utilizando el paradigma orientado a objetos es un proceso de abstraccin. La abstraccin consiste en eliminar lo que no es importante o relevante para un fin determinado y conservar lo relevante o importante. Como se muestra en la figura 2.3, cada quien extrae de la escena lo que es relevante para l o ella. De manera anloga, el programador debe entender muy bien el problema a resolver e identificar mediante un proceso de abstraccin cuales seran los objetos relevantes que podran utilizarse para resolver un determinado problema. Una vez identificados los objetos, el programador debe establecer cules son las caractersticas (atributos) de los objetos que son relevantes al problema para representarlos en la computadora. Finalmente, tambin debe establecer cules son las funciones (o mtodos) relevantes que cada objeto debe realizar para la solucin al problema.

Figura 2.3 El proceso de Abstraccin Ejemplo: Clculo de la Nmina de una Empresa. Veamos un primer ejemplo: Se desea calcular el pago a un grupo de trabajadores de una empresa. A este tipo de programas se les llama Sistema de Nmina. La gran mayora de las empresas tienen un sistema de nmina que les permite calcular el pago a los trabajadores. Tomaremos este
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 24

ejemplo para explicar varios conceptos importantes de la programacin orientada a objetos y escribiremos cdigo que implementa dichos conceptos. La empresa desea calcular el pago de acuerdo a las horas trabajadas y el salario por hora. El reporte de la nmina deber ser parecido a lo que aparece en la figura 2.4

Figura 2.4 Reporte de la nmina de la empresa Acme Empezaremos por identificar cules seran los objetos del mundo real que sera conveniente representar en la computadora. Obviamente, los objetos ms relevantes para este problema son los trabajadores. Sin embargo, podemos encontrar otros objetos como la propia empresa, el sueldo, el pago, etc. La decisin de que objetos se representarn no es nica para cada problema. Depende de la experiencia, habilidad y sentido comn del programador. Por ejemplo, el salario de los trabajadores lo podramos considerar como un objeto o como un atributo del objeto trabajador. En este ejemplo, tomaremos la segunda opcin. Consideraremos al salario por hora, a las horas trabajadas y al nombre como atributos de cada trabajador. En cuanto a los mtodos, consideraremos slo un mtodo que sera el clculo del pago. Probablemente, el lector pueda pensar que el clculo del pago no debera hacerlo el trabajador. De hecho, en la vida real, sera muy raro que cada trabajador calcule su pago. Pero por conveniencia lo implementaremos de esta forma. Para este ejemplo, empezaremos considerando nicamente al objeto trabajador con sus atributos: nombre, salario por hora y horas trabajadas. El nico mtodo que consideraremos inicialmente es calcular el pago. Ms adelante, mejoraremos el diseo agregando otros objetos. Puede el lector contestar la siguiente pregunta: Por qu no elegimos el pago como atributo del objeto trabajador? La respuesta la encontraremos ms adelante. Clases y Objetos Como se mencion anteriormente, un programa orientado a objetos es un grupo de objetos que interactan envindose mensajes. Como sucede en la vida real, (recuerde el lector que la programacin orientada a objetos trata de modelar el mundo real) para crear un objeto es necesario construir dicho objeto. Para construir los objetos, la programacin orientada a objetos utiliza moldes que reciben el nombre de clases. As, para construir un objeto en el programa necesitamos primero definir su clase. Imagine que los objetos son pasteles y las clases son los moldes en los que se cocinan los pasteles (ver figura 2.5).

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

25

Figura 2.5 Relacin entre Clase y Objeto Existen varias analogas que podemos establecer de la figura 2.5. Veamos la siguiente lista: Con un molde podemos crear varios pasteles, anlogamente, con una clase podemos crear varios objetos. Todos los pasteles que se crearon con el mismo molde tienen la misma forma, anlogamente, todos los objetos de la misma clase tendrn las mismas caractersticas (atributos y mtodos). Aunque dos (o ms) pasteles se creen con el mismo molde, cada pastel ocupa un lugar en el espacio y puede tener diferentes valores en sus atributos. Por ejemplo, cada pastel podra tener diferente sabor (vainilla chocolate). Anlogamente, cada objeto que se cree de la misma clase ocupa su propio espacio en la memoria heap y puede tener diferentes valores en sus atributos. Los moldes tambin pueden tener sus propios atributos (por ejemplo, el material del que estn hechos, sus dimensiones, etc.). Anlogamente, las clases tambin pueden tener sus propios atributos (y mtodos). Creacin de una clase en Java. Para crear una clase en Java, se tiene que escribir en un archivo de texto con la extensin java y definir sus mtodos y sus atributos. La sintaxis (mnima) es la siguiente: class <nombre de la clase> { <definiciones de atributos y mtodos> } Para el ejemplo de la nmina, escribimos el cdigo de la figura 2.6 para definir la clase (molde) del cual podremos construir trabajadores ms adelante en el programa.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

26

Figura 2.6 Definicin en Java de la clase Trabajador Es necesario aclarar varios detalles de la figura 2.6. Primero que nada, es un archivo de texto que puede crearse con cualquier editor de textos. Puede tener cualquier nombre, pero debe tener la extensin java. Es una buena costumbre poner el nombre del archivo igual al nombre de la clase. Por lo que nombraremos a este archivo Trabajador.java. Los nmeros de lneas NO se escriben en el archivo, fueron incluidos para poder hacer referencia a cada lnea del cdigo fcilmente. Empecemos con la lnea 1, en ella declaramos el nombre de la clase Trabajador. Por convencin internacional, el nombre de la clase debe empezar con letra mayscula. Las lneas 2,3 y 4 declaran los atributos con sus tipos de datos de los objetos de la clase Trabajador. Note que el nombre es de tipo String lo que significa que podremos almacenar cualquier caracter en este atributo. Los atributos salarioPorHora y horasTrabajadas son de tipo entero (int) lo que significa que slo podremos almacenar nmeros enteros en ellas. Tambin por convencin internacional, Los nombres de los atributos empiezan con minscula y si tienen varias palabras, cada palabra empieza con mayscula (excepto la primera, la cual comienza con minscula). A esta notacin se le llama notacin camello por las jorobas que se forman al inicio de las palabras (ver figura 2.7).

Figura 2.7 Notacin Camello

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

27

La razn por la que no incluimos el atributo correspondiente al pago semanal es porque puede ser calculado fcilmente multiplicando el salario por hora por las horas trabajadas. Los nombres de las clases de los atributos y los mtodos no pueden llevar espacios. Si se ponen espacios entre ellos, el programa no compilar. La lnea 5 est en blanco. Las lneas en blanco se ignoran. La lnea 6 define el mtodo llamado calculaPago(). Es sumamente importante aclarar varias cosas sobre la definicin de los mtodos. Primero, debemos tener muy claro que los mtodos, como los atributos, tambin tienen asociado un tipo de dato. En este caso, el tipo de datos es int, lo que significa que cada vez que un objeto de la clase Trabajador calcule su pago, la cantidad resultante ser un entero (o sea, no podr contener cifras decimales). Despus del nombre del mtodo siempre se escriben parntesis. En este caso no se escribe nada adentro de los parntesis porque este mtodo no recibe parmetros (ms sobre esto despus). Algo muy importante que el lector debe notar es que los mtodos que regresan valores siempre deben tener una instruccin return (lnea 7). La instruccin return le indica al programa que la ejecucin del mtodo termina y que la expresin que est a la derecha de la palabra return debe ser evaluada (calculada) y el valor resultante es el resultado del llamado del mtodo. En este caso, el objeto multiplica el valor de sus atributos salarioPorHora y horasTrabajadas. Haciendo una analoga con el mundo real, sera como si instruyramos al objeto de la clase trabajador lo siguiente: Cuando te pidan calcular tu pago, multiplica tu sueldo por las horas que trabajaste y el resultado de la multiplicacin es tu respuesta a la solicitud La lnea 8 contiene solamente la llave que cierra, la cual corresponde a la llave que fue abierta en la lnea 6. Los mtodos se delimitan con llaves y las instrucciones que estn adentro de las llaves se ejecutarn cada vez que se ejecute ese mtodo. La lnea 9 cierra la llave abierta en la lnea 1. Creacin de objetos. Hasta ahora, ya creamos la clase (o molde) con la cual podremos crear objetos de la clase trabajador. Todos los trabajadores que se creen van a tener como atributos nombre, salario por hora y horas trabajadas. Tambin van a saber calcular su pago (salario * horasTrabajadas). Ahora completaremos el programa creando una clase llamada Main, la cual contendr un mtodo tambin llamado main el cual crear los tres objetos, asignar valores a los atributos y les enviar sendos mensajes (sendos = a cada uno). La figura 2.7 muestra el cdigo de la clase Main completo. Antes de empezar con el desglose lnea por lnea de la clase Main, necesitamos entender porqu creamos la clase Main si no existe ningn objeto de esa clase en el mundo real. La razn es la siguiente: Los programas orientados a objetos se basan en la creacin de objetos y en el paso de mensajes entre ellos. Sin embargo, para que puedan existir esos objetos, alguien los tiene que crear y empezar el proceso de envo de mensajes. Ese precisamente es el objetivo de la clase Main. Ahora... Por qu se llama Main?... Por razones histricas. La sintaxis de Java est basada en gran medida en el lenguaje C++, el cual llama a su mtodo inicial main (que por cierto

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

28

significa principal en espaol). Aunque podemos utilizar cualquier otro nombre para esta clase, se acostumbra ponerle Main a la clase porque el mtodo de esa clase que se ejecuta al principio se llama main y ese nombre si es obligatorio! Empecemos ahora a desglosar el cdigo de la figura 2.7. La lnea 1 define el nombre de la clase, la lnea 2 define el mtodo main. Note por favor que el mtodo main debe tener las palabras: public, static y void. La razn de las dos primeras la veremos ms adelante, la razn de la tercera (void) es porque este mtodo no regresa ningn valor. Los mtodos que no regresan ningn valor no requieren del uso de la palabra return como vimos anteriormente. Todo lo que est adentro de los parntesis (String[] args) indica el tipo de parmetros que este mtodo recibir. Por lo pronto, tendremos que aprendernos de memoria la lnea 2 y la usaremos tal cual en todos los programas de este libro. Ms adelante veremos la razn para cada una de sus partes.

Figura 2.7 Cdigo de la clase Main para el clculo de la Nmina

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

29

La lnea 3 es muy importante y debemos entenderla por completo. Lo primero que se hace es declarar la variable trab1 de tipo Trabajador. Esto significa que la variable trab1 slo podr almacenar objetos de la clase Trabajador (no enteros, no reales, no cadenas, slo trabajadores). A la derecha del smbolo = tiene la instruccin: new Trabajador(). Esta instruccin provoca que se cree un trabajador en la memoria heap (ver figura 1.2). A partir de la lnea 3, podemos decir que ya hemos creado un objeto y que este objeto reside en la memoria heap. Sin embargo, este objeto creado no tiene ni nombre, ni salario por hora, ni horas trabajadas. Precisamente de esa asignacin de valores se encargan las lneas 4,5 y 6. Observe que para hacer referencia a un atributo de un objeto, se utiliza un punto. De esta forma trab1.nombre hace referencia al atributo nombre del objeto que est almacenado en la variable trab1.Las lneas 7 a la 14 hacen algo similar pero con los otros dos objetos que deseamos crear. De esta forma, el estado de la computadora despus de haber ejecutado la lnea 14 se representa en la figura 2.8.

Figura 2.8 Estado de la computadora despus de haber creado los tres objetos y asignado los valores de sus atributos. En la figura 2.8, podemos observar que despus de haber ejecutado la lnea 14, ya existen tres objetos creados en la memoria heap. Existen tres variables locales en el stack (trab1, trab2 y trab3) y cada de una de esas variables locales apunta a cada uno de los objetos creados. Por el momento, no es necesario entender a fondo como funciona a detalle el concepto de apuntador. Ms adelante en el libro veremos con mucho mayor grado de detalle cmo una variable apunta a un objeto creado en la memoria heap. Por ahora, lo nico que debe quedar claro es que

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

30

podemos referenciar (o sea, asignar o leer valores) de los atributos de los objetos a travs del nombre de la variable, seguida de un punto, seguido del nombre del atributo. Las lneas 19 a 21 provocan que se muestre en la pantalla toda la cadena que escriba entre comillas. Los espacios, los tabuladores (\t), etc. La lnea 19 es una continuacin de la lnea 18. En Java, las cadenas de caracteres (o Strings) se pueden concatenar con el operados +. Los Strings siempre se escriben entre comillas. Entonces, lo que hace la lnea 19 es concatenar el String que se empez en la 18 con el String de la lnea 19. Adems, en Java podemos separar las lneas de programacin sin ningn problema. Esto le puede agregar mayor claridad y elegancia al programa. La lnea 22 es sumamente importante y es necesario que la desglosemos minuciosamente. Es fundamental que no se contine con la lectura si no se ha entendido completamente lo que pasa al ejecutarse esta lnea. Al ejecutarse int pago1 = trab1.calculaPago()primeramente se declara que la variable pago1 es entera, como hemos mencionado anteriormente, esto significa que slo podr contener valores enteros. A la derecha del smbolo igual, se est enviando un mensaje al objeto contenido en la variable trab1. Este mensaje le solicita al objeto que ejecute su mtodo calculaPago(). Note que es muy importante que el tipo de dato de la variable pago1 coincida con el tipo de dato del mtodo calculaPago() pues el resultado del clculo del pago ser asignado a la variable pago1. Imagnese que usted le pregunta a un obrero: Cunto te debo pagar esta semana? Obviamente, usted espera un nmero!, no sera lgico que el obrero le contestara: Departamento de Produccin. Por eso es muy importante que los mtodos definan el tipo de valor que regresarn. En el caso de los trabajadores, esto se efecta en la lnea 6 de la figura 2.6. Cuando se ejecuta la instruccin: trab1.calculaPago(), se pasa el control del programa al objeto trab1, el cual, realiza la multiplicacin de los valores de su salario por hora y sus horas trabajadas y regresa el valor calculado para que sea asignado a la variable pago1. Eso ya lo debemos tener bien claro, pero De dnde obtiene los valores de sus atributos (horas trabajadas y salario diario)? Podra el lector decir en qu lneas se asignan estos valores? Exactamente, en las lneas 5 y 6 de la figura 2.6. De esta forma, cuando a un objeto se le asignan valores a sus atributos, stos se conservarn por todo el programa, a menos que nosotros destruyamos el objeto (ms sobre ese tema despus) de manera explcita o implcita. La lneas 23 y 24 muestran en la pantalla, los datos para el pago del primer trabajador. Las lneas restantes muestran los datos del pago de los otros trabajadores. El resultado de la ejecucin del programa se muestra en la figura 2.9

Figura 2.9 Resultado de la ejecucin del programa de la figura 2.7


Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 31

En este momento es muy importante que el lector haya compilado y ejecutado el ejemplo. En caso de que no lo haya hecho, le sugerimos enormemente que lo haga pues la nica forma de aprender a programar es escribiendo la mayor cantidad de programas. Existe una cantidad tan grande de detalles que suceden cuando se escribe un programa, que resulta prcticamente imposible enumerarlos todos. Por esta razn, es muy importante que el lector compile y ejecute todos los ejemplos presentados en este libro. Uso de Paquetes. El programa presentado en la seccin anterior consta de dos clases: La clase Trabajador y la clase Main. Estas dos clases deben de residir en el mismo directorio, de otra forma, el programa no compilar pues la clase Main hace referencia a la clase Trabajador y slo las clases que estn en el mismo directorio pueden ser vistas por otras clases. Esto obligara a los programadores a crear todas las clases en el mismo directorio. La siguiente lista enumera los problemas que esta restriccin trae en el desarrollo de un programa no trivial: Los programas quedan mal estructurados pues todas las clases deben estar en el mismo directorio, an si no estn relacionadas. En el desarrollo de programas complejos, es probable que varios programadores colaboren en el mismo proyecto. Esto genera la posibilidad de que haya duplicidad en el nombre de las clases. Si no se utilizan paquetes, es imposible manejar este conflicto. Todas las clases pueden acceder a todos los atributos de las otras clases. Esto es indeseable y potencialmente peligroso (ms sobre eso despus) Java utiliza paquetes para eliminar los problemas mencionados en la lista de arriba. Un paquete es simplemente un directorio o folder en el cual se agrupan las clases que estn relacionadas. Al usar paquetes, un programador puede colocar las clases relacionadas en cierto paquete e importarlas para uso en otros paquetes. Por ejemplo, supongamos que tenemos pensado que el programa de nmina que hemos desarrollado sufrir cambios en el futuro (lo cual es bastante probable) para acomodar nuevas necesidades de la empresa, como son: Incorporacin de nuevos tipos de trabajadores Conexin a una sucursal remota para el clculo del pago de los trabajadores de esa sucursal Conexin a las computadoras del gobierno para el envo de declaraciones de impuestos en formato electrnico Interface visual con los usuarios Etc. Como puede el lector imaginarse, estos cambios harn que el nmero de clases requeridas por el programa crezca de manera importante y es evidente que ser necesaria la agrupacin de estas clases en paquetes. Por lo pronto, crearemos dos paquetes. Un paquete que llamaremos
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 32

nomina porque en este paquete colocaremos las clases relativas a la nmina (note que eliminamos el acento en la palabra nmina para evitar algn problema con el sistema operativo en el que se ejecute el programa). La nica clase que colocaremos por ahora en este paquete es la clase Trabajador. El otro paquete que crearemos, agrupar las clases que no pertenecen estrictamente al dominio de la nmina, pero que son necesarias para la ejecucin del programa. En este caso, la clase Main. Llamaremos a este paquete etc (por etctera). La figura 2.10 muestra las clases y los paquetes a los que pertenecen. A este tipo de diagramas se les llama Diagrama de Clases. Veamos varios puntos interesantes del diagrama. Lo primero que observamos es que los paquetes se representan como carpetas o folders y las clases se representan con un rectngulo. Esta notacin se utiliza en UML (Unified Modeling Language) o Lenguaje Unificado de Modelado. Este lenguaje, utilizado extensivamente en la industria y en la academia, permite representar procesos y sistemas. Es un lenguaje muy extenso que incluye muchos smbolos y tipos de diagramas. La figura 2.10 presenta un Diagrama de Clases. Este tipo de diagramas permiten representar las clases, con sus atributos y mtodos y los paquetes a los cuales pertenecen.

Figura 2.10 Diagrama de Clases del Programa de Nmina La siguiente lista contiene los puntos ms relevantes del Diagrama de Clases: Los paquetes se representan por carpetas (folders) Las clases se representan por rectngulos La parte superior del rectngulo de la clase contiene el nombre de la clase La parte de en medio del rectngulo de la clase contiene los atributos de los objetos de esa clase.
Hctor A. Andrade G. 33

Conceptos de Programacin Orientada a Objetos

La parte inferior del rectngulo de la clase contiene los mtodos de los objetos de esa clase. El smbolo se utiliza para indicar que la clase pertenece al paquete. Aunque tambin se puede dibujar la clase adentro del paquete. Los mtodos estticos se representan con las letras subrayadas. En este caso, el mtodo main() de las clase Main es esttico y por eso se escribe con letras subrayadas. Seguramente, el lector se estar preguntando Qu es un mtodo esttico? Lo veremos un poco ms adelante en este captulo. Regresemos ahora a cdigo en Java que implementa el diagrama de la figura 2.10. Lo primero que debemos hacer es crear dos subdirectorios: nomina y etc los cuales estarn situados abajo del directorio ejemploNomina. Posteriormente colocaremos los archivos Trabajador.java y Main.java en los directorios correspondientes. La figura 2.11 muestra la estructura de los directorios y los archivos.

Figura 2.11 Directorios correspondientes a los paquetes de la figura 2.11 Los cambios que debemos hacer a los programas que habamos mostrado anteriormente son mnimos. Las figuras 2.12 y 2.13 muestran los listados completos de ambos archivos.

Figura 2.12 Cdigo de la clase Trabajador incluida en el paquete nomina del Programa de nmina La figura 2.12 muestra el cdigo de la clase Trabajador. Hemos realizado slo dos cambios con respecto al cdigo de la figura 2.6. El primer cambio se observa en la primera lnea, en la cual se incluy la declaracin del paquete. Para declarar que una clase est incluida en un paquete es necesario escribir al principio del archivo la palabra package seguida del nombre del paquete. As, package nomina; en la primera lnea del archivo Trabajador.java indica que la clase
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 34

Trabajador pertenece al paquete nomina. El segundo cambio es en la lnea 3. En esa lnea se agreg la palabra public a la declaracin de la clase. Este segundo cambio es necesario porque la clase Trabajador es utilizada en otro clase (Main) que no est en el mismo paquete. Como regla general, podemos decir que si deseamos utilizar una clase en otro paquete, esta clase deber ser pblica. La figura 2.13 muestra el cdigo de la clase Main que se encuentra en el paquete etc. Como puede observarse, se agregaron dos lneas con respecto al cdigo de la figura 2.7. Agregamos la declaracin del paquete en la lnea 1 y adems importamos la clase Trabajador en la lnea 2. Esto ltimo requiere una explicacin ms detallada. En ocasiones, deseamos utilizar una clase que no se encuentra en el mismo paquete que la clase que estamos escribiendo. En nuestro ejemplo, la clase Trabajador no est en el mismo paquete que la clase Main. En este caso, la clase que desea utilizar una clase de otro paquete, debe incluir en su cdigo la instruccin import, La lnea: import nomina.Trabajador; le indica a la computadora que la clase Main desea utilizar la clase Trabajador, la cual se encuentra en el paquete nomina. Observe que se utiliza un punto para separar el paquete del nombre de la clase. La compilacin y ejecucin de este programa se realiza desde el directorio ejemploNomina. Como puede verse en la figura 2.14, tanto para la compilacin, como para la ejecucin, se utiliza el nombre completo de la clase, es decir, el paquete al que pertenece y el nombre de la clase. Observe tambin que no es necesario compilar la clase Trabajador.java. Slo de compila el cdigo de la clase Main.java y como este cdigo hace referencia a la clase Trabajador, el compilador busca a esta clase en el paquete correspondiente y realiza la compilacin de manera automtica.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

35

Figura 2.13 Cdigo de la clase Main incluida en el paquete etc del Programa de Nmina

Figura 2.14 Resultado de la compilacin y ejecucin del programa de nmina. El uso de paquetes permite estructurar los programas complejos de tal forma que las clases que estn relacionadas puedan ser agrupadas en un paquete. Por ejemplo, si un programador desea utilizar interfaces grficas en sus programas (ventanas, mens, cuadros de textos, etc.) Puede
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 36

incorporar a su programa las clases que estn en ese paquete. Pero si adems desea que su programa se conecte a una red, podra incorporar al programa el paquete que contiene las clases necesarias para la conexin a redes. De igual forma podramos incorporar (importar) clases para el manejo de archivos, impresoras, pginas web, etc. Adems de lo anterior, el uso de paquetes permite que grupos de programadores escriban programas sin tener que preocuparse por el nombre que le den a las clases siempre y cuando no nombren igual a los paquetes. Por ejemplo, supongamos que un programador de una compaa que desarrolla videojuegos est escribiendo las clases para la creacin de naves. Decide entonces nombrar a su paquete naves. Dentro del paquete naves, decide crear una clase Casco (para crear los cascos de los barcos). Otro programador de la misma compaa, es el encargado de crear las clases necesarias para los personajes del videojuego decide crear un paquete que contenga todas las clases para la creacin de los soldados del videojuego. A este paquete le llama soldados. Dentro del paquete soldados coloca la clase Casco para referirse a los cascos de los soldados. Como puede verse, cada uno de los programadores han creado una clase llamada Casco. Aunque se llaman igual, ambas clases corresponden a objetos muy distintos y se encuentran en diferente paquete. En el caso que se requiera el uso de ambas clases en un programa, se debern referenciar con el nombre completo del paquete y la clase. Para este ejemplo, las clases para el casco del barco y el casco del soldado se haran referencia con los nombres: naves.Casco y soldados.Casco respectivamente. La figura 2.15 muestra el cdigo de la clase Videojuego que utiliza ambas clases.

Figura 2.15 Cdigo de la clase Videojuego que utiliza dos clases que se llaman igual pero localizadas en diferentes paquetes Observe que el cdigo de la figura 2.15 no contiene la instruccin import para las clases naves.Casco y sodados.Casco. De hecho, si se incluyeran las instrucciones para importar ambas clases, el compilador marcara un error por la ambigedad que representa importar dos clases con el mismo nombre. Es por esta razn que en las lneas 3,4, 6 y 7 se hace referencia al nombre completo de la clase (esto es, incluyendo el nombre del paquete).

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

37

Resumen del Captulo. En este captulo creamos, compilamos y ejecutamos nuestros primeros programas en Java. Vimos que para poder ejecutar un programa que utiliza objetos, es necesario previamente crear las clases que definen las caractersticas y funciones de los objetos. Posteriormente, es necesario crear los objetos y finalmente enviar mensajes a los objetos para que efecten sus funciones. Vimos la forma en que se declaran los atributos y los mtodos de los objetos y cmo se llaman a sus mtodos. Finalmente utilizamos paquetes para agrupar las clases relacionadas en directorios y estudiamos ejemplos de uso de paquetes en el cdigo. Ejercicios y preguntas. 1. Explique brevemente el concepto de abstraccin. 2. Describa las principales diferencias entre la Programacin Orientada a Objetos y la Programacin Imperativa. 3. Considere el siguiente enunciado: El Comit Olmpico Internacional desea tener en su computadora la informacin correspondiente a los atletas que participan en la Olimpiada. Se desea producir informacin sobre el desarrollo de los juegos. Ejemplos de esta informacin es la siguiente: Gafetes de los atletas y entrenadores, cuadro de Medallas por pas, resultados de cada una de las competencias, etc.. De acuerdo al enunciado, identifique las clases con los atributos y mtodos de los objetos que de acuerdo a su opinin sean los ms relevantes. 4. Escriba un programa en Java que resuelva el siguiente problema. Un distribuidor de Automviles desea almacenar en su computadora los datos importantes (marca, modelo y nmero de asientos) de los vehculos que vende. Escriba la clase Automovil de tal forma que el siguiente cdigo pueda compilar y ejecutar sin errores. public class Main { public static void main(String[] args) { Automovil a = new Automovil(); a.marca = Ford; a.modelo = 2000; a.numeroDeAsientos = 4; System.out.println("Se ha creado un automovil marca:"+a.getMarca()); System.out.println("Con "+a.getNumeroDeAsientos()+" asientos"); System.out.println("El cual tiene "+a.calculaAntiguedad()+" aos de uso"); } } La deber ser la siguiente: Se ha creado un automvil marca: Ford Con 4 asientos El cual tiene 12 aos de uso 7. Describa las ventajas que tiene el uso de paquetes en programas complejos.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

38

8. De la siguiente lista de atributos y mtodos, identifique aquellos que sean incorrectos y escriba la razn por la que son incorrectos a. salariodiario e. salarioDiario i. calculasalario() b. Salariodiario f. salario j. calculaSalario() c. salario diario g. SalarioDiario k. calcula el salario() d. salario_diario h. salario/diario l. CALCULASALARIO()

9. Dibuje un Diagrama de Clases que represente el nombre de la clase, los atributos y mtodos del siguiente cdigo:

10. Escriba el cdigo en Java que represente las clases correspondiente al siguiente diagrama de clases:

Para implementar el mtodo: calculaEdad() de la clase escuela, se debe restar al ao actual el ao de nacimiento del alumno. Puede probar su cdigo compilando y ejecutando el cdigo mostrado a continuacin:

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

39

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

40

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

41

3. Conceptos Bsicos de Programacin Orientada a Objetos


En este captulo veremos diversos temas importantes para el desarrollo de programas orientados a objetos. La razn por las que se incluyeron estos temas en un captulo aparte es simplemente didctica. Con el conocimiento de los conceptos estudiados en el captulo anterior, el estudiante debe ser capaz de escribir programas en Java que definan clases y creen objetos que realicen funciones simples. Sin embargo, apenas estamos empezando. La intencin del autor es que el estudiante realice los ejercicios conforme avanza en la lectura y es por esa razn que se escogi hacer ms pequeos los captulos. Con el conocimiento de los nuevos conceptos que se introducirn en este captulo, el estudiante podr escribir programas ms complejos que representen ms adecuadamente la parte del mundo real que se pretende modelar. Como se mencion anteriormente, el objetivo de la programacin orientada a objetos es el modelado del mundo real a travs del proceso de abstraccin. Esto es, tomando en cuenta slo las caractersticas del mundo real que nos interesa modelar. El mundo real es muy complejo y por consiguiente, muchos conceptos que suceden en el mundo real deben de poderse representar de alguna forma dentro de la programacin orientada a objetos. Algunos de los conceptos importantes que veremos en este captulo son: Mtodos y atributos de clase, constructores, arreglos y mtodos de acceso a los miembros (atributos y mtodos) de los objetos. Mtodos y Atributos de Clase. En el captulo anterior vimos que los objetos tienen comportamiento (mtodos) y estado (atributos). Tambin hicimos una analoga con un molde utilizado para hacer un pastel. El molde corresponde a la clase y el pastel es el objeto. Pero una pregunta que podemos hacernos es: El molde en s, podra tener sus propios atributos y mtodos? Pensemos por un momento en el molde. La respuesta por supuesto es si. Ahora Podra identificar el lector atributos propios del molde? Por ejemplo, el material del molde, las dimensiones, el color, etc. Todos estos atributos pertenecen al molde y no al pastel. Es muy importante que el lector entienda perfectamente esta idea antes de continuar. Lo que se acaba de afirmar es que las clases (moldes) tambin pueden tener sus propios atributos y mtodos. Entonces tenemos dos clases de atributos (y mtodos) los que pertenecen a los objetos y los que pertenecen a las clases. En muchas ocasiones en nuestra actividad de programacin, encontraremos la necesidad de utilizar mtodos y atributos de la clase. La figura 3.1 muestra algunos atributos de clase y de objeto para el ejemplo del molde para hacer pasteles. La pregunta que ahora puede hacerse el lector es: Por qu complicarse la vida con esto de los atributos y mtodos de clase? No era suficiente con los atributos y mtodos de los objetos? La respuesta es desafortunadamente, no. Los atributos y mtodos de los objetos son tiles para
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 42

representar caractersticas y comportamiento de los objetos solamente. Imagine el lector la siguiente situacin. En el programa para el clculo de la nmina que realizamos en el captulo anterior, un nuevo requerimiento es conocer el nmero de trabajadores que tiene la empresa. La pregunta que podemos hacernos es Se puede considerar al nmero de trabajadores como un atributo del objeto trabajador? Si razonamos un poco esta pregunta nos daremos cuenta que no es correcto considerar al nmero de trabajadores como un atributo del objeto trabajador pues no proporciona informacin acerca del trabajador. Entonces Ser un atributo de la clase? Exactamente! El nmero de trabajadores es un atributo de la clase Trabajador pues representa informacin acerca de la clase completa y no slo de un individuo.

Figura 3.1 Atributos y Mtodos de Clase y del Objeto Los atributos y mtodos de los objetos reciben tambin el nombre de atributos y mtodos de instancia. En java, para representar un atributo mtodo de clase se utiliza la palabra reservada static. Por esta razn, algunos programadores le llaman a este tipo de atributos y mtodos estticos. Vamos ahora a utilizar este conocimiento para incluir un nuevo requerimiento al programa de nmina del captulo anterior. Supongamos que nos solicitan ahora que contemos el nmero de trabajadores que laboran en la empresa. La salida requerida del programa se muestra en la figura 3.2

Figura 3.2 Salida deseada del programa de nmina

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

43

Como puede observarse, el nuevo requerimiento consiste en contar el nmero de trabajadores de la empresa y mostrarlo al final. La forma como resolveremos este nuevo requerimiento es la siguiente. Usaremos un atributo esttico de la clase Trabajadores al que llamaremos numTrabajadores. Ahora Cmo lo vamos utilizar para contar el nmero de trabajadores? Utilizaremos un constructor. Un constructor es algo parecido a un mtodo (debe quedar claro que un constructor no es un mtodo) que se ejecuta cuando se crea un objeto. A diferencia de los mtodos, los constructores no tienen regresan ningn valor y adems slo pueden ejecutarse una vez, al momento de la creacin del objeto. Los constructores se deben llamar exactamente igual que la clase y no se declara el valor de retorno. La figura 3.3 muestra el cdigo de la clase Trabajador. En el cdigo se muestra la declaracin del atributo de clase (esttico) numTrabajadores y tambin el cdigo del constructor de la clase Trabajador. Como puede observarse en la figura 3.3, se declara el atributo de la clase numTrabajadores en la lnea 4. La forma en que se declara un atributo esttico (o de clase) es muy parecida a la forma de declarar un atributo de instancia, simplemente escribimos la palabra static antes del tipo de datos y el lenguaje Java lo interpreta como un atributo que pertenece a la clase Trabajador y no al objeto de dicha clase.

Figura 3.3 Cdigo de la clase Trabajador con su constructor y su atributo de clase Aunque la diferencia en la declaracin de los atributos de clase y de instancia es mnima (slo una palabra) la diferencia en significado es muy grande. Como se mencion anteriormente, los atributos de instancia pertenecen al objeto y por lo tanto se almacenan en la memoria heap. Por otro lado, los atributos de clase no pertenecen al objeto sino a la clase y por lo tanto no se almacenan en la misma rea. Como los atributos de la clase no requieren de ningn objeto para poder utilizarse, se puede acceder a ellos simplemente a travs del nombre de la clase. Esto queda

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

44

ejemplificado en la lnea 10 de la figura 3.3 pues estamos incrementando en uno la variable esttica numTrabajadores de la clase Trabajador sin tener que hacer referencia a ningn objeto. Las lneas 9 a 11 corresponden al constructor de la clase Trabajador. Como se mencion anteriormente, estas lneas se ejecutan cuando se crea cada objeto de la clase Trabajador. De esta manera, nos estamos asegurando de que se cuente cada trabajador creado. En la figura 3.4 se presenta el cdigo de la clase Main que crea los trabajadores y muestra su pago considerando el nuevo requerimiento de mostrar el nmero de trabajadores. El cdigo de la figura 3.4 es prcticamente el mismo cdigo que el de la figura 2.13. Excepto por la lnea 33. Esta lnea muestra el nmero total de trabajadores de la empresa. Como puede observarse, la forma de acceder al atributo de clase desde afuera de la clase es idntica a la forma como accedimos al atributo desde adentro de la clase (lnea 10 de la clase Trabajador). El lector podra hacerse la siguiente pregunta. Si los atributos de clase no requieren la creacin de objetos para su uso entonces en qu momento se pueden utilizar? La respuesta es: desde el primer momento, es decir, desde que se inicia la ejecucin de un programa. Si la clase no est en el mismo paquete, entonces desde que se importe la clase. De hecho, una clase puede ser accedida an sin importarla, si se utiliza el nombre completo de la clase incluyendo el nombre del paquete como lo usamos en el ejemplo de la figura 2.15 Constructores En el ejemplo anterior, utilizamos el constructor de la clase Trabajador para contar cuantos trabajadores se han creado en la empresa. Los constructores son una especie de mtodos que se ejecutan nicamente cuando se crean los objetos. Por ejemplo, cuando se ejecuta la instruccin: Trabajador t1 = new Trabajador(); Se realizan los siguientes pasos: 1. Se reserva un espacio en la memoria heap para el nuevo objeto de la clase Trabajador 2. Se ejecuta el constructor de la clase Trabajador 3. Se asigna a variable t1 la direccin de memoria en la cual se cre el nuevo objeto En este ejemplo, utilizamos el constructor para incrementar el contador de trabajadores. Un uso ms comn de los constructores es para inicializar valores de los atributos de los objetos. En el ejemplo de la figura 3.4 se asignan los valores de los atributos de los objetos en las lneas: 6, 7, 8, 10, 11, 12, 14,15, 16. Esto en general no es una buena prctica de programacin, en primer lugar porque es necesario escribir mucho cdigo, en segundo lugar porque no es una buena prctica de programacin permitir que los atributos de las clases sean modificados desde afuera de la clase. En este ejemplo, desde la clase Main hemos asignados los valores a los atributos de instancia de los objetos de la clase Trabajador.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 45

Figura 3.4 Cdigo de la clase Main incluida en el paquete etc del Programa de Nmina Modificaremos ahora el cdigo de la clase Trabajador de tal forma que podamos inicializar (enviar valores iniciales) a los objetos para que, justo despus de haberse reservado en la memoria heap el espacio para el objeto, se asignen los valores de sus atributos. Para lograr lo anterior, vamos a utilizar un constructor que permita recibir los parmetros que contienen los valores de los atributos de los objetos. Por supuesto, tambin contaremos a los trabajadores como lo hicimos anteriormente. La figuras 3.5 y 3.6 muestran los cdigos de la clase Trabajador y de la clase Main respectivamente.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

46

Figura 3.5 Cdigo de la clase Trabajador cuyo constructor recibe valores de atributos La diferencia entre el cdigo de la figura 3.5 y el de la figura 3.3 es precisamente en el constructor que se encuentra en las lneas 9 a 14 de la figura 3.5. Podemos ver que ahora el constructor recibe tres parmetros (nombre, saalarioPorHora y horasTrabajadas). Estos parmetros son variables que toman su valor cuando se hace el llamado al constructor (o sea cuando se crea el objeto). La lnea 10 contiene la asignacin: this.nombre = nombre; La palabra this se utiliza en este caso para resolver una ambigedad pues tenemos dos variables con el mismo nombre Cules? La variable nombre (que en este caso es ms bien atributo) que fue definida en la lnea 5 y la variable nombre que fue definida como un argumento del constructor de la clase Trabajador en la lnea 9. La palabra this hace que la parte izquierda de la asignacin se refiera al atributo. De esta forma, estamos asignando el valor del parmetro nombre al atributo nombre. Podamos haber prescindido del uso de la palabra this si hubiramos usado otro nombre para el parmetro del constructor pero escogimos hacerlo as precisamente para mostrar el uso de esta palabra. La palabra this es muy utilizada en java pues es la forma que tenemos de hacer referencia a un objeto dentro de sus mtodos. Dicho sea de otra forma, el this the Java es anlogo al yo (o al mi) que utilizamos en nuestro lenguaje cotidiano. Si estamos haciendo referencia a nosotros mismos, utilizamos la palabra yo o mi. En la lnea : this.nombre = nombre; Lo que estamos expresando es: Asigna el valor que tenga el parmetro nombre que aparece en la lista de parmetros del constructor a mi atributo nombre

Similarmente, las lneas 11 y 12 asignan las horas trabajadas y el salario por hora a los atributos respectivos del objeto.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 47

Figura 3.6 Cdigo de la clase Main que utiliza el constructor de la clase Trabajador para asignar los valores iniciales de los atributos Las lneas 5, 6 y 7 del cdigo de la clase Main utilizan el constructor de la clase Trabajador. Como puede observarse, se disminuye considerablemente la cantidad de lneas de cdigo. Adems de lo anterior, esta forma de asignar valores iniciales a los atributos tiene varias ventajas importantes que veremos ms adelante. Sobrecarga de Constructores Una de las caractersticas ms tiles de la programacin orientada a objetos es la sobrecarga de constructores. Esta consiste en definir varios constructores de la misma clase pero con diferentes parmetros. Supongamos por ejemplo, que la mayora de los trabajadores trabajan 40 horas semanales. Entonces podramos tener un constructor especial para estos trabajadores. Este constructor asignara de manera automtica el valor 40 al atributo horasTrabajadas. Las figuras 3.7 y 3.8 muestran los cdigos de las clases Trabajador y Main respectivamente.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

48

Figura 3.7 Clase Trabajador con el constructor sobrecargado Las lneas 14, 15 y 16 muestran el constructor de la clase Trabajador sobrecargado. Como puede observarse en las lneas 8 y 14 se declaran dos constructores de la clase Trabajador, lo cual es perfectamente vlido siempre y cuando los parmetros sean diferentes ya sea en tipo o en cantidad. En este caso, los parmetros son diferentes en cantidad pues en la lnea 8, el constructor espera 3 parmetros mientras que en la lnea 14 el constructor slo recibe dos parmetros. En la lnea 15, encontramos otro uso de la palabra this. En este caso, usamos la palabra this para llamar al constructor con tres argumentos, es decir, al constructor definido en la lnea 8. DE esta manera, cuando se llama al constructor con dos argumentos (lnea 14), este constructor llama al constructor con tres argumentos (lnea 8). El argumento que se rellena es precisamente el de las horas trabajadas, el cual es una constante con valor de 40. Algo que es muy importante sealar es que si se utiliza la palabra this para llamar otro constructor, este llamado debe ser la primera instruccin del constructor. De lo contrario, el programa no compilar, Puede el lector contestar la siguiente pregunta. Cul sera el error en el siguiente cdigo? class X { X(int a){ this(5); } } La lnea 5 de la clase Main de la figura 3.8 crea el objeto de la clase Trabajador con dos argumentos. Observe que las lneas 6 y 7 tambin crean objetos de la clase Trabajador pero con tres argumentos. Java puede distinguir cual constructor utilizar de acuerdo a nmero de parmetros. No es difcil encontrar clases que contienen varios constructores para manejar las diferentes situaciones que se pueden presentar al momento de construir un objeto.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

49

Figura 3.8 Cdigo de la clase Main que utiliza el constructor sobrecargado de la clase Trabajador Arreglos En muchas ocasiones, es conveniente almacenar un grupo de objetos dentro de otro objeto con el fin de poder acceder a ellos y manipularlos de una manera conveniente para el programador. A los objetos contenidos en el arreglo se les llama elementos del arreglo. Por ejemplo, imagine que la empresa a la que estamos calculando la nmina tuviera ms de 3 empleados, digamos unos 10. Puede imaginarse el lector como se complicara el cdigo de la figura 3.8? Tendramos que repetir las lneas 5,6 y 7 y las lneas 10 a 23 varias veces ms, una por cada una de los 10 trabajadores. Por esta razn, se crearon los arreglos en los lenguajes de programacin. Un arreglo es un objeto que contiene a un grupo de objetos (aunque tambin puede contener valores simples como enteros, caracteres, etc.). Con el uso de arreglos, estas repeticiones se pueden poner dentro de ciclos, como se ver un poco ms adelante. Los arreglos no forman parte exclusiva de la programacin orientada a objetos, es decir, otras formas o paradigmas de programacin tambin permiten manejar arreglos. Sin embargo, es un tipo de objetos muy utilizado en la programacin orientada a objetos. La siguiente lista muestra las caractersticas principales de los arreglos: 1. 2. 3. 4. 5. Los arreglos son objetos Los arreglos tienen un tamao fijo que se define en el momento de crear el arreglo Todos los elementos del arreglo deben ser del mismo tipo Los elementos se acceden a travs de un ndice numrico que empieza en 0 El ltimo elemento del arreglo est en la posicin t-1 donde t es el tamao del arreglo
Hctor A. Andrade G. 50

Conceptos de Programacin Orientada a Objetos

Declaracin y Creacin de arreglos. Como se mencion anteriormente, todos los arreglos son objetos, por lo que residen en la memoria heap. La forma de declara un arreglo es muy parecida a la declaracin de una variable o atributo, slo que se agregan los corchetes [] para indicar que se trata de un arreglo. Por ejemplo, la declaracin: int[] a; Declara que la variable (o atributo) a es un arreglo que contendr un cierto nmero de enteros. Note que como todava no se est creando el arreglo, no es necesario todava especificar la cantidad de elementos (el nmero de nmeros enteros) que sern almacenados en el arreglo. Tambin podemos tener arreglos de objetos. Por ejemplo: Trabajador[] trabajadores; Declara un arreglo de trabajadores. Igualmente a la declaracin anterior, no es necesario determinar cuntos trabajadores contendr el arreglo trabajadores porque todava no se est creando el arreglo. Las siguientes instrucciones crean ambos arreglos respectivamente: A = new int[15]; trabajadores = new Trabajador[10]; Estas dos ltimas instrucciones crean los arreglos a y Trabajadores. El arreglo a tiene 15 enteros y el arreglo trabajadores tiene 10 objetos de la clase Trabajador. Al momento de crear los arreglos, todos los elementos del arreglo a sern 0s y los elementos del arreglo trabajadores contendrn un valor especial llamado null que representa que el objeto no ha sido creado. Es importante hacer la siguiente aclaracin: Cuando se crea un arreglo que contiene objetos (como el arreglo trabajadores), slo se crea un objeto (o sea el arreglo!) y no los objetos que contiene. Debe quedar claro que la instruccin: trabajadores = new Trabajador[10]; Slo crea un objeto y no 10 como errneamente se puede suponer. El nico objeto creado es el arreglo en si. Aunque este arreglo tiene 10 espacios para los elementos, estos espacios estn vacios, o sea, tienen un valor de null. La figura 3.9 muestra el estado de la memoria despus de crear el arreglo trabajadores. Como puede observarse en la figura 3.9, el arreglo trabajadores ha sido creado en la memoria heap. Sin embargo, los 10 espacios reservados para cada uno de los trabajadores contienen la
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 51

palabra null. Esto significa que los espacios estn en blanco. Sabemos que cada uno de esos espacios contendr un objeto de la clase Trabajador pero hasta este momento no se han creado estos objetos.

Figura 3.9 Estado de la memoria Heap despus de haber creado el arreglo trabajadores Tambin es posible hacer la declaracin de la variable y crear el arreglo al mismo tiempo. Por ejemplo, la lnea: Trabajador [] trabajadores = new Trabajador[10]; Declara el arreglo trabajadores y adems crea el arreglo con 10 posiciones en la memoria heap. El resultado es exactamente el mismo que si se usa el par de lneas: Trabajador [] trabajadores; Trabajadores = new Trabajador[10]; Ahora que ya se tiene el arreglo creado, el paso necesario para poder almacenar a los trabajadores en el arreglo es crear cada uno de los 10 trabajadores y asignarlo a cada una de las 10 posiciones del arreglo. Existen varias formas de hacer lo anterior. Primero presentaremos la forma estndar y luego presentaremos la forma abreviada. Las figuras 3.10 y 3.11 muestran ambas formas respectivamente.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

52

Figura 3.10 Forma estndar de creacin y carga del arreglo trabajadores En la figura 3.10 la lnea 8 declara la variable trabajadores como un arreglo de objetos de la clase Trabajador, el cual contiene 15 elementos. Tambin se crea el arreglo en la memoria heap. Sin embargo, no se crean ninguno de los 15 objetos de la clase Trabajador. La lnea 9 crea el objeto que corresponde al trabajador Armando Paredes y lo asigna al elemento 0 del arreglo trabajadores. Las lneas 10 a la 18 crean los dems objetos de la clase y los asignan a las posiciones 1 a la 9. El tamao del arreglo es de 10 posiciones, es por esta razn que el ltimo elemento del arreglo est en la posicin 9. Si el programa intenta acceder a un elemento en una posicin mayor a 9 (o menor a 0), se generar un error de ejecucin. La figura 3.11 muestra otra forma ms compacta o abreviada de crear y asignar valores a un arreglo. A diferencia de la forma anterior, esta forma abreviada no requiere especificar el nmero de elementos del arreglo. Como puede observarse en la lnea 8, se asigna directamente al arreglo los objetos creados, los cuales se encierran en llaves. Cmo determina entonces el compilador el tamao del arreglo? Se deja al lector que encuentre la respuesta.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

53

Figura 3.11 Forma abreviada de creacin y carga del arreglo trabajadores Las dos formas de declarar, crear y asignar valores al arreglo presentadas en las figuras 3.10 y 3.11 son idnticas. Es decir producen exactamente el mismo resultado. El estado de la memoria heap despus de la ejecucin de cualquiera de los dos cdigos se muestra en la figura 3.12. Podemos observar fcilmente en la figura 3.12 que despus de la ejecucin de cualquiera de los cdigos mostrados en la figura 3.10 y 3.11 se habrn creado 11 objetos en la memoria heap. Porqu 11? Porque se crearon 10 objetos de la clase Trabajador y un objeto que contiene a estos 10 objetos. En realidad los 10 objetos no estn adentro del arreglo como puede observarse en la figura 3.12. Cada elemento del arreglo contiene un apuntador que indica la posicin dentro de la memoria heap en la cual se encuentra almacenado el objeto. Por ejemplo, la posicin 0 del arreglo trabajadores contiene un apuntador (o direccin de memoria) que corresponde a la direccin de memoria en la cual est almacenada toda la informacin del objeto Armando Paredes. En la figura 3.12 no se incluyeron los dems atributos del objeto por razones de espacio. En resumen, hemos visto que un arreglo en una objeto que puede contener varios objetos. La forma como accedemos a cada uno de los objetos contenidos en el arreglo es por medio de un ndice. Este ndice comienza en 0 que corresponde a la primera posicin y termina en la posicin que se calcula restando uno al tamao del arreglo. Otra cosa importante que vale la pena remarcar es que al crear el arreglo no se crean los elementos del mismo. Esto hace necesario que adems de crear el arreglo se deban crear cada uno de los elementos del mismo. En este libro usaremos

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

54

extensivamente los arreglos para almacenar informacin de varios objetos (o tipos primitivos de datos) en otro objeto.

Figura 3.12 Estado de la memoria heap despus de crear los trabajadores y asignarlos a las posiciones del arreglo A pesar de haber visto las ventajas del uso de arreglos, es an posible que algn lector suspicaz piense: Bueno pero Donde est el ahorro de cdigo? De todas formas, se tienen que crear los objetos y al final se est utilizando una lnea de cdigo por cada trabajador. Lo mismo que se hace en el cdigo de la figura 3.8. Es cierto. El ahorro en el cdigo no est en la declaracin del arreglo sino en el procesamiento del mismo. Es decir, en el cdigo que calcula e imprime la nmina. La figura 3.13 muestra el cdigo completo del programa.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

55

Las lneas 23 a 28 de la figura 3.13 realizan la misma funcin que las lneas 11 a 23 de la figura 3.8. Esto es, un ahorro de 7 lneas!. Pero esto es porque slo aumentamos 7 trabajadores ms. Imagine por favor el lector si en lugar de 7, hubiramos aumentado el nmero de trabajadores a 500 (o a 5000). El ahorro en lneas de cdigo sera muy grande.

Figura 3.13 Cdigo completo del programa de Nmina utilizando un arreglo

La lnea 23 de la figura 3.13 inicia el ciclo for que termina en la lnea 28. La variable i declarada en la lnea 23 se utiliza como ndice para acceder a los elementos del arreglo trabajadores. De esta forma, se calcula el pago y se muestra el sueldo por cada trabajador. Existe an una pregunta que algn lector suspicaz pudiera hacer con respecto al ahorro de cdigo. Qu hay de las lneas 5 a la 15? Por qu no podemos utilizar un ciclo para ahorrarnos lneas de cdigo? El problema es que tenemos que cargar el arreglo de trabajadores con los datos de cada uno de ellos. Sera imposible hacerlo en un ciclo, a menos que asignramos los mismos valores a todos los trabajadores, outilizramos archivos para almacenar la informacin, lo cual haremos casi el final de este libro en el captulo que trata sobre archivos y flujos de datos.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 56

Algo que vale la pena mencionar, es que hemos cambiado varias veces el cdigo de la clase Main sin necesidad de alterar la definicin de la clase Trabajador. Esto es una caracterstica muy importante de un buen diseo. Tratar de evitar al mximo que una modificacin de una clase afecte al diseo de otras. Este concepto se llama bajo acoplamiento o (low coupling). En general, se debe disear cada clase de tal forma que slo tenga atributos y mtodos relativos y pertenecientes exclusivamente a esa clase. Por ejemplo, supongamos que para el pago de la nmina es necesario el uso de un tabulador que indique la tarifa correspondiente al trabajo que desempe el trabajador. Si un trabajador trabaja como soldador recibe un salario de 100 pesos por hora pero si trabaja como lubricador entonces recibe 150 pesos la hora. Entonces, podramos estar tentados a incorporar la tarifa a la clase Trabajador. Sin embargo, sta no sera una buena decisin de diseo pues se tendra que modificar la clase Trabajador si existe algn cambio en las tarifas. Lo conveniente en este caso es crear otra clase que podramos llamar Tarifa que contiene exclusivamente la informacin de las tarifas y almacenar en cada objeto de la clase Trabajador las horas trabajadas y el tipo de trabajo desempeado. Permisos de Acceso a los Miembros de los Objetos. Una de las caractersticas ms importantes de la programacin orientada a objetos es la posibilidad de esconder informacin de los objetos al mundo exterior. Por qu necesitamos esconder informacin de los objetos? Hay varias respuestas posibles. Empezaremos con un ejemplo. Imaginemos que tenemos un piano como el que se muestra en la figura 3.14

Figura 3.14 Piano con sus interfaces pblica y privada

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

57

En la figura 3.14 podemos observar un piano de cola. En el piano distinguimos las teclas y los pedales como su interface con el pianista (usuario normal de un piano). A esta interface le llamamos interface pblica porque esta interface est completamente expuesta, o sea al alcance de cualquier usuario. El usuario puede interactuar con el piano aunque no sepa tocarlo sin que pase nada malo. Excepto quizs, un mal rato para los desafortunados que tengan que or la ejecucin! Por otro lado, tenemos las perillas de ajuste que se utilizan para la afinacin del piano. Estas perillas slo debe moverlas un especialista en afinacin de pianos. Este oficio es complicado y no cualquiera puede llevarlo a cabo. Las perillas de afinacin les llamamos interface privada porque no cualquiera debe tener acceso a ellas. Podemos decir que estn escondidas debajo de una tapa y por esta razn no estn a la vista de los usuarios normales. Para acceder a ellas, es necesario desmontar la tapa que las cubre. Si un usuario inexperto mueve estas perillas, el piano quedara desafinado. Esto es algo muy grave, y es por esa razn que las perillas de ajuste estn ocultas para los usuarios normales. Existe otra razn igual de importante para separar las interfaces pblicas y privadas de los objetos. De nuevo, recurriremos al ejemplo del piano para ilustrar este concepto. Supongamos que el fabricante de pianos decide modificar el funcionamiento interno del piano. Esto implica un cambio en la forma de afinacin de las perillas. Imagine el lector lo que pasara si este cambio en el funcionamiento del piano afectara tambin la forma de tocarlo! Esto sera un desastre! Ningn pianista deseara tocar un piano que requiera habilidades especiales. Por esta razn, los fabricantes de piano no modifican la interface pblica (teclas, pedales). Sin embargo, pueden modificar la interface privada sin mayores consecuencias pues los afinadores de los pianos pueden adaptarse ms fcilmente a los cambios si cuentan con la informacin suficiente. En resumen: Las ventajas de tener interfaces privadas y pblicas en los objetos son las siguientes: 1. Los usuarios comunes acceden al objeto a travs de las interfaces pblicas exclusivamente, lo que protege al objeto de que sea daado o afectado por un mal uso 2. En caso de que haya modificaciones en las partes internas del objeto, estas modificaciones slo afectan la interface privada, por lo que no afectan a los usuarios comunes de los objetos De manera similar al ejemplo mostrado, en la programacin orientada a objetos, los objetos poseen una interface pblica, la cual puede ser accedida por cualquier otro objeto y una interface privada, la cual slo puede ser accedida dentro del mismo objeto. En realidad, el manejo de interfaces pblicas y privadas en la programacin orientada a objetos es ms complicado que lo presentado hasta ahora. Sin embargo, la idea en general es muy similar y tambin las razones por las que es conveniente esconder informacin. A continuacin presentaremos los mismos conceptos pero los pondremos en prctica en el ejemplo de la nmina, el cual hemos utilizado hasta ahora en este libro.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

58

La figura 3.15 muestra la clase Trabajador de acuerdo a nuestra ltima definicin. Es decir, incorpora el uso de sobrecarga de constructores.

Figura 3.12 Cdigo de la clase Trabajador Cmo puede verse en el cdigo de la figura 3.12, las lneas 4, 5, 6 y 7 declaran los atributos de los objetos de la clase Trabajador como pblicos. Esto es por la palabra public que aparece a la izquierda de la declaracin. Esto significa que se puede acceder a estos atributos desde cualquier clase que est localizada en cualquier paquete. La figura 3.16 muestra la clase ClaseMala que asigna y lee valores de los atributos de un objeto de la clase Trabajador.

Figura 3.16 Cdigo de la clase ClaseMala que asigna datos incorrectos a un Trabajador El resultado de la ejecucin del cdigo de la clase ClaseMala es el siguiente: El pago de Juan X es: -450

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

59

El resultado anterior, el cual es a todas luces inaceptable pues no puede haber un pago negativo, (excepto si la empresa le cobra al trabajador en lugar de pagarle). Empecemos por revisar el cdigo de la figura 3.16. La lnea 1 declara que el archivo est en el paquete etc. La lnea 2 importa la clase Trabajador lo cual es necesario para que pueda ser utilizada por la clase ClaseMala. Las lneas 4, 5 y 6 son comentarios del programa. Es decir, una explicacin del cdigo. Los comentarios en Java se escriben empezando con los caracteres /* y terminando con */. Todo lo que est entre estos dos pares de caracteres es ignorado por el compilador y su nica utilidad es agregar legibilidad al programa. Otra forma de escribir comentarios es utilizando los caracteres // como se muestra en la lnea 10. La diferencia entre estos dos tipos de comentarios es que este ltimo tipo se usa comentarios de una sola lnea. El error de este cdigo est en la lnea 10 pues se asigna un nmero negativo a las horas trabajadas. (t.horasTrabajadas=-3;). Obviamente, esto es incorrecto pues imposible que alguien trabaje un nmero negativo de horas. La pregunta es: Cmo podramos prevenir que se asigne un valor inaceptable a un atributo de un objeto? Otra pregunta ms interesante an Quin debe ser el encargado de checar que los valores de los atributos sean vlidos? La primera pregunta tiene muchas respuestas. Puede el lector dar algunas soluciones? Por ejemplo, se podra checar que no se tengan nmeros negativos en el momento de calcular el pago, o sea en el mtodo calculaPago() de la clase Trabajador. Con respecto a la segunda pregunta: Quin debe ser el encargado de checar que los atributos de los objetos sean vlidos? La respuesta a esta pregunta es mucho ms obvia: El mismo objeto! Dado que el programador de la clase Trabajador es quien conoce a fondo a la clase (pues es quien la program!) l es el ms indicado para escribir el cdigo que cheque la validez de los valores de los atributos. Esto est muy bien, pero Cmo se puede prevenir que cualquier usuario (o clase) pueda asignar valores a los atributos de los objetos? Hacindolos privados! Si los atributos de los objetos son privados, no existe forma de que sus valores puedan ser alterados desde un cdigo escrito en otra clase. sta es una forma de proteccin para que los valores de los atributos slo puedan ser modificados (o incluso consultados) dentro de la misma clase. La figura 3.18 muestra el cdigo de la clase trabajador con la modificacin de que ahora todos los atributos de los objetos de esta clase son privados.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

60

Figura 3.18 Cdigo de la clase Trabajador con sus atributos privados Como puede observarse, ahora todos los atributos (tanto el de la clase como los de los objetos) son privados. Esto significa que slo podrn ser vistos (consultados y modificados) dentro de la misma clase. Sin embargo, al compilar el cdigo de la clase ClaseMala de la figura 3.16 obtenemos los siguientes errores:
etc\ClaseMala.java:10: horasTrabajadas has private access in nomina.Trabajador t.horasTrabajadas = -3; // !El error esta aqui! ^ etc\ClaseMala.java:12: nombre has private access in nomina.Trabajador System.out.println("El pago de "+ t.nombre +" es: "+pago); ^ 2 errors

Los dos errores que marca el compilador (lneas 10 y 12) tienen que ver precisamente con el hecho de que estamos tratando de acceder a atributos privados desde afuera de la clase. Pues estos son atributos privados de la clase Trabajador y los estamos tratando de acceder desde la clase ClaseMala. Hemos corregido un problema pero ahora tenemos ahora uno peor Ni siquiera podemos compilar el programa sin errores! Qu hacer? La respuesta en la prxima seccin. Setters y Getters En la seccin anterior, hemos visto que es conveniente tener atributos privados para que slo pueda tener acceso a ellos el cdigo escrito en la misma clase a la cual pertenecen dichos atributos. Sin embargo, a veces puede ser necesario este acceso externo a los atributos de los
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 61

objetos. La solucin consiste en lo siguiente. Escribir mtodos que tengan permisos pblicos y que permitan acceder desde afuera a los atributos privados de los objetos. Estos mtodos se escriben adentro de la clase y por lo tanto tienen acceso a los atributos privados pero al ser mtodos pblicos pueden ser llamados desde el exterior de la clase. El nombre que reciben estos mtodos es setters y getters. Un mtodo setter se usa para asignar un valor a un atributo de un objeto y un mtodo getter se utiliza para conseguir el valor de un atributo de un objeto. La figura 3.19 ilustra la idea de los setters y los getters a travs de una analoga. La bola de boliche, es impenetrable. Slo tiene tres agujeros los cuales permiten tomar la pelota para lanzarla.

Figura 3.19 Un objeto con atributos privados es como una bola de boliche Los getters de la figura 3.19 son los agujeros superiores y los setters (aunque en este caso es l setter porque slo es uno) es el agujero inferior. Observamos por la direccin de las flechas que los setters permiten introducir algo (asignar un valor) al objeto mientras que los getters permiten sacar u obtener algo del objeto. Las figuras 3.20 y 3.21 muestran la forma de escribir un getter y un setter para el atributo horasTrabajadas. De la figura 3.20 en la lnea 64 observamos que el mtodo getter para el atributo horasTrabajadas es pblico, del tipo int (porque el atributo es entero) y no recibe ningn valor como parmetro. Por otro lado, en la figura 3.21 observamos que el setter debe ser pblico, void y si debe recibir un valor. Este valor es el que se asignar al atributo.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

62

Figura 3.20 El mtodo getter del atributo horasTrabajadas Observamos tambin que en la lnea 69 de la figura 3.21, se asigna el valor parmetro de entrada (horasTrabajadas) al atributo horasTrabajadas. Cmo el parmetro y el atributo tienen el mismo nombre, usamos la palabra this para referirnos al atributo.

Figura 3.21 El mtodo setter del atributo horasTrabajadas La figura 3.22 muestra el cdigo completo de la clase Trabajador en el cual hemos implementado todos los setters y getters para todos los atributos. En el caso del atributo esttico (o sea, de la clase) numTrabajadores, no implementamos el setter pues no sera conveniente que cualquier clase externa pudiera modificar el valor de este atributo. Recordemos que slo debe modificarse si se crea un nuevo objeto de la clase Trabajador como puede verse en el constructor de la clase (lnea 14 de la figura 3.22).
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 63

Figura 3.22 Cdigo de la clase Trabajador con atributos privados y mtodos setters y getters La figura 3.23 muestra el cdigo de la clase ClaseMala con las modificaciones necesarias para que pueda compilarse junto con la clase Trabajador de la figura 3.22.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

64

Figura 3.23 Cdigo de la clase ClaseMala Como puede observarse en la lnea 10 de la figura 3.23, se utiliza un getter para asignar el valor de -3 al atributo horasTrabajadas del objeto t. De esta forma, podemos asignar un valor a un atributo privado desde otra clase. Aunque horasTrabajadas es privado, el mtodo setter setHorasTrabajadas es pblico y si puede ser llamado desde afuera de la clase Trabajador. De manera similar, en la lnea 12 se utiliza el mtodo getter getNombre, del objeto t el cual se utiliza para conseguir el nombre del trabajador y mostrarlo en la salida del programa. El programa de la figura 3.23 compila y ejecuta sin errores produciendo la salida: El pago de Juan X es: -450 El mismo resultado invlido! Todos los cambios que hemos hecho y Seguimos teniendo el mismo resultado! El problema radica en que el mtodo setHorasTrabajadas no realiza ninguna validacin sobre los datos que se envan. Es decir, asigna los valores a los atributos tal cual son enviados. Dicho de otra manera, an podemos asignar un valor invlido al atributo horasTrabajadas de la clase Trabajador. Una manera de blindar al objeto para que no pueda tener valores invlidos es realizar una validacin antes de asignar el valor al atributo del objeto en el mtodo setter. La figura 3.24 muestra el cdigo de la clase Trabajador con la validacin correspondiente en el mtodo setHorasTrabajadas de tal forma que acepte cualquier valor entre 0 y 168. Es decir suponemos que nadie puede trabajar menos de 0 horas ni ms de 168 (24*7) en una semana. Despus de modificar el cdigo de la clase Trabajador de acuerdo a la figura 3.24, al ejecutar de nuevo el cdigo de la figura 3.23 produce la salida: El pago de Juan X es: 0

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

65

Lo cual es aceptable (aunque posiblemente errneo) pero la decisin que se tom es asignar un valor default que en este caso es cero a cualquier valor que se salga del rango como lo hace la lnea 42 de la figura 3.24.

Figura 3.24 Cdigo de la clase Trabajador cuyo mtodo setHorasTrabajadas checa que el valor del atributo horasTrabajadas sea vlido

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

66

De manera similar, podramos modificar los mtodos setters para los dems atributos de la clase Trabajador de tal forma que se validen los valores de los atributos antes de ser asignados. Se deja al lector como ejercicio. Resumen del Captulo. En este captulo vimos algunos conceptos bsicos de la programacin orientada a objetos como son: los mtodos y atributos de clase, los cuales a diferencia de los atributos de instancia, pertenecen a la clase y no al objeto. stos son necesarios cuando deseamos almacenar informacin general sobre la clase a la cual pertenecen un grupo de objetos. Otro concepto importante mencionado en este captulo es el de constructor de un objeto. Un constructor es algo parecido a un mtodo que se ejecuta al crear un objeto. Normalmente se usa para asignar valores a las variables de instancia o realizar procesos iniciales en los objetos. En este captulo tambin vimos el uso de la palabra reservada this la cual se usa para hacer una autoreferencia al objeto o tambin para llamar a un constructor dentro de otro constructor del mismo objeto. Otros conceptos importantes vistos en este captulo son: sobrecarga de constructores, arreglos, encapsulamiento a travs del uso de setters y getters y permisos de acceso a miembros de los objetos. Ejercicios y preguntas. 1. Considere la clase BalnFutbol, la cual describe las caractersticas de un baln de futbol (soccer). De la siguiente lista de atributos, escriba una I si considera que el atributo debe ser considerado como un atributo de instancia o una C si el atributo debe ser considerado como de clase. a. pesoTotal ___ f. numeroDebalones ___ b. color ___ g. material ___ c. dimetro ___ d. fabricante ___ h. nombreDeporte ___

2. Considere el siguiente cdigo:

a. Cul es la salida del cdigo? b. Por qu la asignacin de la lnea 9 no afecta la salida producida por la lnea 12?
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 67

c. Por qu no es necesario hacer referencia al objeto x en la lnea 6 como se hace en la lnea 7? d. Cuntas localidades de memoria se utilizan para almacenar el contenido de TODOS los atributos que se utilizan en el cdigo? 3. Escriba la clase JugadorDefutbol con los atributos nombre, edad y posicin de tal forma que el siguiente cdigo pueda compilar y al ejecutarse produzca la salida mostrada:

La salida debe ser: Jugadores: Edson,50,delantero Javier,20,desconocida 4. Escriba el cdigo de la clase Alumno con los atributos de instancia, de clase y mtodos setters y getters necesarios para que el siguiente cdigo corra y produzca la salida mostrada.

La salida debe ser: Nombre: Juan, Edad: 20, Nivel: Licenciatura Nombre: Ernesto, Edad: 13, Nivel: Secundaria Nmero de Alumnos: 2 5. Modifique el cdigo de la figura 3.13 de tal forma que se muestre al final el nombre del trabajador que recibir el pago mayor. Sugerencia: use un ciclo for para recorrer todo el arreglo y comparar los valores. La salida deber ser la siguiente:

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

68

6. Modifique el cdigo de la figura 3.24 de tal forma que no sea posible asignar un nmero negativo al atributo salarioPorHora y adems, el mximo valor que pueda asignarse sea de 150 pesos. Si se intenta asignar un valor mayor a 150 pesos, entonces el setter deber asignar 150 pesos. Nota: deber modificar el mtodo setSalarioPorHora(). Pruebe su cdigo con el cdigo que escribi para resolver el problema anterior. Describa y explique los cambios en la salida.

7. Suponga que por disposicin oficial, a todos los trabajadores debe otorgrseles un bono de 50 pesos. Cmo afectara esta modificacin a la interface pblica de la clase Trabajador? Se tendran que realizar cambios al programa de la figura 3.13 para que produzca el resultado deseado? 8. El siguiente cdigo contiene errores. Corrjalos y explique en qu consiste el error y cmo lo corrigi.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

69

9. Resuelva el siguiente problema utilizando arreglos. Se tiene una lista de 20 personas con los siguientes datos: Nombre, Edad y Sexo. Se desea encontrar la siguiente informacin: a) El promedio de edad de los hombres b) El promedio de edad de las mujeres c) El nombre de la mujer con mayor edad d) El nombre del hombre ms joven e) El nmero de mujeres mayores al promedio de los hombres f) El nmero de hombres mayores al promedio de las mujeres 10. Construya la clase Estadisticas de acuerdo al siguiente diagrama de clases:

El mtodo mayor encuentra el mayor de los elementos del arreglo, el mtodo menor encuentra el menor, el mtodo promedio encuentra el promedio de los elementos y el mtodo suma regresa la suma de todos los elementos del arreglo. Note que todos los mtodos son estticos. Eso se puede observar en el diagrama porque estn subrayados. Pruebe su programa con el siguiente cdigo (colocar este archivo en el mismo directorio del archivo Estadisticas.java):

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

70

public class PruebaEstadisticas { public static void main(String[] args) { int[] numeros = {1,2,3,4,10,6,7,8,9,5}; int mayor = Estadisticas.mayor(numeros); System.out.println("El mayor es: "+mayor); int menor = Estadisticas.menor(numeros); System.out.println("El menor es:"+ menor); float promedio = Estadisticas.promedio(numeros); System.out.println("El promedio es:"+promedio); int suma=Estadisticas.suma(numeros); System.out.println("La suma es:"+suma); } } La salida del programa deber ser: El mayor es: 10 El menor es:1 El promedio es:5.5 La suma es:55 11. Se les llama arreglos multidimensionales o matrices a los arreglos en los cuales cada elemento es a su vez otro arreglo. Se pueden representar grficamente como tablas o cubos para dos o tres dimensiones respectivamente. Por ejemplo:
(0,0) (1,0) (2,0) (3,0) (4,0) (0,1) (1,1) (2,1) (3,1) (4,1) (0,2) (1,2) (2,2) (3,2) (4,2) (0,3) (1,3) (2,3) (3,3) (4,3) (0,4) (1,4) (2,4) (3,4) (4,4)

ndices de la matriz

En Java, las matrices se declaran en forma similar a los arreglos, solo que en lugar de usar un par de corchetes se usan varios pares dependiendo del nmero de dimensiones de la matriz. As, una matriz de nmeros enteros como la del ejemplo, se declarara as:

int[][] matriz = new int[5][5];

El siguiente cdigo, declara una matriz de 10 por 10 y le asigna nmeros aleatorios entre 0 y 99:

public class Matrices { public static void main(String[] args) {

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

71

int[][] matriz = new int[10][10]; for (int i=0;i<10;i++){ for(int j=0;j<10;j++){ matriz[i][j]=(int)(Math.random()*100); } } // Escriba el cdigo que muestre la matriz en pantalla // Escriba el cdigo que encuentre el mayor de cada hilera } }

Substituya los comentarios por cdigo que muestre la matriz y posteriormente que encuentre el mayor de cada hilera. Su salida deber ser como esta: Matriz de enteros: 19 30 91 51 41 73 42 29 11 31 87 81 17 92 49 70 33 45 76 53 74 2 52 98 15 11 62 5 84 65 88 70 40 84 27 71 75 29 52 23 Mayores de cada 19 30 91 41 73 42 11 31 87 17 92 49 33 45 76 74 2 52 15 11 62 84 65 88 40 84 27 75 29 52

70 47 28 71 57 55 8 56 57 7

43 71 46 28 58 63 18 25 70 40

38 30 70 39 60 27 65 38 10 33

78 13 15 51 20 89 68 74 41 35

7 59 91 93 77 11 47 15 43 17

44 90 68 21 81 16 69 33 44 58

hilera: 51 70 29 47 81 28 70 71 53 57 98 55 5 8 70 56 71 57 23 7

43 71 46 28 58 63 18 25 70 40

38 30 70 39 60 27 65 38 10 33

78 13 15 51 20 89 68 74 41 35

7 59 91 93 77 11 47 15 43 17

44 90 68 21 81 16 69 33 44 58

MAYOR:91 MAYOR:90 MAYOR:91 MAYOR:93 MAYOR:81 MAYOR:98 MAYOR:69 MAYOR:88 MAYOR:84 MAYOR:75

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

72

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

73

4. Herencia y Polimorfismo
En este captulo trataremos una de las principales caractersticas de la programacin orientada a objetos que es la Herencia y un concepto muy ligado a la herencia que es el Polimorfismo. Veremos cmo estos dos conceptos son muy tiles pero tambin agregan complejidad a la programacin. Una de las implicaciones del uso de herencia es que tenemos ms opciones para otorgar permisos de acceso a los miembros de la clase. En el captulo anterior, vimos que podemos otorgar permisos pblicos y privados. En este captulo veremos que podemos otorgar permisos de paquete y protegidos. Otros conceptos relacionados con la herencia son: clases abstractas, interfaces, mtodos abstractos, clases finales, y por ltimo, veremos el concepto de retorno covariante. La figura 4.1 muestra la relacin de la herencia con los otros conceptos antes mencionados.

Figura 4.1 La Herencia es el eje central de una serie de conceptos importantes de POO

Concepto de herencia.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 74

Como hemos insistido varias veces en este libro, la Programacin Orientada a Objetos intenta representar el mundo real en la computadora. La herencia en POO es un mecanismo que intenta representar el concepto de especializacin que existe en el mundo real. En el mundo real, existen conceptos que son ms generales que otros (y por consiguiente, unos son ms especficos que otros). Por ejemplo, un mueble es un concepto ms general que una silla. Podemos decir que todas las sillas son muebles pero no todos los muebles son sillas. Una cama, por ejemplo es un mueble pero no es una silla. Entonces Qu hace que un conc epto sea ms general (o especfico) que otro? La respuesta a la pregunta es que un concepto es ms especfico que otro si contiene mayor informacin que el otro (o sea el concepto especfico tiene ms informacin que el general). El concepto de mueble es el siguiente (segn la real academia espaola): Cada uno de los enseres movibles que sirven para los usos necesarios o para decorar casas, oficinas y todo gnero de locales Esta definicin, no contiene informacin sobre el uso principal del mueble, ni su construccin, sin embargo, en las definiciones de silla y cama encontraremos mayor informacin. Por ejemplo que la cama est hecha para que las personas se acuesten en ella o que la silla se compone de asiento y respaldo. Entonces, un concepto ms general tiene menos informacin pero abarca ms objetos, mientras que un concepto ms especfico tiene ms informacin pero abarca menos objetos. La figura 4.2 muestra la relacin entre mueble, silla y cama.

Figura 4.2 Relacin entre los conceptos de Mueble, Cama y Silla

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

75

La herencia en POO nos permite representar el concepto de especializacin (o generalizacin) segn lo vamos de arriba hacia abajo o de abajo hacia arriba. Podemos definir clases que heredan de otras (o sea, son ms especficas). Por ejemplo, la clase Mueble es ms general que la clase Silla o que la clase Cama. La forma de indicar en Java que una clase es ms especfica (o sea, que hereda de) otra es utilizando la palabra extends en la declaracin de la clase. La figura 4.3 muestra al cdigo en Java que define estas tres clases y la relacin entre ellas.

Figura 4.3 Definicin de las clases Mueble, Silla y Cama Como puede verse en la figura 4.3, la lnea 4 define la clase Silla como una extensin o especializacin de la clase Mueble. De manera similar, la lnea 7 define la clase Cama como una extensin de la clase Mueble. Hemos visto que el concepto de herencia en POO se usa para representar el concepto de especializacin del mundo real. Sin embargo, no hemos visto an cul es su utilidad. Es decir, Por qu es necesario o para qu queremos representar este concepto en la computadora? La siguiente seccin intenta responder a estas preguntas. La Herencia como mecanismo de reso de cdigo. Una de las principales razones para el uso de herencia en POO es el reso de cdigo. Cmo funciona? Muy simple. Cuando especializamos (extendemos) una clase como en el ejemplo de la figura 4.3, las clases ms especficas, las cules de ahora en adelante llamaremos subclases, heredan (por eso se le llama herencia a esta caracterstica de la POO) todos los mtodos y atributos de la clase ms general, a la cual, de ahora en adelante llamaremos Superclase. En el ejemplo de la figura 4.5, las clases Silla y Cama heredan todos los mtodos y atributos (note que no son privados) de la clase Mueble. Los atributos y mtodos privados no se heredan aunque como veremos ms adelante an es posible usarlos con el cdigo adecuado. Como pude verse en la figura 4.5, en la lnea 16 se asigna in valor de 3 al atributo peso del objeto s de la clase Silla. Pero Ese atributo no fue definido en la clase silla! La razn por la cual

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

76

es posible utilizarlo es porque Silla es una subclase de la clase Mueble y por lo tanto hereda todos los atributos y mtodos (no privados) de la clase Mueble. De manera similar, en la lnea 18 se llama al mtodo mueve() del objeto s aunque este mtodo no haya sido definido en la clase Silla. Podemos concluir entonces que la clase Silla tiene todos los atributos y mtodos definidos en la propia la clase, ms todos los atributos y mtodos de su superclase (en este caso, la clase Mueble). Qu pasa si una subclase tiene una superclase que es a su vez subclase de otra? Pues que todos atributos y mtodos de las dos clases superiores son heredados a la subclase ms especfica. La figura 4.6 muestra esta idea.

Figura 4.5 Definicin de las clases Mueble, Silla y Cama con mtodos y atributos En la herencia no tenemos lmites en cuanto al nmero de niveles que puede haber entre clases y subclases. Las subclases heredarn los mtodos y atributos de las superclases y a su vez pasarn estos mtodos y atributos a sus subclases y as sucesivamente. Como es obvio suponer, la ltima clase, es decir la ms especfica, contiene la mayor cantidad de informacin pues en cada nivel de la herencia se agrega nueva informacin, o sea, ms atributos y/o mtodos.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

77

La figura 4.6 muestra como las subclases heredan de las superclases y estas a su vez heredan de sus superclases y as sucesivamente. La clase Mueble tiene la caracterstica: movible, la clase Silla hereda esta caracterstica y agrega otra ms: sirve para sentarse. Finalmente, la clase Silla Plegable hereda caractersticas de todas sus clases superiores: movible, sirve para sentarse y agrega otra ms: Se puede plegar. De esta forma, no es necesario redefinir caractersticas (o sea, mtodos y atributos en las subclases siempre y cuando se hayan definido en las superclases. Mientras ms especfica sea una clase, tendr mayor cantidad de informacin. Una observacin: un programador no debe extender clases, a menos que realmente sea necesario, es decir, a menos que se agregue informacin a la superclase.

Figura 4.6 Herencia entre varias clases en la misma lnea jerrquica Ahora, la pregunta es Dnde est el reso de cdigo? Pues precisamente en el hecho de que no es necesario volver a escribir mtodos y atributos para las subclases. Una vez que un mtodo o atributo es definido en una clase, todas sus subclases heredarn esos mtodos y atributos. El reso de cdigo obviamente es muy importante pues permite ahorrar grandes cantidades de esfuerzo, tiempo y dinero. Pero Por qu no hacer desde un principio las clases lo suficientemente especficas?... Es decir Por qu no definir desde el principio las clases con toda la informacin para que no sea necesaria la creacin de clases ms especficas? Bueno la respuesta es que la programacin no es una actividad de una sola persona. Cuando un programador escribe un programa, se basa en el trabajo de otros programadores. Sera muy difcil escribir un programa desde cero. En particular, los programadores que escriben programas

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

78

orientados a objetos extienden clases escritas por otros programadores y les agregan caractersticas especficas al problema que desean resolver. La figura 4.7 ilustra esta idea. La figura 4.7 ilustra el hecho de que la programacin es una actividad colectiva en la cual los programadores se basan en el trabajo de otros programadores. En la figura 4.7 observamos que el programador de cierta compaa utiliza (extiende) una clase que le permite mostrar una ventana. La superclase (JFrame) fue creada por otro programador, el cual no conoce todos los detalles del tipo de ventana que ser finalmente utilizada. Sin embargo, conoce algunos atributos y mtodos que toda ventana debe tener. Por ejemplo, que la ventana debe tener mtodos para dibujarse, abrir, cerrar, cambiar de tamao, etc. As mismo, debe tener atributos como color de fondo, tamao, etc.

Figura 4.7 Programadores extendiendo clases de otros programadores Corresponde al programador de la compaa extender la ventana general agregando los detalles particulares de la compaa. Por ejemplo, la informacin que se mostrar en la ventana, el logotipo de la empresa, etc. La herencia es, entonces, un mecanismo muy importante para el reso de cdigo con lo cual los programadores ahorran una gran cantidad de esfuerzo al utilizar cdigo previamente escrito por otros programadores (o por ellos mismos). Permiso de Acceso Protegido Como se mencion anteriormente, el permiso de acceso pblico permite que cualquier clase desde cualquier paquete pueda tener acceso a los miembros pblicos de una clase, mientras que el mtodo de acceso privado prohbe cualquier acceso desde cualquier clase. Entonces una pregunta que podra surgir es No hay algo en medio? Es decir Existe alguna forma de acceso que no sea tan restrictiva como la privada pero tampoco tan relajada como la pblica? La respuesta es s. De hecho, existen otras dos formas de acceso de las que hablaremos un poco en sta y en la siguiente seccin.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

79

Supongamos que deseamos definir una clase cuyas subclases puedan heredar sus caractersticas (o sea, sus mtodos y atributos). Pero no deseamos ponerlos pblicos porque no queremos que cualquier clase tenga acceso a ellos. Qu podemos hacer? Respuesta: Utilizar el permiso de acceso protegido (protected). Este tipo de permiso otorga a cualquier subclase acceso a los mtodos y atributos de la superclase, aunque ambas estn en diferentes paquetes. La figura 4.8 muestra un ejemplo de cdigo que utiliza este tipo de permiso de acceso.

Figura 4.8 La clase Deportista con atributos protegidos La clase Deportista de la figura 4.8 fue diseada de tal forma que los atributos nombre y edad declarados en las lneas 3 y 4 slo pueden ser accedidos por subclases de esta clase. De esta forma, ninguna clase que no sea subclase de la clase Deportista (aunque est en el mismo paquete) puede tener acceso a estos atributos. La palabra protected a la izquierda del tipo del atributo establece este premiso de acceso. Las figuras 4.9 y 4.10 muestran las clases Futbolista y Nadador. Ambas clases extienden la clase Deportista y heredan sus atributos (nombre y edad) aunque cada una de las tres clases est en diferente paquete.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

80

Figura 4.9 Clase Futbolista que extiende la clase Deportista

Figura 4.10 Clase Nadador que extiende la clase Deportista Como puede observarse de las figuras 4.9 y 4.10, ambas clases (Futbolista y Nadador) extienden de Deportista y por lo tanto heredan los atributos (nombre y edad) de esta clase. Sin embargo, cada clase aade sus propios atributos. Por ejemplo, la clase Futbolista aade dos atributos: numeroCamiseta y posicin. Es importante sealar que estos atributos Slo tienen sentido para un futbolista! Un nadador no utiliza nmero de camiseta (Ni siquiera utiliza
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 81

camiseta!) ni posicin. De manera similar, los atributos especialidad y mejorTiempo slo tienen sentido en objetos de la clase Nadador. Algo que el lector puede observar es que los atributos de las subclases son privados (private). Esto significa que no deseamos que las subclases de estas clases los hereden. La figura 4.11 muestra la relacin entre las clases Deportista, Futbolista y Nadador utilizando la notacin UML Como puede verse en la figura 4.11, la herencia en POO se representa mediante una flecha que va de la subclase a la superclase. Esto significa que la clase de la cual sale la flecha extiende la clase a la que llega la flecha. Por lo tanto, todos los atributos y mtodos (que no sean privados) de la superclase pertenecen tambin a la subclase. En la figura 4.11 observamos tambin que se utilizan ciertos smbolos para representar el tipo de permiso de acceso de loa atributos y los mtodos de los objetos. Aunque tanto los libros como el software de diagramacin a menudo no coinciden en dichos smbolos, la especificacin de la versin 2.0 de UML establece que los smbolos para los tipos de permiso: pblico, privado, protegido y de paquete (este lo veremos en la siguiente seccin) son respectivamente: +, -, # y ~. La figura 4.11 no es del todo correcta con respecto al cdigo presentado para las clases Deportista, Futbolista y Nadador pues no representa el hecho de que estas clases estn en distintos paquetes. La figura 4.12 muestra las clases con sus respectivos paquetes.

Figura 4.11 Diagrama de Clases UML que muestra las clases Deportista, Futbolista y Nadador

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

82

Figura 4.12 Diagrama de Clases UML que muestra las clases Deportista, Futbolista y Nadador con sus respectivos paquetes

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

83

Finalmente, la figura 4.13 muestra la clase Main que crea dos deportistas y les asigna valores a sus atributos heredados y atributos propios. Tambin hace uso de mtodos heredados y mtodos propios.

Figura 4.13 Uso de las clases Futbolista y Nadador que heredan de la clase Deportista. Podemos ver en las lneas 3 y 4 que la clase Main debe importar las clases Futbolista y Nadador porque crea objetos de estas clases. Sin embargo, no es necesario importar la clase Deportista, porque esta clase es importada por cada una de las subclases (adems de que Deportista y Main estn en el mismo paquete).

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

84

Permiso de acceso de Paquete. Aunque el permiso de acceso de paquete (tambin llamado default en Java) no es necesariamente un tema relacionado con la herencia, lo hemos incluido en este captulo para completar los diferentes tipos de permisos de acceso. Hemos visto que el tipo de acceso pblico permite que los miembros de una clase puedan ser accedidos desde cualquier clase en cualquier paquete. Por otro lado, miembros privados slo pueden ser accedidos desde la misma clase. Finalmente, vimos que los miembros protegidos slo pueden ser accedidos por subclases de la clase a la que pertenecen. Existe an otro tipo de permiso de acceso que en Java es el default. Es decir, si no se escribe el tipo de acceso a la izquierda del mtodo o atributo, se asume este tipo de acceso. Se le llama acceso de paquete porque permite que las clases que estn en el mismo paquete tengan acceso a los miembros declarados con este tipo de permiso. El cdigo de la figura 4.15 compila y se ejecuta correctamente pues la clase Pago est en el mismo paquete que la clase Trabajador. De hecho, est en el mismo archivo. Todas las clases que estn en el mismo archivo, estn tambin en el mismo paquete pues un archivo slo puede pertenecer a un paquete.

Figura 4.15 Cdigo de las clases Trabajador y Pago Si colocamos la clase Pago en otro paquete como lo muestra la figura 4.16, el compilador nos marcara un error pues estamos tratando de acceder a los atributos con permiso de paquete desde una clase situada en otro paquete. El error producido por el compilador se muestra en la misma figura 4.17. Es interesante observar que a pesar de que si tenemos acceso a la clase Trabajador, no tenemos acceso a los atributos de los objetos de esa clase. Por esta razn, el error que marca el compilador es en la lnea 7 y no en la lnea 6. Es decir, podemos crear objetos de la clase Trabajador pero no podemos acceder a sus atributos. Por supuesto, ya sabemos que podramos tener acceso si escribimos un getter y un setter con permiso pblico, pero no es posible acceder a los atributos de manera directa.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 85

Figura 4.17 Cdigo de la clase Pago tratando de acceder a miembros con permiso de paquete de la clase Trabajador desde otro paquete Sobre-escritura de Mtodos. Regresemos al tema central de este captulo, que es la herencia. En muchas ocasiones, es necesario que una subclase redefina (o sobre escriba) un mtodo que fue definido en la superclase. Por ejemplo, supongamos que vamos a escribir cdigo para un videojuego el cual utiliza varios personajes, armas, niveles, naves, etc. Despus de determinar cules son las clases necesarias, Llegamos a la conclusin que necesitamos tener, entre muchas otras, una clase Arma y dos subclases: RifleLaser y LanzaFuego. La clase Arma debe tener un atributo carga que indique cuanta carga tiene (o sea, el porcentaje de carga de municiones o ammo como le llaman en los videojuegos) y un mtodo dispara() el cual realiza el disparo segn el tipo de arma. La figura 4.18 muestra el cdigo de estas clases. La lnea 5 de la figura 4.18 declara el mtodo dispara() de la clase Arma. Como este mtodo es pblico, es heredado por las subclases RifleLaser y LanzaFuego. Sin embargo, no es lo suficientemente explcito, pues deseamos que al disparar, cada arma indique como se est disparando. En el caso de el RifleLaser debe mencionar que se dispara un rayo laser y en el caso del LanzaFuego debe mencionar que se est lanzando fuego. Pero eso no es todo, al disparar, se disminuye la carga de manera diferente. El RifleLaser disminuye su carga 10% y el LanzaFuegos disminuye su carga 5%. Por esta razn, las clases RifleLaser y LanzaFuego tambin definen el mtodo dispara(). Al hecho de que una subclase redefina un mtodo de la superclase, se le llama sobre-escritura de mtodos. Lo anterior puede verse en las lneas 17-20 y 24-27 de la figura 4.18.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

86

El mtodo dispara() de la clase Arma ha sido sobre-escrito en las subclases LanzaFuego y RifleLaser. Qu repercusiones tiene sobre-escribir un mtodo? La respuesta la encontraremos al compilar y ejecutar el cdigo de la figura 4.19.

Figura 4.18 Cdigo de las clases Arma, RifleLaser y LanzaFuego Al compilar y ejecutar el cdigo de la figura 4.19, obtenemos el resultado esperado: Arma Disparando con 100% de intensidad! Disparando un rayo laser con 100 de intensidad! Lanzando fuego con 100% de intensidad! Las lneas 5, 6 y 7 de la figura 4.19 crean tres objetos las clases Arma, RifleLaser y LanzaFuego respectivamente. Al momento de llamar al mtodo dispara() de cada uno de los objetos de las subclases , lo cual se hace en las lneas 9 y 10, el mtodo que se ejecuta es el de la subclase. Entonces, podemos concluir que una subclase hereda los mtodos de las superclase, pero Si los mtodos son redefinidos (sobre-escritos) en la subclase, entonces el mtodo heredado se desecha y se utiliza el mtodo definido en la subclase. Qu pasara si eliminamos la definicin del mtodo dispara() de la clase LanzaFuego? Dejamos ese experimento al lector.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 87

Figura 4.19 Uso de las clases Arma, RifleLaser y LanzaFuego Clases Abstractas. En muchas ocasiones, un programador desea crear una clase y conoce cules son los atributos y los mtodos que deben tener los objetos de la clase. Sin embargo, desconoce la implementacin de algunos o de todos los mtodos. Para ilustrar este concepto, tomemos el mismo ejemplo de la seccin anterior. Si analizamos la clase Arma, podemos llegar a la conclusin que no tiene mucho sentido crear objetos de esta clase. La razn es muy simple Para qu crear un objeto de la clase Arma si podemos crear un objeto ms especfico como un RifleLaser o un LanzaFuegos? Adems, la carga se disminuye de manera diferente por cada disparo de cada tipo de arma (uno disminuye un 5% y el otro 10%). El mtodo dispara() de la clase Arma no disminuye la carga porque no se puede saber si el arma es un RifleLaser o un LanzaFuegos. Conclusin: no es conveniente crear objetos de la clase Arma. Por otro lado, si es conveniente crear la clase Arma porque tiene atributos (en esta caso, el atributo carga) que son heredados a sus subclases. Entonces, tenemos un dilema: Queremos crear una clase pero no queremos que se creen objetos a partir de esa clase y adems queremos definir un mtodo pero no queremos implementarlo en la clase sino ms bien que lo implementen las subclases. Lo que necesitamos es crear una clase abstracta. Una clase abstracta es aquella que puede tener mtodos abstractos y de la cual no se pueden crear objetos. Un mtodo abstracto es aquel en el cual slo se define el encabezado, es decir el nombre del mtodo, el tipo de retorno, los permisos de acceso y los parmetros. No se define el cuerpo del mtodo, es decir las instrucciones. La figura 4.20 muestra la clase Arma definida como abstracta.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

88

Figura 4.20 Definicin de la clase abstracta Arma y sus subclases LanzaFuego y RifleLaser La lnea 3 de la figura 4.20 define la clase Arma como abstracta. La lnea 6 de la misma figura define el mtodo dispara() como abstracto. Como puede verse, no se ha definido el cuerpo del mtodo, o sea, las instrucciones que se ejecutarn cuando se llame al mtodo. Si queremos ejecutar cdigo de la figura 4.19 con esta modificacin, nos producir un error de compilacin: C:\...\Main.java:5: armas.Arma is abstract; cannot be instantiated Arma a = new Arma(); 1 error El error anterior ocurre porque en la lnea 5 estamos tratando de crear un objeto de la clase Arma, la cual fue declarada como abstracta. Eliminando las lneas 5 y 8 de la figura 4.19, nos produce la salida esperada: Disparando un rayo laser con 100 de intensidad! Lanzando fuego con 100% de intensidad!

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

89

Debe quedar muy claro entonces que las clases abstractas no son intanciables. Es decir, no se pueden crear objetos de estas clases. Algo que es tambin muy importante sealar es que el programador que extiende una clase abstracta est obligado a implementar todos aquellos mtodos abstractos que son heredados a las subclases (siempre y cuando estas no sean abstractas). En el ejemplo de la clase Arma, las clases Lanzafuego y RifleLaser deben implementar el mtodo dispara(). Por ejemplo, si eliminamos las lneas 24-28 de la figura 4.20, el compilador marcar el siguiente error: armas.RifleLaser is not abstract and does not override abstract method dispara() in armas.Arma at armas.RifleLaser.<clinit>(Arma.java:23) Lo que est indicando el compilador es que el mtodo dispara() no ha sido implementado en la clase RifleLaser y debe ser implementado porque es un mtodo abstracto que pertenece a la superclase Arma. Tomemos por favor un tiempo para pensar un poco sobre esta obligacin que tienen las subclases (o ms bien los programadores que las programan) de implementar los mtodos abstractos de la superclases. Primero, hagamos una analoga: Recordemos que una clase es como el plano de una casa y el objeto es como la casa. Si le damos un plano de una casa incompleto a un constructor, obviamente No podr construir la casa! (Figura 4.21). Podemos ver a una clase abstracta como un plano incompleto pues los mtodos abstractos no tienen cuerpo. O sea, le falta informacin pues no est especificado cmo implementar estos mtodos. Por esta razn, el compilador marca error al momento de tratar de instanciar una clase abstracta o al momento de extender la clase abstracta sin implementar todos sus mtodos abstractos. Por un momento, supongamos que una subclase no implementa un mtodo abstracto de su superclase abstracta. Consideremos el cdigo de la figura 4.22. Este cdigo como ya lo habamos mencionado, marca un error. Pero supongamos que pudiramos compilar sin error. Como puede verse en la figura 4.22, el mtodo dispara() de la clase RifleLaser no se implement. La clase RifleLaser extiende de la clase Arma, y por lo tanto, hereda el mtodo abstracto dispara(). Entonces Qu pasar cuando se ejecute la lnea 31? El mundo como lo conocemos se acabara! Bueno, quizs no sera tan grave el resultado, pero si habra un grave problema porque la computadora no sabra qu hacer al momento de ejecutar el mtodo dispara() del objeto r de la clase RifleLaser. Ahora, podemos preguntarnos Es posible extender una clase abstracta en otra clase abstracta? La respuesta es s. Otra pregunta Es posible dejar mtodos sin implementar (abstractos) en la subclase abstracta? La respuesta es otra vez s. Por qu? Recordemos que una clase abstracta no es instanciable. Cuando un programador declara que una clase es abstracta es como si hiciera la promesa solemne: Juro que jams intentar crear un objeto de esta clase. Entonces el
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 90

compilador no tiene ningn problema en dejar que queden mtodos sin implementar porque nunca ocurrir la tragedia de que se llame un mtodo que no ha sido implementado. Una clase abstracta tambin puede tener mtodos concretos (o sea, implementados). De hecho, una clase abstracta puede tener TODOS sus mtodos implementados. Es un poco raro encontrar esta situacin en la vida real, pero es posible y perfectamente vlido.

Figura 4.21 Tratar de instanciar una clase abstracta es como tratar de construir una casa con un plano incompleto Si modificamos el cdigo de la figura 4.22, especficamente en la lnea 23, agregando la palabra abstract antes de la palabra class, el compilador ya no marcara el error: armas.RifleLaser is not abstract and does not override abstract method dispara() in armas.Arma at armas.RifleLaser.<clinit>(Arma.java:23) Esto es porque aunque estamos dejando sin implementar el mtodo dispara() de la clase RifleLaser, estaramos tambin declarando la clase RifleLaser como abstracta. Pero ahora marcara otro error: armas.RifleLaser is abstract; cannot be instantiated at armas.Main.main(Main.java:31) Ahora obtenemos este error porque estamos tratando de instanciar la clase RifleLaser la cual fue declarada como abstracta.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

91

Para aquellos que no estn muy interesados en el porqu de las cosas, a continuacin mostramos una serie de reglas que se deben de recordar al momento de escribir un programa que utiliza clases abstractas. Si en algn momento, se despierta este inters, favor de leer las secciones anteriores.

Figura 4.22 Extendiendo una clase abstracta sin implementar (sobre-escribir) su mtodo abstracto Reglas para programar con clases abstractas: 1. Las clases abstractas no se pueden instanciar. 2. Las clases abstractas pueden tener mtodos abstractos. 3. Las clases concretas (o sea las que no son abstractas) no pueden tener mtodos abstractos.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 92

4. (Esta es consecuencia de la anterior) las clases concretas que extienden clases abstractas deben implementar todos los mtodos abstractos de las superclases. 5. Las clases abstractas pueden tener todos sus mtodos implementados.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

93

Interfaces. Recordemos que el objetivo de la Programacin Orientada a Objetos es modelar la realidad en la computadora. Existe otro concepto en la realidad que es muy til y que los lenguajes de programacin nos permiten de alguna o de otra forma modelarlo. Este concepto es la Herencia Mltiple. Ponindolo de manera muy simple, la herencia mltiple consiste en el hecho de que una subclase tenga dos o ms superclases. Por ejemplo, un telfono inteligente (smartphone) es un dispositivo de comunicaciones y por lo tanto tiene ciertas funciones que permiten la comunicacin entre personas como realizar y recibir llamadas, envo y recepcin de mensajes entre otros. Sin embargo, un smartphone tambin es un dispositivo de entretenimiento y por lo tanto, hereda tambin funciones de este tipo de dispositivos como son: reproducir msica, reproducir videos, mostrar imgenes, etc. (Figura 4.23)

Figura 4.23 Ejemplo de un objeto cuya clase tiene dos superclases Podemos entonces decir que un Smartphone es una subclase de Telfono pero tambin es una subclase de DispositivoEntretenimento. La figura 4.24 muestra el Diagrama de Clases de esta relacin de herencia mltiple. En este ejemplo, nos referimos a un dispositivo de entretenimiento de video, como podra ser un reproductor de DVD o un videojuego conectado a una pantalla de televisin por supuesto. Por un lado, los telfonos tienen el volumen del timbre como atributo y permiten realizar llamadas. Por otro lado, los dispositivos de entretenimiento (en este caso un reproductor de video) tienen como atributo la resolucin, o sea las dimensiones en
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 94

pixeles con la que reproducen el video, y la funcin de reproducir el video. El smartphone tiene todos estos atributos y estas funciones y adems tiene las propias del smartphone como son el tamao en pixeles con las que toma las fotos y la funcin de enviar la ubicacin o posicin en donde se encuentra la persona a travs de un sistema de posicionamiento global (GPS)

Figura 4.24 Diagrama de Clases del Ejemplo de Herencia Mltiple La figura 4.24 muestra que la clase Smartphone es subclase de Telfono y de DispositivoEntretenimiento. Por lo tanto, hereda todos los atributos y mtodos de ambas clases. Podemos estar tentados a escribir el siguiente cdigo:

class Smartphone extends Telfono, DispositivoEntretenimiento { }

Sin embargo, el cdigo de arriba es errneo en Java porque Java no permite la herencia mltiple. La razn por la cual no la permite tiene que ver con uno de los objetivos del lenguaje, que es su simplicidad. La herencia mltiple, a pesar de que es un concepto muy importante, tambin trae problemas inherentes a l, como por ejemplo, el problema del Diamante Mortal (Deadly Diamond of Dead). Este problema sucede cuando dos o ms superclases tienen atributos o mtodos con el mismo nombre. En este caso, hay ambigedad sobre cul de los atributos o mtodos se hereda. La figura 4.25 muestra el problema del diamante mortal con un ejemplo. La figura 4.25 muestra una situacin en la cual una clase tiene dos subclases. La clase Trabajador contiene el mtodo calculaPago(). Las clases Docente y
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 95

Administrativo, las cuales son subclases de Trabajador, sobre-escriben dicho mtodo. Finalmente, la clase AdministrativoDocente Hereda el mtodo calculaPago() de las dos superclases! El problema est en la ambigedad sobre cul de los mtodos calculaPago() debe escogerse.

Figura 4.25 El problema del Diamante Mortal en la Herencia Mltiple Hemos establecido que Java no permite la Herencia Mltiple. Entonces Cmo podemos modelar el hecho de que un objeto de cierta clase pueda heredar caractersticas de dos o ms clases? A travs del uso de interfaces. Una interface en Java es un tipo especial de clase abstracta en la cual todos sus mtodos son abstractos. Existen algunas caractersticas adicionales de las interfaces, pero por lo pronto, tomaremos la definicin anterior. Las interfaces no pueden tener mtodos concretos. Es decir, cuando un programador crea una interface, solamente define cuales sern los mtodos que debern ser implementados por las clases que implementen la interface y no define el cuerpo, o sea, las instrucciones que tienen cada mtodo. Regresemos al ejemplo del videojuego. Tenemos la clase Arma, la cual es abstracta porque sabemos que las armas deben disparar pero no podemos determinar a detalle cmo hacerlo, ya que cada subclase de esta clase abstracta dispara de manera diferente (ver figura 4.22). Las implementaciones del mtodo dispara() se encuentran en cada una de las subclases RifleLaser y LanzaFuegos. Supongamos que hemos decidido que un objeto de la clase LanzaFuegos puede ser recargado si el personaje que lo usa encuentra un tanque de gas. Sin embargo, un RifleLaser no hay
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 96

forma de recargarlo, pues la batera atmica no es reemplazable. Adems, el LanzaFuegos no es el nico objeto recargable. Existen otros objetos recargables como son: Linterna y LanzaGranadas, entre otros. La figura 4.26 muestra estos objetos y sus caractersticas.

Figura 4.26 Algunos Objetos de un Videojuego y sus Caractersticas Los objetos recargables tienen cierto comportamiento similar, o sea, se pueden recargar. Entonces podramos crear la clase abstracta Recargable con su mtodo recargar()para que todas las clases hereden este mtodo. Sin embargo, los objetos de la clase LanzaFuego tambin son armas (de la clase Arma). Entonces Tenemos un caso de herencia mltiple! En Java, no se permite la herencia mltiple, es decir, no podemos tener la clase LanzaFuego como subclase de las clases Arma y Recargable. Sin embargo, podemos crear la clase Recargable como una interface y especificar que un LanzaFuego es una Arma pero tambin se comporta como un objeto Recargable. La figura 4.27 muestra cmo hacer esto en Java. La lnea 18 de la figura 4.27 declara la clase LanzaFuego extiende la clase Arma e implementa la interface Recargable. Esto significa que los objetos de la clase LanzaFuego se comportarn como Armas pero tambin se comportarn como objetos Recargables. Como se indica en la figura 4.27, cuando una clase (concreta) extiende una clase abstracta y/o implementa una interface, debe de implementar todos los mtodos abstractos heredados de ellas, de lo contrario el programa no compila. Por qu? Porque las clases concretas son instanciables (es decir, se pueden crear objetos de estas clases) entonces, si no se implementaran todos los mtodos abstractos Crearamos objetos incompletos! (ver figura 4.21).

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

97

La lnea 14 de la figura 4.27 declara la interface recargable. Las interfaces se declaran de manera muy similar que las clases, incluso tambin pueden extender otras interfaces. Sin embargo, la principal diferencia entre las clases y las interfaces es que TODOS los mtodos de las interfaces deben ser abstractos. De hecho, aunque no se ponga la palabra abstract se asume que el mtodo es abstracto (y pblico). Finalmente, observamos que la lnea 48 de la figura 4.27 declara la clase Linterna. Esta declaracin no contiene la palabra extends. Esto no significa que la clase Linterna no tenga ninguna superclase. Existe una clase que es superclase de todas las clases. sta clase se llama Object. Si en la declaracin de una clase, se omite la palabra extends entonces se asume que esa clase extiende de la clase Object. Sin embargo, la lnea 48 si contiene la palabra implements. Esto significa que la clase Linterna est implementando la interface Recargable. Por lo cual, debe implementar el mtodo recargar(). Resumiendo lo anterior, en la Programacin Orientada a Objetos, tenemos el concepto de herencia mltiple. La herencia mltiple se da cuando un objeto puede heredar caractersticas de varias clases. Por ejemplo, tenemos armas que tambin son objetos recargables. Sin embargo, Java no permite la herencia mltiple, la forma de representar este concepto es a travs del uso de interfaces. Una interface es un tipo de clase abstracta en la cual TODOS los mtodos son abstractos. Otro aspecto importante de la implementacin del concepto de herencia en el lenguaje Java es que una clase slo puede extender otra, pero puede implementar muchas interfaces. Tantas como sean necesarias. Por ejemplo, en el caso de que el LanzaFuego implementara tambin la interface Destructuble (objetos que pueden ser destruidos). Entonces slo agregaramos esta nueva interface a la lnea 18:
class LanzaFuego extends Arma implements Recargable, Destructible {

El lector podra entonces hacerse la pregunta Cmo se evita el problema del diamante mortal, si de cualquier forma se permite que se hereden mtodos abstractos de varias interfaces? La respuesta es muy simple: Las interfaces no pueden tener implementados sus mtodos. Entonces, an en el caso de que una clase implementara varias interfaces con mtodos con el mismo nombre Solo podra haber una implementacin!... Problema resuelto! (Ver Figura 4.28) En la figura 4.28 vemos un diagrama UML de clases que muestra dos interfaces: VehiculoMotorizado y ObjetoInflamable. Ambas interfaces tienen el mtodo abstracto encender(). Obviamente, aunque el mtodo se llama igual en las dos interfaces, tiene un significado diferente pues en el caso del vehculo se refiere a ponerlo en marcha mientras que en el caso del objeto inflamable se refiere a que comience a arder en llamas. En la misma figura, observamos la clase Automovil. sta clase implementa ambas interfaces, por lo cual hereda el mtodo abstracto encender(). A pesar de esta ambigedad, se puede escribir un programa que
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 98

represente estas relaciones sin ningn problema pues se tendr que definir la implementacin del mtodo en la clase Automovil. Finalmente, vemos que en UML, se utilizan cursivas para representar clases y mtodos abstractos. Las interfaces se representan agregando adems de las letras cursivas, la leyenda: <<interface>> en la parte superior. La implementacin de una interface se representa por medio de una flecha punteada de la clase a la interface. Utilizando las Clases del Videojuego Regresemos al ejemplo del videojuego. Supongamos ahora un escenario en el cual el soldado, el cual es el personaje principal, comienza disparando todas sus armas y posteriormente entra a una estacin de recarga en la cual puede recargar todas sus armas. La linterna inicialmente no tiene batera, pero tambin se recarga en la estacin. Las figuras 4.29 y 4.30 muestran el cdigo de las clases Soldado y Escenario.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

99

Figura 4.27 Uso de Interfaces en Java

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

100

Figura 4.28 Diagrama UML de clases que muestra la clase Automovil implementando dos interfaces con el mismo mtodo abstracto. El cdigo de las figuras 4.29 y 4.30 se encuentra en el mismo archivo de la figura 4.27. Por esta razn los nmeros de lnea continan. Debido a que tanto el RifleLaser como el LanzaFuego y el LanzaGranada extienden la clase abstracta Arma, estamos seguros que los tres objetos tienen el mtodo dispara(). De lo contrario, el programa no compilara. Esto lo podemos ver en las lneas 77, 78 y 79 de la figura 4.29. Por otro lado, el mtodo recargaTodo() que est implementado en las lneas 81 a 86 de la figura 4.29, manda llamar al mtodo recargar()de los objetos que implementan la interface Recargable (LanzaFuego, LanzaGranada y Linterna). Finalmente, el mtodo muestraEstado() muestra en la consola de la computadora el nivel de carga de las armas y el nivel de batera de la linterna. Observe que el mtodo getCarga() fue implementado en la clase Linterna pues dicho mtodo no fue heredado de la clase Arma porque la Linterna no es una arma! En otras palabras, Linterna no extiende Arma como puede verse en la lnea 48 de la figura 4.27. Slo implementa la interface Recargable.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 101

Figura 4.29 Clase Soldado que utiliza las clases LanzaFuego, LanzaGranada, RifleLaser y Linterna La figura 4.30 muestra la clase Escenario, la cual implementa el escenario descrito anteriormente. Primero, se crea el objeto de la clase Soldado (Figura 4.30, lnea 100). Posteriormente, se crean los tres objetos correspondientes a sus armas (lneas 102 a 104). La lnea 105 crea la linterna. Las lneas 107 a 110 utilizan los setters de la clase Soldado para asignar los valores de los atributos. Finalmente, las lneas 112 a 115 llaman los mtodos que disparan las armas, muestran el estado, recargan el equipo y vuelven a mostrar el estado.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

102

La salida de la ejecucin del cdigo de las figuras 4.27, 4.29 y 4.30 se muestra en la figura 4.31.

Figura 4.30 Cdigo de la clase Escenario la cual crea un Soldado con su equipo y lo pone en accin.

Figura 4.31 Salida de la Ejecucin del cdigo de la clase Escenario

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

103

Polimorfismo Aunque existen varios tipos de Polimorfismo, en esta seccin nos referiremos al polimorfismo de subtipos al que comnmente se le conoce simplemente como polimorfismo. Antes de dar una definicin del concepto, consideremos el siguiente ejemplo. Supongamos que queremos modelar el funcionamiento de un restaurante de comida internacional. Los clientes pueden encontrar comida mexicana, china e italiana entre otras. Obviamente, se esperan clientes de varias nacionalidades y por lo tanto el restaurante debe estar preparado para atender a cada uno de ellos. Los meseros del restaurante hablan varios idiomas y sirven comida de acuerdo a la nacionalidad del cliente. Por ejemplo, a un mexicano le servirn tacos, a un chino arroz y aun italiano pizza. El modelado del problema lo haremos a travs de las clases Mesero, Cliente, Chino, Mexicano e Italiano como se muestra en la figura 4.32.

Figura 4.32. Modelado del Restaurante Internacional La figura 4.32 muestra la clase Mesero, la cual tiene 3 mtodos Los mtodos son: atiende(Chino), atiende(Mexicano) y atiende(Italiano). Recordemos que cuando sobrecargamos un mtodo, escribimos el mismo nombre del mtodo pero con diferentes parmetros. En este caso, escribimos un mtodo para cada diferente tipo de cliente que llegue al restaurante. Tambin podemos observar que las clases Italiano, Mexicano y Chino son subclases de la clase abstracta Cliente. Finalmente, observamos que la clase Cliente y sus subclases tienen un constructor que les permite asignar inicialmente el nombre del cliente. Las figuras 4.33 a 4.38 muestran el cdigo de las clases mostradas en la figura 4.32. La figura 4.39 muestra el resultado de la ejecucin de la clase Main la cual crea un mesero, tres clientes y llama al mtodo atiende() para cada uno de los clientes.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

104

Figura 4.33 Cdigo de la clase Cliente Podemos observar en la figura 4.33, que se declara la clase abstracta Cliente en la lnea 3 aunque no contiene mtodos abstractos. En este caso, la razn por la que fue declarada abstracta no es que la clase tenga mtodos abstractos. De hecho, tenemos toda la informacin de los clientes (atributos y mtodos). La razn por la cual la creamos abstracta es porque no queremos crear objetos de la clase Cliente en el programa. Puede haber situaciones en la cuales el programador podra desear crear objetos tanto de la superclase como de las subclases, pero este no es el caso.

Figura 4.34 Cdigo de la clase Chino La lnea 5 de la figura 4.34 hace un llamado al mtodo super(String). La palabra super se utiliza en Java para referirse a la superclase. Cuando se crea un objeto de la clase Chino, se ejecuta el constructor de la clase Chino (lnea 4). El constructor de la clase Chino, a su vez llama al constructor de la clase Cliente (Cliente es superclase de Chino).
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 105

Figura 4.35 Cdigo de la clase Italiano

Figura 4.36 Cdigo de la clase Mexicano

Figura 4.37 Cdigo de la clase Mesero con el mtodo sobrecargado atiende()

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

106

La figura 4.37 muestra el cdigo de la clase Mesero con el mtodo atiende() sobrecargado (lneas 4, 7 y 10) de tal forma que el mensaje que se muestra depende del tipo de objeto que se enva como parmetro al mtodo atiende().

Figura 4.38 Cdigo de la clase Main que modela el Restaurante de Comida Internacional

Figura 4.39 Salida de la Ejecucin del Cdigo de la figura 4.38

Y el Polimorfismo? El ejemplo anterior modela el funcionamiento del Restaurante Internacional sin polimorfismo. Sin embargo, nos servir para entender el concepto de polimorfismo y tambin el porqu es un concepto tan importante y til en la programacin orientada a objetos. Primero, veremos el problema de modelar el Restaurante de la forma descrita arriba.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

107

Supongamos ahora que el dueo del restaurante decide agregar comida espaola a sus platillos. Qu tendramos que hacer para adecuar el cdigo a este nuevo requerimiento? Pues... Tendramos que agregar otro mtodo atiende(Espaol)a la clase Mesero. Adems. Claro de crear la clase Espaol la cual por supuesto extiende la clase Cliente. Lo anterior puede ser un problema pues modificar cdigo puede causar errores en un programa que ya haba sido probado. Por otro lado, si optamos por esta opcin, cada vez que se agregue un tipo de comida al restaurante, ser necesario modificar la clase Mesero para agregarle un nuevo mtodo atiende(). Por ejemplo, Si el restaurante llegara a tener 10 tipos diferentes de clientes, entonces Tendramos que sobrecargar el mtodo atiende() 10 veces Otro problema, el cual es igualmente importante, es que El mesero es quien decide que comida debe servir de acuerdo a la nacionalidad No sera ms conveniente que fuera el propio cliente quien decidiera la comida tpica de su pas? Usaremos polimorfismo para resolver los dos problemas que acabamos de describir. Podemos decir de manera muy simple que el polimorfismo permite que un objeto pueda tomar varias formas. En esta nueva solucin, definiremos un solo mtodo atiende(Cliente)para cualquier tipo de cliente. Adems, es el propio cliente (o ms bien el programador de la clase Cliente) quien decide el tipo de comida que se servir. Para lograr lo anterior, necesitamos que cada subclase de Cliente implemente su propio mtodo en el cul se especifique que tipo de comida desea que le sirvan. Este mtodo es pideComida(). La figura 4.40 muestra un diagrama UML de clases con otro enfoque al problema del Restaurante de Comida Internacional utilizando polimorfismo. El mtodo atiende(Cliente) de la clase Mesero de la figura 4.40 puede aceptar cualquier tipo de cliente como parmetro. Como puede observarse en la figura, el parmetro cl es de tipo Cliente. Precisamente es ah en donde radica el polimorfismo, pues el objeto que se enva al mtodo atiende(Cliente) puede tomar varias formas. Puede ser un objeto de cualquiera de las clases Chino, Italiano o Mexicano. Por eso se llama polimorfismo, porque el objeto puede tomar varias formas. La variable cl se llama variable polimrfica porque puede contener objetos de diferentes tipos. Tambin observamos que las clases Chino, Mexicano e Italiano tienen implementado el mtodo pideComida(). Lo anterior significa que hemos dejado la responsabilidad de decidir que comida servir al creador de cada una de las subclases de Cliente y no al de la clase Mesero. Esto es muy importante, pues nunca necesitaremos modificar la clase Mesero Si el restaurante, en un futuro lejano o cercano desea servir otro tipo de comida: espaola, francesa, rabe o cualquier otro tipo, slo ser necesario crear la clase Espaol (o cualquiera de las otras) que ser subclase de de Cliente e implementar el mtodo pideComida() para esta nueva clase.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 108

Figura 4.40 Modelado del Restaurante Internacional Utilizando Polimorfismo

Figura 4.41 El Polimorfismo en el Restaurante Internacional


Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 109

La figura 4.41 ilustra el concepto de polimorfismo para el ejemplo del restaurante. El objeto de la clase Cliente puede tomar cualquiera de las formas (Mexicano, Chino o Italiano). Cada una de estas formas que puede tomar el objeto tiene sus propias preferencias de comida especificadas en el mtodo pideComida() (ver figura 4.40) Las figuras 4.42 a 4.45 muestran el cdigo que implementa el polimorfismo para el modelado del Restaurante Internacional.

Figura 4.42 Cdigo de la clase Cliente con el mtodo abstracto pideComida() La figura 4.43 muestra el cdigo de las clases Chino, Mexicano e Italiano. Por motivos de espacio pusimos las tres clases en la misma figura, pero cada clase se tiene que colocar en un archivo diferente (por esa razn la numeracin comienza en cada clase). Como puede verse en la figura 4.43, cada una de las subclases de la clase Cliente implementa el mtodo pideComida(). Esta implementacin es obligatoria pues el mtodo pideComida() el cual es heredado de la clase Cliente, es abstracto y por lo tanto es necesario sobre-escribirlo. Si el mtodo no fuera sobre-escrito, el compilador marcara un error al momento de intentar compilar las clases. La razn de este error fue explicada un poco antes en este mismo captulo. En la figura 4.43, la lnea 9 de la clase Chino y 8 de las clases Italiano y Mexicano llaman al mtodo getNombre()para mostrar el nombre del cliente que est siendo servido en el restaurante. Anteriormente, tenamos que hacer referencia al objeto para poder llamar a este mtodo. Esto puede verse en las lneas 5, 8 y 11 de la figura 4.37. Cuando llamamos a un mtodo de un objeto, necesitamos hacer referencia al objeto, es decir necesitamos usar la sintaxis objeto.metodo(). Sin embargo, en el cdigo de la figura 4.43 omitimos la referencia al objeto. Esto se debe a que cuando un mtodo de un objeto llama a otro mtodo, se asume que ambos

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

110

mtodos pertenecen al mismo objeto. Opcionalmente se puede utilizar la palabra this, como ya lo vimos anteriormente, para hacer referencia al objeto.

Figura 4.43 Cdigo de las clases Chino, Italiano y Mexicano que implementan el mtodo pideComida() La figura 4.44 muestra el cdigo de la clase Mesero. Como puede verse en la figura, el parmetro cl del mtodo atiende(Cliente) es polimrfico. Esto significa que recibe objetos de distintas subclases de la clase con la cual fue declarado y por lo tanto, los mtodos que se llamen pertenecern a las subclases y no a la superclase. Como lo hemos mencionado anteriormente, la gran ventaja del uso de polimorfismo en el cdigo de la figura 4.44 es que este cdigo no tiene que modificarse cuando se agreguen ms
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 111

nacionalidades a las que se pueden atender en el restaurante. Esto es tan importante, que vale la pena mencionarlo repetidamente. Al recibir un objeto del tipo Cliente, la nica funcin del mtodo atiende(Cliente) como puede verse en la lnea 5, es llamar al mtodo pideComida() del objeto que se recibi como parmetro.

Figura 4.44 Cdigo de la clase Mesero que utiliza polimorfismo en el mtodo atiende(Cliente) De esta manera, es responsabilidad del cliente y no del mesero, decidir la comida que se servir. De hecho, esta forma de modelar el problema representa ms fielmente la realidad del funcionamiento de un restaurante. La figura 4.45 muestra el cdigo de la clase Main. La nica diferencia entre este cdigo y el de la figura 4.38 est en la forma de declarar las variables en las lneas 10,11 y 12. En el cdigo de la figura 4.45 se crean los objetos declarando las variables ch, mx e it de tipo Cliente pero se llaman a los constructores de las clases Chino, Mexicano e Italiano respectivamente. Esto es algo perfectamente vlido pues las clases Chino, Mexicano e Italiano son subclases de la clase Cliente. El mtodo atiende(Cliente) puede recibir cualquiera de las tres variables directamente pues las tres han sido declaradas con la clase Cliente.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

112

Figura 4.45 Cdigo de la clase Main que modela el funcionamiento del Restaurante Internacional

En resumen, el polimorfismo nos permite tratar a los objetos de subclases como si fueran de la superclase pero al momento de llamar a los mtodos de stos objetos, se ejecutan los mtodos sobre-escritos en las subclases y no los de la superclase. Sin embargo, no sucede lo mismo con los atributos. Si la subclase tiene definidos atributos que no pertenecen a la superclase, stos no sern visibles a menos que se realice una transformacin del objeto a la clase con la que fue creado. A esta transformacin se le llama cast y lo veremos ms adelante en el libro. Retorno Covariante Hemos visto que un objeto cierta clase puede ser enviado como argumento a un mtodo que recibe argumentos de la superclase. Por ejemplo, podemos enviar un objeto de la clase Perro a un mtodo que espera objetos de la clase Animal. Algo similar podemos hacer al regresar objetos en los mtodos. El lenguaje Java permite el retorno covariante. Podemos decir de manera muy simple que si un mtodo es sobre-escrito, el tipo de retorno del mtodo de la subclase puede ser a su vez subclase del tipo de retorno del mtodo que se est sobre-escribiendo. Esto se ilustra con un ejemplo en la figura 4.46

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

113

Figura 4.46 Ejemplo de Retorno Covariante Las clases FabricaFiguras de la figura 4.46 tiene un mtodo hazFigura() que regresa un objeto de la clase Figura (lneas 5-7). Este mtodo es sobre-escrito en la clase FabricaCuadrado y el objeto que regresa su mtodo hazFigura() (lneas 12 a 14) es de la clase Cuadrado, que es subclase de Figura. Esta caracterstica de los lenguajes orientados a objetos permite que los mtodos sobre-escritos tengan ms flexibilidad en los tipos de retorno y que ambos mtodos (o sea, el de la superclase y el de la subclase) puedan ser de diferentes tipos de retorno. Siempre y cuando el tipo de retorno del mtodo sobre-escrito sea superclase del tipo de retorno del mtodo que sobre-escribe. Un ejemplo de la utilidad de esta caracterstica podra ser que en el ejemplo del videojuego existiera una clase FabricaDeArmas con su mtodo crearArma(). sta clase la podramos especializar en varias clases para fabricar armas especficas, cada una con su respectivo mtodo crearArma() el cual regresara el tipo especfico de arma. Clases Finales En algunas ocasiones, se puede presentar la necesidad de que el programador de cierta clase no desee que la clase pueda ser extendida. Supongamos por ejemplo, que la clase RifleLaser del ejemplo del videojuego presentado anteriormente es lo suficientemente especializada y no debe ser extendida pues no se desea tener ningn tipo especial de RifleLaser. Entonces, Podemos
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 114

prohibir que una clase pueda ser extendida agregando la palabra final a la declaracin de la clase. Para el ejemplo de la clase RifleLaser, el cdigo sera el siguiente: public final class RifleLaser extends Arma {} Al hacer lo anterior, sera imposible extender la clase RifleLaser. Por ejemplo, el siguiente cdigo: class RifleLaserGalactico extends RifleLaser {} Marcara el error: Cannot inherit from final RifleLaser El error est indicando que la clase RifleLaser fue declarada como final por lo tanto no se puede extender. Una de las principales razones para declarar una clase como final es seguridad. Esto es debido a que las clases finales no pueden tener mtodos sobre-escritos. Entonces, de esta forma nos aseguramos que los mtodos que se ejecutan pertenecen a la clase y no existe la posibilidad de ejecutar un mto sobre-escrito por alguna de las subclases. El Ejemplo de la Nmina Revisitado En esta seccin presentaremos nuevamente el ejemplo de la nmina utilizando ahora herencia, polimorfismo y otros conceptos relacionados. Empezaremos describiendo nuevamente el problema con algunos cambios en los requerimientos que harn necesario el uso de los conceptos vistos en este captulo.

Se desea construir un programa que calcule el pago a los trabajadores de una empresa. Existen dos tipos de trabajadores: obreros y supervisores. La empresa cuenta actualmente con 10 trabajadores (8 obreros y 2 supervisores). Ver la siguiente tabla:

Nombre Armando Paredes Cindy Nero Alan Brito Marco Lpez Rosario Mrquez Sergio Martnez

Salario por Hora 60 50 40 55 180 75

Horas Trabajadas 40 35 48 40 40 38

Tipo Obrero Obrero Obrero Obrero Supervisor Obrero

Premio
100 50 ---

Descuento

150 120
115

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

Luisa Domnguez Petra Barrera Manuel Flores Alma Ros

50 55 65 175

30 40 35 40

Obrero Obrero Obrero Supervisor

110 -------

Adems de su salario normal, los trabajadores reciben un bono adicional (500 los supervisores y 300 los obreros) el cual se modifica peridicamente pero es el mismo para todos los trabajadores del mismo tipo. Cada obrero puede obtener un premio por productividad mensual el cual es determinado por el supervisor. Los supervisores que han pedido un prstamo se les hace un descuento semanal. Los obreros no pueden pedir prstamos y los supervisores no tienen premios. La entrada al sistema son las horas trabajadas por semana, el salario por hora, el premio (en el caso de los obreros) y el descuento (en el caso de los supervisores). El programa deber producir el pago semanal y el total pagado en esa semana. La salida del programa ser similar a la mostrada en la figura 4.47.

Figura 4.47 Nmina Semanal de la Empresa Acme

Anlisis del problema. El problema a resolver es bsicamente el clculo del pago a los trabajadores. Este problema ya lo habamos resuelto anteriormente. Sin embargo, existen nuevos requerimientos que nos obligan a replantear nuestras clases. A continuacin presentamos una lista de ellos: 1. 2. 3. 4. Ahora tenemos dos tipos de trabajadores: obreros y supervisores Todos los obreros tienen un bono de 300 pesos Todos los supervisores tienen un bono de 500 pesos Los obreros pueden tener premios que varan de acuerdo a su desempeo
Hctor A. Andrade G. 116

Conceptos de Programacin Orientada a Objetos

5. Los supervisores pueden tener descuentos por prstamos que les fueron otorgados Para satisfacer el requerimiento uno, podemos crear dos clases que extienden la clase Trabajador: Obrero y Supervisor. Los requerimientos dos y tres los podramos resolver definiendo atributos de clase (estticos) para cada clase. Podramos definir un atributo esttico bono para cada una de las clases y de esta manera cuando se cambie el valor del bono solo tendramos que modificarlo una vez, pues el atributo pertenecera a la clase y no a cada uno de los obreros y supervisores. Los requerimientos tres y cuatro indican que la forma de calcular el pago es diferente para los supervisores que para los obreros. Entonces, podemos utilizar polimorfismo para que un Trabajador pueda tomar la forma de un Supervisor o de un Obrero y que el pago sea calculado de acuerdo a su tipo de Trabajador. Adems de las clases mencionadas anteriormente, hemos decidido incluir la clase Impresora que se encargar de imprimir o mostrar la informacin en la consola de la computadora. Otra clase que consideramos necesaria para un buen diseo es la clase BaseDatos. sta clase se encargar de cargar la informacin al arreglo de trabajadores. Finalmente, la clase Main que arranca la ejecucin del programa. La figura 4.48 muestra las clases que utilizaremos y una breve explicacin de sus responsabilidades o sea cules son sus funciones dentro del programa. Es generalmente una buena idea hacer un diagrama que muestre de manera preliminar cuales sern las clases del nuestro diseo. Puede describirse tambin en este diagrama las responsabilidades que tendrn dentro del programa as como las relaciones entre ellas. Como puede observarse en la figura 4.48, no todas las clases que se implementarn en el programa fueron mencionadas en la definicin del problema. Por ejemplo, las clases Impresora, Main y BaseDatos no pertenecen realmente al dominio del problema. Decidimos incluirlas porque, para este problema, existen funciones que no quedan muy bien en ninguna de las clases del mundo real. Por esta razn, las colocamos en el paquete etc como se muestra en la figura 4.49. Lo contrario tambin es posible. Podramos tener clases mencionadas en el problema que no son necesarias en diseo de la solucin del mismo. Por ejemplo, no consideramos necesario incluir la clase Empresa en el diseo de la solucin de este problema.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

117

Figura 4.48 Clases y sus Responsabilidades para el Sistema de Nmina La figura 4.49 muestra el diagrama de clases de la solucin al problema de la nmina. Hemos estado introduciendo ms notaciones a los diagramas UML. Es muy importante dominar la nomenclatura de este lenguaje pues con l se expresan prcticamente todos los conceptos que hemos visto hasta ahora. Adems, es un lenguaje universalmente aceptado para expresar tanto los dominios de los problemas como las soluciones a los mismos. En la figura 4.49 podemos ver las clases que intervienen en la solucin del problema, as como sus relaciones, los atributos y mtodos, los permisos de acceso a los mismos, los atributos y mtodos estticos, etc. Algo importante que debemos discutir sobre el diseo presentado en la figura 4.49 es que algunas clases slo contienen mtodos estticos como por ejemplo Main, Impresora y BaseDatos. Una pregunta que podemos hacernos es Cundo debemos utilizar mtodos estticos? Hay alguna ventaja? Qu pasara si en lugar de mtodos estticos (o sea, de clase) hubisemos utilizado mtodos de instancia? Trataremos de responder a estas preguntas pero antes debemos aclarar que la decisin del uso de mtodos estticos tiene que ver con eficiencia y con elegancia
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 118

en el diseo y NO con funcionalidad. Lo que significa esto es que podramos omitir en la mayora de los casos los mtodos estticos y utilizar solamente mtodos de instancia y viceversa. En este caso en particular, no es necesario crear un objeto de la clase Impresora porque realmente la impresora no tiene datos ni atributos que sean tiles y lo mismo pasa con las clases Main y BaseDatos. Por otro lado, las clases Obrero y Supervisor s contienen datos de cada trabajador. Por lo tanto, cada trabajador maneja datos diferentes (sus propios datos) y es conveniente que los mtodos que accedan a stos datos sean de instancia y no estticos. Respondiendo a la segunda pregunta. Si utilizramos mtodos de instancia en estas clases, entonces tendramos que crear los objetos para poder utilizarlas, lo cual sera ineficiente pues los objetos estaran ocupando un lugar en la memoria sin que realmente se utilice.

Figura 4.49 Diagrama de Clases del Diseo del Programa de Nmina Las figuras 4.50 a 4.55 contienen los cdigos de las clases mencionadas anteriormente. Cada clase es pblica, por lo que deber estar grabada en un archivo con el nombre de la clase y la extensin java. Cmo los cdigos estn en dos diferentes paquetes, se tienen que crear sendos subdirectorios, uno por cada paquete.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

119

Figura 4.50 Cdigo de la clase Trabajador del Ejemplo de la Nmina

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

120

Figura 4.51 Cdigo de la Clase Supervisor

Figura 4.52 Cdigo de la Clase Obrero

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

121

Figura 4.53 Cdigo de la Clase BaseDatos En la figura 4.54 podemos observar que el mtodo imprimeDetalle(Trabajador) de la clase Impresora, recibe un objeto de la clase Trabajador. Esto puede parecer un poco extrao pues hemos mencionado en repetidas ocasiones que las clases abstractas no son instanciables (o sea,que no se pueden crear objetos de ellas). En este caso, la clase Trabajador es abstracta, entonces Cmo es posible que el mtodo imprimeDetalle(Trabajador) reciba un objeto de la clase Trabajador? La realidad es que el objeto NO es propiamente de la clase Trabajador. Si observamos la figura 4.53 en las lneas 10 a 19 vemos que cada objeto es creado ya sea como Supervisor o como Obrero. Lo que ocurre es que el mtodo imprimeDetalle(Trabajador) recibe al objeto en esa forma pero no significa que el objeto en si, sea de la clase Trabajador. Sera como una especie de rol que el objeto juega para ese mtodo. Cmo hemos visto anteriormente, un objeto puede tener varios roles y diferentes mtodos pueden recibir al mismo objeto en diferentes roles. Algo similar sucede en la realidad cuando un objeto, por ejemplo un cuchillo puede tener el rol de utensilio de cocina, pero tambin puede usarse como una herramienta para atornillar.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

122

Figura 4.54 Cdigo de la Clase Impresora

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

123

Figura 4.55 Cdigo de la Clase Main Resumen del Captulo En este captulo estudiamos el concepto de herencia, el cual es muy importante en la Programacin Orientada a Objetos. Es fundamental entender la herencia y todos los conceptos relacionados para poder escribir programas correctos y eficientes. La herencia est asociada tambin al permiso de acceso protegido, al polimorfismo, a las clases abstractas, a las clases finales a la sobre-escritura de mtodos y a muchos otros conceptos de gran relevancia para la programacin. Bsicamente, podemos decir que la herencia es un mecanismo de reso de cdigo en el cual una clase se especializa (se agrega informacin) para que pueda ser utilizada por un programa particular. La relacin entre la clase original y la clase derivada es una relacin es un o sea, la clase derivada o subclase es un tipo particular de la superclase. Por ejemplo, un automvil es un vehculo, un obrero es un trabajador, etc. Vimos detalladamente cmo funciona el polimorfismo y en qu casos puede ser aplicado. El polimorfismo nos permite ahorrar grandes cantidades de cdigo pues podemos escribir mtodos con argumentos polimrficos. Es decir, argumentos que pueden tomar varias formas. Esto permite que escribamos cdigo ms robusto pues como vimos en los ejemplos, cada subclase implementa sus propios mtodos declarados en la superclase, la cual normalmente es una clase abstracta. Las clases abstractas son clases no instanciables. Es decir, no se puede crear objetos a partir de ellas. Sin embargo, su utilidad radica en que sirven de base para crear otras clases. Otra de las facilidades que nos otorga el lenguaje Java ebn la sobre-escritura de mtodos es el retorno covariante, en el cual, podemos sobre-escribir mtodos cuyo tipo de retorno puede ser una subclase del tipo de retorno del mtododo que se est sobre-escribiendo. Finalmente, vimos que al agregarle la palabra final a la declaracin de una clase, sta ya no puede ser instanciada.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

124

Ejercicios y preguntas. 1. Describa la relacin entre el concepto de Herencia y el de Polimorfismo 2. EL siguiente cdigo marca error. Explique la razn por la que este cdigo no debe compilar public final abstract class X {} 3. Cules de las siguientes parejas de Clase Subclase seran correctas de acuerdo al significado de sus nombres. Llenar la tabla con Correcto o Incorrecto segn sea el caso:
SUPERCLASE SUBCLASE CORRECTO / INCORRECTO

Vehculo Automvil Padre Color Computadora Mujer Mquina Perro Amrica

Avin Llanta Hijo Verde Teclado Hombre Motor Animal Mxico

4. Escriba el mnimo cdigo en Java que implemente el siguiente diagrama de clase UML:

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

125

5. Dibuje un diagrama UML de clases que represente el siguiente cdigo:

6. Escriba una clase base (superclase) que contenga los atributos y mtodos propios de un Vehculo. La considerara abstracta? 7. Resuelva el siguiente problema utilizando herencia, polimorfismo y colecciones heterogneas. Dibuje un diagrama UML de clases de su solucin e implemente el cdigo de tal forma que concuerde con el diagrama. Una escuela desea calcular el pago de sus Profesores, los cuales son considerados como objetos de tipo Pagable. Hay tres tipos de Profesores: Profesores de Tiempo Completo. A estos profesores se les paga un salario fijo Profesores de asignatura A estos profesores se les paga por hora (horas trabajadas por salario_hora) Profesores con cargo adminstrativo A estos profesores se les paga un salario fijo ms un bono de 1000 pesos quincenales Pruebe su sus clases con el siguiente cdigo (No debe modificar este cdigo en absoluto):

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

126

class ExamenPoli { public static void main(String[] args) { Pagable[] profesores = { new ProfesorTiempoCompleto("Juan Lpez", 15000), new ProfesorAsignatura("Nury Mercado", 30, 200), new ProfesorAdministrativo("Mariano Torres", 15000, 2000) }; System.out.println("**Pago de Nmina**"); System.out.printf("%-15s\t%10s\n", "NOMBRE", "PAGO"); System.out.println("--------------------------------"); for (Pagable p : profesores) { float pago = p.calculaPago(); System.out.printf("%-15s\t%10.2f\n", ((Profesor) p).getNombre(), pago); } } }

La salida del programa deber ser la siguiente:


**Pago de Nmina** NOMBRE PAGO --------------------------------------Juan Lpez 15000.00 Nury Mercado 6000.00 Mariano Torres 17000.00

8. Describa el concepto de retorno covariante y escriba un ejemplo de cdigo Java que lo implemente. 9. Llene la siguiente tabla con los permisos de acceso. Escriba una P si se puede acceder o una N si no se puede acceder a los miembros de la clase. La columna Clase se refiere al acceso a los miembros desde la misma clase. La columna Paquete se refiere al acceso desde las clases que se encuentren en el mismo paquete. La columna Subclase se refiere al acceso desde cualquier subclase que est o no en el mismo paquete y la columna Cualquiera se refiere a cualquier clase situada en cualquier paquete.

Tipo
public protected (default) private

Permisos de Acceso Clase Paquete Subclase Cualquiera

10. Describa el concepto de Herencia Mltiple. Explique el problema del Diamante Mortal y Cmo Java elimina este problema a travs del uso de interfaces. 11. Considere el siguiente cdigo:

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

127

Cul(es) lneas son errneas? Explique el porqu (si las hay)

12.- Escriba el cdigo que implemente completa y correctamente el diagrama de clase mostrado:

Pruebe su cdigo con el siguiente cdigo de la clase Main:

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

128

La salida deber ser la siguiente:


Area del circulo:78.53982 Perimetro del crculo:31.415928 Area del circulo:12.0 Perimetro del crculo:14.0

13.- Explique por qu el uso de clases finales hace ms seguro el funcionamiento de los programa en Java. Muestre un ejemplo con la clase String (la cual es final). Qu escenario inseguro podra ocurrir si la clase String no fuera final? 14. Escriba un programa que implemente las siguientes las siguientes clases: Clase abstracta Mueble Interface Armable Interface Pintable Clase concreta Silla Clase concreta Mesa Clase concreta Banco Clase concreta Main

El mtodo public static main(String[]) deber crear un arreglo (coleccin heterognea de muebles) y un mtodo esttico void construye(Mueble) que imprima las instrucciones para construir el mueble de acuerdo a su tipo. La salida deber ser similar a esta:
Mueble: Silla Colonial Tipo de mueble: Silla Instrucciones de armado: Pegar las patas al asiento y pegar el respaldo Pintar con brocha usar barniz rebajado al 70% Mueble: Mesa de Comedor para seis personas Tipo de mueble: Mesa Instrucciones de Armado: Pegar las patas a la superficie y reforzar Pintar con pistola de aire y barniz rebajado al 50%

NOTAS: Utilice polimorfismo Las clases concretas implementan dos interfaces Deduzca los mtodos adecuados de las interfaces Deduzca los constructores adecuados de las clases 15.- Cual es la salida del siguiente cdigo (Ejectelo mentalmente)

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

129

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

130

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

131

5. Excepciones y Flujos Avanzados de Datos


En este ltimo captulo veremos dos temas que completan el curso bsico de Programacin Orientada a Objetos. Primero discutiremos el manejo de Excepciones, el cual es un mecanismo para especificar a la computadora que hacer en caso de que suceda una situacin extraordinaria durante la ejecucin de un programa. Posteriormente, veremos el manejo de Flujos Avanzados de Datos y particularmente estudiaremos el manejo de archivos los cuales nos permiten almacenar los objetos de manera permanente en la memoria secundaria de la computadora. Excepciones Como fue mencionado en el prrafo anterior, una excepcin es una situacin extraordinaria que puede pasar cuando se ejecuta un programa. Las excepciones slo pueden suceder cuando se ejecuta un mtodo de un objeto o de una clase. Cuando un objeto realiza una funcin, es posible que suceda algo que no est dentro del cauce natural de cosas que pueden suceder. Veamos por ejemplo la figura 5.1. El padre est ordenando a su hijo que vaya a la tienda a comprar un refresco.

Figura 5.1 Ejemplo de Excepciones Al ordenar la compra de un refresco, existen varias excepciones que pueden ocurrir. Como lo muestra la figura 5.1, el hijo pregunta al padre que hacer en caso de que la tienda est cerrada o que no le alcance el dinero para comprar el refresco. Existen muchas otras excepciones en las que
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 132

podemos pensar en esta situacin. Por ejemplo, que no haya el tipo de refresco deseado, o que existan varias presentaciones, etc. En general, se deben plantear las excepciones ms comunes o probables de acuerdo a la experiencia del programador. Algo muy similar sucede en programacin. Cuando un objeto est ejecutando una funcin (mtodo) es posible que suceda una situacin extraordinaria. Por ejemplo, supongamos que un objeto tiene un mtodo que calcula la raz cuadrada de un nmero que se enva como argumento. Una posible excepcin podra ser que el argumento sea un nmero negativo, el cual no tiene un nmero real que sea su raz cuadrada. Manejo de Excepciones en Java. En Java, las excepciones son objetos de la clase Exception la cual se encuentra en el paquete java.lang. Aunque pueden pertenecer tambin a alguna de sus subclases. Existen varias clases de excepciones predefinidas en el mismo paquete. Todas terminan con el sufijo Exception. La figura 5.2 muestra algunas excepciones predefinidas y la situaciones en las cuales ocurren.

Figura 5.2 Algunas Excepciones predefinidas en el paquete java.lang En la figura 5.2 vemos que existen bsicamente dos tipos de excepciones predefinidas: Las que ocurren al ejecutar instrucciones de entrada o salida (IOException) y las que ocurren al ejecutar cualquier otro tipo de instruccin (RunTimeException). Existen otras excepciones predefinidas pero en este libro slo discutiremos las mostradas en la figura. Algo interesante es que nosotros podemos crear nuestras propias excepciones. Esto lo veremos a continuacin.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

133

Clusulas Throws y Throw. Regresemos al ejemplo de la compra del refresco. Simularemos esta situacin con las clases Padre e Hijo. El padre invocar al mtodo compraCoca() del hijo. El mtodo compraCoca() puede generar (o aventar) dos posibles excepciones. Cada excepcin es un objeto que en este caso puede ser de la clase TiendaCerradaException o de la clase DineroInsuficienteException. La figura 5.3 muestra el cdigo de la clase Hijo. Existen varias cosas importantes que debemos entender del cdigo de la figura 5.3. La lnea 7 muestra el encabezado del mtodo compraCoca(). En esta lnea y en la siguiente, se declara que el mtodo compraCoca() puede aventar dos tipos de excepciones TiendaCerradaException y DineroInsuficienteException. Ntese que enfatizamos puede porque no necesariamente aventar alguna de las dos excepciones como se ve ms adelante en el cdigo. La forma de declarar que un mtodo puede aventar una excepcin, es a travs del uso de la palabra throws (que significa avienta en Ingls). Cuando se utiliza la palabra throws en la declaracin de un mtodo para indicar que el mtodo puede aventar una excepcin, esto obliga al mtodo llamador a manejar la excepcin a menos que la excepcin no pertenezca a la clase Exception como veremos ms adelante.

Figura 5.3 Cdigo de la clase Hijo Otra cosa que debemos observar de la figura 5.3 es que se est simulando las diferentes situaciones extraordinarias a travs del uso de un nmero aleatorio generado a por el mtodo esttico random() de la clase Math la cual ya viene incluida en el paquete java.lang por lo que no es necesario hacer el import para esta clase. El mtodo random() genera un nmero
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 134

de tipo double mayor o igual a 0 y menor que 1 con una distribucin de probabilidad uniforme (o sea con igual probabilidad para cualquier nmero). Se asume entonces que hay un tercio de probabilidad para cada rango (o sea, que el nmero sea menor que 0.33, que est entre 0.33 y 0.66, y que sea mayor que 0.66). Si el nmero generado es menor que 0.33, entonces se ejecuta la instruccin en la lnea 18: throw(new TiendaCerradaException()); El throw es una instruccin que provoca que el mtodo que la ejecuta, en este caso compraCoca(), aviente la excepcin. A quin se la avienta? Al mtodo que haya llamado al mtodo compraCoca(). Ms adelante veremos que puede hacer un mtodo cuando ocurre una excepcin dentro de su ejecucin. Otra cosa interesante que observamos en la lnea 18 es que estamos enviando como argumento al mtodo throw(Exception) un objeto que Estamos creando al vuelo! Este tipo de objetos que son creados al vuelo se les llama objetos annimos. Por qu annimos? Porque No tienen nombre! Es muy comn este tipo de instrucciones en situaciones en las que un objeto slo ser referenciado una sola vez. Es importante sealar que tanto la clusula throws de la lnea 7 como el mtodo throw de las lneas 18 y 19 slo con pueden ser usados con subclases de la clase Exception. Clusulas try y catch. La figura 5.4 muestra el cdigo de la clase Padre. Las lneas 3 y 4 importan las dos clases correspondientes a las excepciones declaradas en el mtodo comprarCoca(). Ntese que se tiene que importar ambas clases porque estn en otro paquete. Por otro lado, no es necesario importar la clase Hijo porque est en el mismo paquete (familia).

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

135

Figura 5.4 Cdigo de la Clase Padre Cuando un mtodo o una instruccin pueden aventar una excepcin de la clase Exception o alguna subclase de Exception, es necesario que se encierre este mtodo o instruccin en un bloque precedido por la palabra try. Las lnea 9 a 11 muestran el bloque que encierra el llamado al mtodo compraCoca() de la clase Hijo. Debido a que en ese caso, el mtodo compraCoca() puede aventar dos tipos de excepciones, entonces tenemos que escribir dos bloques precedidos por la palabra catch inmediatamente despus de terminar el bloque try. Las lneas 11 a 14 y 14 a 17 de la figura 5.2 muestran estos dos bloques, uno para cada tipo de excepcin que el mtodo pueda aceptar. La sintaxis para el manejo de excepciones entonces es la siguiente:
try { //Mtodos o instrucciones que pueden generar alguna excepcin } catch (ClaseDeLaExcepcion e) { //Cdigo que debe ejecutarse cuando se genera una excepcin }

Las instrucciones que se escriben dentro del bloque try son las que provocan las excepciones y las que se escriben dentro del bloque catch son las que manejan las excepciones. Regresando al ejemplo de la compra del refresco. Si tuviramos que traducir al espaol lo que est escrito en las lneas 9 a 17, sera una conversacin ms o menos como la siguiente: Padre: Por favor ve a comprar una coca a la tienda (lnea 10) Hijo: Qu hago si la tienda est cerrada? (lnea 11) Padre: Ve a al sper (lneas 12 y 13) Hijo: Y si no tengo suficiente dinero? (lnea 14) Padre: Pdele a tu mam (lneas 15 y 16) Cuando se ejecute el cdigo de la figura 5.4, como ya se explic anteriormente, las tres situaciones (tienda cerrada, dinero insuficiente y ningn problema) sern emuladas con un nmero aleatorio generado en el mtodo compraCoca() de la clase Hijo. Ms adelante veremos un ejemplo en el cual la excepcin ocurre en realidad. Finalmente, la Figuras 5.5 y 5.6 muestran los cdigos de las clases TiendaCerradaException y DineroInsuficienteException respectivamente. En ambos cdigos podemos ver que las clases extienden a la clase Exception. Esto es necesario para crear excepciones que obliguen a los programadores a utilizar bloques try catch para manejarlas.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

136

Figura 5.5 Cdigo de la clase TiendaCerradaException

Figura 5.6 Cdigo de la Clase DineroInsuficienteException Al ejecutar el cdigo de la clase Padre mostrado en la figura 5.4 varias veces, tendremos diferentes resultados como lo muestra la figura 5.7.

Figura 5.7 Resultado de la ejecucin del cdigo de la clase Padre (fig. 5.4) Otra forma de manejar las Excepciones Como hemos visto hasta ahora, las excepciones deben ser manejadas por el mtodo llamador al que gener la excepcin. En el ejemplo de la compra de refresco, quien maneja las excepciones es el mtodo main(String[]) de la clase Padre. Esto es, quien decide que hacer para manejar
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 137

las excepciones es este mtodo y no el mtodo compraCoca() de la clase Hijo. Resumiendo, el mtodo compraCoca() avienta la excepcin y el mtodo main(String[]) la atrapa (por eso el nombre del bloque catch). Sin embargo, supongamos que el programador del mtodo llamador no desea manejar la excepcin. Existe alguna forma de no manejar la excepcin sin que marque error el compilador? La respuesta, obviamente, es s (si no, No hubiramos escrito la pregunta!). Podemos ver el manejo de excepciones de manera similar como se manejan los conflictos en una organizacin. Supongamos que existe un conflicto en un departamento de una organizacin. El jefe del departamento puede manejar el conflicto (excepcin) o puede pasrsela a su jefe. Este a su vez puede manejar el conflicto o pasrselo a su jefe y as sucesivamente hasta llegar a la mxima autoridad de la organizacin quien tiene la obligacin de manejar todos los conflictos. La figura 5.8 ilustra este concepto. El manejo de excepciones es muy similar al ejemplo de la figura 5.8. Cuando ocurre una excepcin en un mtodo, este puede manejarlo de dos formas: Utilizando las clusulas try-catch puede simplemente aventarlo al mtodo llamador utilizando la clusula throws en la declaracin del mtodo. Si el programador est absolutamente seguro como debe manejar la excepcin, pues entonces no tiene sentido aventarla al mtodo llamador. Lo mismo que pasa en la organizacin, si el jefe del departamento sabe cmo manejar el conflicto, no tiene caso que lo pase a su superior. Sin embargo, no se debe manejar un conflicto (o excepcin) si no se tiene la seguridad plena de que se sabe cmo manejarla correctamente.

Figura 5.8 Analoga del Manejo de Excepciones con el Manejo de Conflictos


Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 138

Algo ms sobre la analoga de la figura 5.8. Es posible que algunas excepciones puedan ser manejadas por el jefe y otras no. De igual forma, podemos manejar algunas excepciones utilizando la clusulas try-catch y otras con la clusula throws como veremos en los ejemplos posteriores. Ejemplo de la Compra del Refresco Revisitado. Para ilustrar los conceptos vistos arriba sobre el manejo de excepciones vamos a extender el ejemplo de la compra del refresco introduciendo una nueva clase (Madre) la cual podr manejar algunas excepciones dentro de su mtodo, pero otras las aventar al mtodo llamador. La idea est ilustrada en la figura 5.9.

Figura 5.9 Ejemplo de Excepciones La madre de la figura 5.9 puede manejar la excepcin del dinero insuficiente pues ella lo tiene. Sin embargo no sabe cmo manejar el problema de que la tienda est cerrada. Entonces, utiliza los dos tipos de manejo de excepciones. Aventar la excepcin TiendaCerradaException y resolver la excepcin DineroInsuficienteException. De esta forma, el padre slo tiene

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

139

que preocuparse por la primera. El ejemplo completo del cdigo de las clases Madre y Padre est en las figuras 5.10 y 5.11. El cdigo de la case Hijo permanece igual al de la figura 5.3 al igual que la salida del programa.

Figura 5.10 Cdigo de la clase Madre

Figura 5.11 Cdigo de la clase Padre

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

140

Propagacin de Excepciones. Existen varias cuestiones que an es necesario discutir para tener un conocimiento ms completo sobre el manejo de excepciones. Por ejemplo, Qu pasa cuando una excepcin no es atrapada? Consideremos el cdigo de la figura 5.12

Figura 5.12 Ejemplo de Cdigo que Genera una Excepcin Al compilar y ejecutar el cdigo de la figura 5.12 se produce la salida mostrada en la figura 5.13. El cdigo de la figura 5.12 contiene una instruccin que genera una excepcin. sta excepcin ocurre cuando se intenta realizar una divisin entera con el divisor igual a 0. Como puede verse en la figura 5.12, no existe ningn bloque try-catch ni tampoco una clusula throws en la declaracin de ningn mtodo. Una pregunta que surge inmediatamente es Porqu el cdigo compila sin errores si hay una instruccin que genera una excepcin? La respuesta es muy simple. No todas las excepciones deben ser atrapadas. En la figura 5.2 vemos que hay una clase de excepcin llamada RunTimeException. Ni esta excepcin, ni sus subclases obligan a escribir bloques try-catch o clusulas throws al programador. A este tipo de excepciones se les llama Excepciones sin Checar (Unchecked Exceptions). Por otro lado, las excepciones que pertenezcan a la clase Exception o alguna subclase son cachables (Checked Exceptions). Es decir, deben ser atrapadas o el programa no compila.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

141

Figura 5.13 Resultado de ejecutar el cdigo de la figura 5.12 Cuando una excepcin no es atrapada, el programa termina de manera abrupta, mostrando un mensaje de error en la consola de errores (la cual normalmente es la misma consola de salida del programa). La salida mostrada en la figura 5.13 es precisamente el mensaje de error que indica que el programa tuvo una excepcin y por lo tanto no puede continuar. Como puede verse en la figura 5.13 se muestra la excepcin ocurrida, el mtodo en el cual ocurri, el nmero de lnea, la clase e incluso el nombre del archivo que contiene dicha clase. Vemos que no solo muestra un mtodo sino varios mtodos con sus nmeros de lneas. Esto es porque cuando ocurre una excepcin, esta se propaga desde el mtodo en el cual ocurri hacia el mtodo llamador, y despus hacia el llamador del llamador y as sucesivamente hasta llegar al mtodo main(String[]) el cual es el mtodo que inicia la ejecucin de todos los programas. El texto mostrado en la figura 5.12 se le llama pila de ejecucin (execution stack) porque cada vez que un mtodo llama a otro se almacenan en una pila en la cual el orden es inverso al orden del llamado. Observe que el ltimo mtodo mostrado es el main(String[]) cuando en realidad fue el primero en ser llamado. Otro punto interesante que debemos observar es que aunque la lnea 5 de la figura 5.12 contiene la instruccin System.out.println("Hola") el mensaje no se muestra en la salida del programa. Esto se debe a que cuando ocurre una excepcin, el programa detiene su ejecucin normal. En este caso particular, al ocurrir la excepcin en la lnea 15 se provoca una excepcin en la 11, la cual provoca una excepcin en la 8, la cual a su vez provoca la excepcin en la lnea 5. Como la excepcin no es atrapada, entonces se detiene la ejecucin del programa y no se ejecuta la instruccin que imprime el mensaje. Es decir, el programa aborta antes de ejecutar la instruccin de impresin.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

142

La figura 5.14 muestra un cdigo muy similar pero en este caso hemos agregado instrucciones para atrapar la excepcin.

Figura 5.14 Cdigo de la clase EjemploRuntimeException En el cdigo de la figura 5.14, hemos agregado instrucciones para atrapar y manejar la excepcin mediante bloques try-catch (lneas 5 y 8). Al ejecutar el cdigo, vemos que ahora el programa termina su ejecucin normal pero an no muestra el mensaje de la lnea 6. La salida del programa es simplemente: / by zero Es decir, slo se muestra el mensaje de la excepcin. Esto es debido que cuando atrapamos una excepcin, se ejecuta el cdigo del bloque catch y se contina con el cdigo siguiente al bloque catch. Si quisiramos mostrar el mensaje Hola aunque suceda le excepcin, debemos colocar la instruccin de impresin despus del bloque catch. Esto se muestra en la figura 5.15.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

143

Figura 5.15. Cdigo de la clase EjemploRuntimeException. Finalmente Finally En ocasiones, es necesario que algunas instrucciones se ejecuten sin importar si hubo o no excepcin o inclusive si dentro del bloque catch, hubo otra excepcin o un return. Veamos otro ejemplo de cdigo en la figura 5.16.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

144

Figura 5.16 Cdigo de la clase EjemploRuntimeException que no muestra el mensaje A pesar de que pusimos la instruccin de impresin despus del bloque catch (lnea 12 de la figura 5.16), el return de la lnea 10 impide que se ejecute la lnea 12 pues termina la ejecucin del mtodo main(String[]). Entonces podemos preguntarnos Existe alguna forma de que se ejecuten instrucciones sin importar si hubo o no excepciones, o returns dentro de las excepciones? Obviamente la respuesta es s. El lenguaje Java permite incluir el bloque finally el cual SIEMPRE se ejecuta. Ms adelante veremos que esto es muy til cuando se manejan archivos y otro tipo de flujos avanzados de datos. El uso del bloque finally se muestra en la figura 5.17. En la figura 5.17 observamos que se ha agregado un bloque finally (lneas 12, 13 y 14). Este bloque imprime el mensaje importante que debe ser impreso sin importar lo que ocurra dentro del bloque catch. En realidad, el nico caso en el cual el bloque finally no sera ejecutado sera si se hubiera terminado la ejecucin del programa dentro del bloque catch. Esto es, si se escribe la instruccin system.exit(1) en lugar del return en la lnea 10. Un ltimo ejemplo de Excepciones. Los ejemplos vistos hasta ahora ilustran el manejo de excepciones pero no son muy realistas pues primero simulamos la situacin de la excepcin mediante un nmero aleatorio y posteriormente fabricamos la excepcin al dividir por cero. En este ltimo ejemplo de excepciones presentaremos un caso ms realista con una situacin que puede presentarse al manejar una cuenta bancaria.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 145

Supongamos que tenemos que representar una cuenta bancaria la cual tiene un saldo y operaciones para depositar y retirar dinero de la cuenta. El cdigo se muestra en la figura 5.18.

Figura 5.17 Cdigo de la clase EjemploRuntimeException con el uso de finally

Figura 5.18 Cdigo de la clase CuentaBancaria

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

146

La lnea 10 de la figura 5.18 se encarga de aventar una excepcin cuando se intenta realizar un retiro de una cantidad mayor al saldo. Obviamente esto no debe ser permitido pues el saldo quedara negativo. La figura 5.19 muestra el cdigo de la clase Cliente que hace uso de la excepcin para terminar una serie de retiros a la cuenta bancaria.

Figura 5.19 Cdigo de la clase Cliente que utiliza excepciones para terminar su ejecucin Al ejecutar el cdigo de la figura 5.19 obtenemos la salida mostrada en la figura 5.20.

Figura 5.20 Salida de la ejecucin del cdigo de la figura 5.19 Note que an falta crear la clase SaldoInsuficienteException que se encuentra en el paquete excepciones. Pero esto lo dejamos al lector como ejercicio. El manejo de excepciones permite que los cdigos sean ms limpios pues no tenemos la necesidad de agregar ifs para el manejo de las diversas situaciones que se puedan presentar.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 147

Adems muchas excepciones son estndar y pueden ser aventadas por diferentes mtodos. Por otro lado, las excepciones pueden almacenar informacin contextual sobre el error o situacin extraordinaria que se present. En los ejemplos mostrados nosotros slo utilizamos el mensaje de la excepcin, pero podramos almacenar cualquier tipo de informacin sobre el error. Despus de todo, las excepciones son objetos con atributos y mtodos. En la siguiente seccin veremos el uso de flujos avanzados de datos en los cuales usaremos otro tipo de excepciones. Flujos Avanzados de Datos. Hasta ahora, hemos trabajado totalmente en la memoria de la computadora. Es decir, todos los datos asociados con los objetos permanecen en la memoria de la computadora. Esto tiene sus ventajas, pues los accesos a los datos son ms rpidos y no es necesario usar instrucciones para guardar o leer datos desde los dispositivos de almacenamiento (discos duros, memorias flash, cintas, etc.). Sin embargo, tambin existen varias desventajas, La primera es que los datos se borran cuando se apaga la computadora. La segunda es que la memoria principal de las computadoras es ms pequea que la memoria permanente proporcionada por los dispositivos de almacenamiento. Otra desventaja es que, en general, la memoria principal es ms costosa. En los lenguajes de programacin, tenemos la posibilidad de almacenar los objetos en la memoria permanente. En el lenguaje Java se hace a travs del uso de flujos avanzados de datos. Un flujo avanzado de datos (o Stream como se le conoce en Ingls) es simplemente una fuente (o un destino) de la cual (o a la cual) viajan datos. Ver figura 5.21

Figura 5.21 Flujos Avanzados de Datos Los flujos avanzados de datos (les llamaremos simplemente flujos por comodidad) pueden ser de entrada o de salida. En la figura 5.21 vemos que los flujos estn ligados a los dispositivos de entrada/salida de la computadora. Por ejemplo, tenemos flujos de entrada para el teclado, el disco duro e incluso podemos tener asociado un flujo de entrada a un punto de conexin en una red de
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 148

computadoras. Por otro lado, tenemos flujos de salida asociados a impresoras, consolas, discos duros y redes. Los flujos de entrada (los cuales son objetos por supuesto) tendrn atributos y mtodos que permitan leer datos de ellos. Por otro lado, los flujos de salida (tambin objetos) tendrn atributos y mtodos que nos permitan escribir en ellos. Una de las caractersticas ms interesantes de los flujos de datos es que permiten tratar de manera uniforme las operaciones de entrada salida sin importar de qu tipo de dispositivos se trate. Por ejemplo, podemos asociar un mismo tipo (o sea, una misma clase) de flujo de entrada a un archivo que est almacenado en un disco o a la consola de la computadora. Entonces cuando efectuemos una lectura, estaremos leyendo informacin del disco para el caso del archivo o estaremos leyendo caracteres introducidos usando el teclado para el caso de la consola. Desde el punto de vista del programa que lee los datos, ambos dispositivos se tratan igual, es decir ambos son fuentes de datos de entrada. Esto quedar mas claro con los ejemplos que veremos ms adelante. Sabemos que la unidad bsica de almacenamiento en las computadoras es el bit (digito binario). Los bits se agrupan en bytes para formar caracteres (letras, nmeros y caracteres especiales). Para el manejo de flujos, consideraremos adicionalmente que los bytes se agrupan para formar palabras y las palabras se agrupan para formar lneas. Veremos que existen flujos que nos permiten leer o escribir byte por byte, carcter por carcter o lnea por lnea. Tambin existen flujos que nos permiten leer o escribir objetos. Flujos de Bytes Los flujos que leen y escriben bytes (secuencias de 8 bits) son subclases de las clases InputStream y OutputStream respectivamente y se encuentran en el paquete java.io. Normalmente, cuando se trabaja con flujos de bytes se hace de manera secuencial desde el primer byte del flujo pasando por cada byte del mismo hasta llegar al ltimo byte. A continuacin presentamos un ejemplo de un programa que copia archivos, los cuales son un caso especial de flujos de datos. Las clases que se usan en el ejemplo son FileInputStream y FileOutputStream para leer y escribir datos en archivos en el disco de la computadora. La figura 5.22 muestra la idea general del algoritmo. Como puede observarse en la figura 5.22, el algoritmo para copiar un archivo byte por byte es muy simple. Consiste en ir leyendo cada byte del archivo de entrada y escribirlo en el archivo de salida. Los archivos tienen asociado un apuntador que indica la posicin del siguiente byte que se va a leer. Cada vez que se lee un byte (llamando al mtodo read()) se avanza al apuntador para no leer dos veces el mismo byte. Al principio, cuando el archivo se acaba de abrir, el apuntador (a veces tambin se le llama cursor) apunta al primer byte. Cuando se intenta leer un byte y ya no hay ms que leer, entonces el mtodo de lectura regresa un -1. Obviamente, el nmero -1 no puede formar parte del archivo porque solo lee bytes cuyo rango es de 0 a 255.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

149

Figura 5.22 Algoritmo para copiar un archivo byte por byte La figura 5.23 muestra paso por paso como se copia el archivo con el algoritmo mostrado. Asumimos que cada dgito es un byte. Cada paso de la figura indica el estado de los archivos y el apuntador antes de leer y escribir en cada uno en cada iteracin del ciclo while. As, en el paso 1, se acaban de abrir ambos archivos y el apuntador del archivo entrada.txt apunta al primer byte. An no se ha escrito nada en el archivo salida.txt. El paso 2 muestra el estado de los archivos despus de haber ledo el primer byte y haberlo escrito en el archivo de salida. El paso 3 muestra el estado cuando se han ledo dos bytes y se han escrito en el archivo de salida. Finalmente en paso 4 muestra el estado cuando se leyeron los tres bytes del archivo de entrada y se han escrito los tres bytes en el archivo de salida. La siguiente lectura que se realice en el archivo de entrada ya no regresar un byte sino un valor de -1 indicando que ya no se pueden leer ms bytes.

Figura 5.23 Funcionamiento del algoritmo para copiar bytes

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

150

La figura 5.24 muestra el cdigo completo de la clase CopiaBytes que implementa el algoritmo mostrado. Para que el cdigo funcione correctamente, se deber primero crear el archivo entrada.txt. Se puede hacer con el block de notas o cualquier otro programa. Este archivo debe estar situado en el directorio en el cual se corre el programa. En este caso, debemos estar situados arriba del directorio flujos pues as se llama el paquete. La instruccin sera la siguiente: C:\.....\>javac flujos\CopiaBytes.java (para compilar) C:\...\>java flujos.CopiaBytes (para ejecutar el archivo) El archivo entonces debe estar situado en el mismo directorio en el que est situado el directorio flujos. Flujos de Caracteres. Algo muy similar podemos hacer para leer caracteres en lugar de bytes. Los flujos que leen caracteres heredan de la clase Reader y de la clase Writer las cuales tambin se encuentran en el paquete java.io. El siguiente ejemplo de cdigo muestra el contenido de un archivo de texto en la consola. El funcionamiento del programa es prcticamente igual al que acabamos de mostrar, excepto porque en este caso, se leen caracteres en lugar de bytes y adems la salida no se graba en otro archivo sino que se muestra en la consola. El lenguaje Java utiliza una codificacin para los caracteres llamada Unicode. sta codificacin utiliza dos bytes por cada caracter. La figura 5.25 muestra el cdigo del programa.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

151

Figura 5.24 Cdigo de la clase CopiaBytes que copia un archivo byte por byte.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

152

Figura 5.25 Cdigo de la clase CopiaCaracteres La principal diferencia entre los cdigos de las figuras 5.24 y 5.25 est en los flujos que utilizan pues uno est orientado a bytes y el otro a caracteres. El finally de la lnea 19 nos asegura que siempre se cerrar el flujo sin importar lo que pase con el programa. En ocasiones cuando un programa se termina sin haber cerrado el flujo puede ocasionar que el archivo quede daado o incompleto. Por eso es necesario cerrar los flujos antes de terminar los programas. En la lnea 16 de la figura 5.25 observamos que el caracter ledo se tiene convertir de entero a caracter. Este tipo de conversin recibe el nombre de cast y es muy utilizada para convertir datos primitivos o tambin objetos como vimos en el captulo anterior. Si no realizramos el cast el programa mostrara slo una serie de nmeros enteros que corresponderan a los cdigos numricos de cada carcter. Se deja de ejercicio al lector verificar lo anterior.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

153

Otros tipos de Flujos. Existe una gran cantidad de flujos, cada uno tiene sus caractersticas particulares. Existen flujos para leer bytes, caracteres, lneas, elementos de arreglos, etc. Cerraremos esta discusin de flujos con un ejemplo de un flujo que lee lneas completas. En este caso, cada instruccin de lectura (readline()) lee toda una secuencia de caracteres hasta encontrar un caracter especial que es el fin de lnea. Este flujo lo utilizaremos ms adelante cuando veamos el ejemplo completo del programa de nmina. La figura 5.26 muestra el cdigo de la clase CopiaLineas, la cual utiliza el flujo BufferedReader. Este flujo, aparte de leer toda la lnea en una sola instruccin, lo hace de una manera ms eficiente pues utiliza un buffer. El buffer es un rea de memoria en la cual se almacena temporalmente la informacin que se est leyendo o escribiendo. La ventaja de usar un buffer es que el sistema operativo de la computadora realiza una sola instruccin de lectura que llena el buffer, en lugar de realizar varias operaciones de lectura. Las operaciones de lectura que realiza el programa leen informacin del buffer. Cuando el programa ha consumido toda la informacin del buffer, se realiza otra operacin de lectura y el buffer se vuelve a llenar. La escritura de datos se realiza de manera muy similar. Esto que los programas sean ms eficientes en general. Serializacin de Objetos Los ejemplos de flujos de datos asociados a archivos que hemos visto hasta ahora pueden leer y escribir bytes, caracteres y lneas. Sin embargo, nosotros hemos trabajado extensivamente con objetos. Una pregunta que podemos hacernos es Cmo podemos grabar y/o leer objetos en archivos? Existen bsicamente dos posibilidades. La primera es grabar en archivos toda la informacin de los objetos convertida a bytes, caracteres o cadenas. Esto implicara obtener los valores de los atributos de los objetos y grabarlos en forma de texto o binario (bytes). Posteriormente tendramos que leer los archivos y crear de nueva cuenta los objetos con los valores ledos. sta opcin tiene un gran inconveniente. Si un objeto hace referencia a otro objeto, no existe forma de guardar esa referencia en un archivo de manera sencilla o automtica. La segunda alternativa es utilizar un mecanismo provisto por el lenguaje Java llamado Serializacin de Objetos. Este mecanismo permite que un objeto sea grabado en disco a travs de una secuencia de bytes que contiene no slo la informacin del objeto sino tambin de los objetos a los cuales este hace referencia. Esto quedar ms claro con los ejemplos que presentaremos ms adelante.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

154

Figura 5.26 Cdigo de la clase CopiaLineas La figura 5.27 muestra el proceso de serializacin y de-serializacin de objetos. Como se muestra en la figura, el proceso para escribir un objeto en disco consiste en convertir los objetos a bytes y grabarlos en disco a travs del mtodo writeObject(Object). El proceso inverso consiste en leer los bytes del disco y crear los objetos a travs del mtodo readObject(). Para poder serializar un objeto, la clase a la cual pertenece debe implementar la interface Serializable. Esta interface en realidad no posee mtodos pero se debe implementar para poder realizar el proceso de serializacin. Los flujos que usaremos son el ObjectOutputStream y el ObjectInputStream los cuales tienen sendos mtodos para grabar y leer objetos en archivos. La figura 5.28 muestra un ejemplo de cdigo que crea dos objetos y los almacena en disco. La figura 5.29 muestra un ejemplo de cdigo que lee objetos almacenados en disco y despliega su informacin.
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 155

Figura 5.27 Serializacin de Objetos

Figura 5.28 Cdigo de la clase GrabaObjetos que utiliza serializacin para almacenar objetos en un archivo

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

156

El cdigo de la figura 5.28 utiliza dos flujos, ambos de salida, pues slo graba informacin. La clase FileOutputStream es un flujo que permite grabar bytes en un archivo y la clase ObjectOutputStream nos permite grabar objetos. Debido a que los objetos se almacenan en bytes, el objeto de la clase ObjectOutputStream que graba los objetos de la clase Empleado requiere a su vez de otro objeto de la clase FileOutputStream que grabe bytes, es por esa razn que en la lnea 11, cuando se construye el objeto de la clase ObjectOutputStream se enva como parmetro del constructor al objeto de la clase FileOutputStream que se acaba de crear. Las lneas 15 y 16 graban los objetos en el disco y la lnea 17 tiene como finalidad asegurarse que no quede nada pendiente de grabar en el buffer. Note que el catch de la lnea 19 atrapa cualquier excepcin. Esto nos permite no tener que poner varios catchs uno por cada excepcin posible, pero no es una buena prctica de programacin hacerlo porque no podemos manejar la excepcin mas adecuadamente. En general, siempre es mejor tratar cada posible excepcin de manera independiente como lo habamos hecho anteriormente. Pero quisimos mostrar que tambin se puede manejar un solo catch para todas las posibles excepciones. El cdigo de la figura 5.28 no produce resultados pero al ejecutarse se crea el archivo objetos.dat el cual contiene toda la informacin de los objetos que se serializaron.

Figura 5.29 Cdigo de la clase LeeObjetos que lee objetos que fueron serializados

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

157

Al ejecutar el cdigo de la figura 5.29 se leen los objetos que haban sido guardados en el archivo objetos.dat. Observe que los flujos de entrada que se utilizan corresponden a los flujos de salida que se utilizaron en al cdigo de la figura 5.28. La clase Empleado no debe haber sufrido ningn cambio, de lo contrario se marcar un error al momento de tratar de leer los objetos. La lneas 13 y 14 son las que leen la informacin y crean los objetos. Observe que se utiliza un cast para convertir el objeto ledo a un objeto de la clase Empleado. El mtodo readObject() regresa un objeto de la clase Object. En este cdigo, podramos haber evitado el uso del cast si hubiramos declarado las variables objeto1 y objeto2 de la clase Object. Pero generalmente es mejor trabajar con las clases ms especficas de los objetos. De hecho, como todas las clases extienden a la clase Object, Cualquier objeto de cualquier clase puede estar almacenado en una variable de la clase Object! Algo interesante que debemos observar del cdigo de la figura 5.29 es que en las lneas 16 y 17 se imprimen los objetos en la consola. Esto slo tiene sentido si se ha implementado el mtodo toString() en la clase Empleado, de lo contrario slo mostrar la direccin de la memoria heap en la que est el objeto y no sus datos. La figura 3.30 muestra el cdigo de la clase Empleado cuyos objetos pueden ser serializados y almacenados en disco. Observe que la clase implementa la interface Serializable. Esta implementacin es necesaria para llevar a cabo la serializacin. Sin embargo, la interface Serializable no contiene ningn mtodo. Se utiliza slo para indicar que los objetos de esa clase pueden ser serializados y almacenados en disco.

Figura 5.30 Cdigo de la clase Empleado cuyos objetos pueden ser serializados

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

158

Serializando objetos que hacen referencia a otros objetos. Los ejemplos mostrados anteriormente permiten grabar y leer objetos de la clase Empleado. Esta clase es muy sencilla y no contiene referencias a otros objetos. Sin embargo, es muy comn que existan situaciones en las cuales un objeto hace referencia a otro o a varios objetos. Supongamos por ejemplo, que cada empleado est asignado a un departamento. Si representamos a los departamentos como objetos de la clase Departamento, entonces la clase Empleado hace referencia a la clase Departamento como se muestra en las figuras 5.31 y 5.32.

Figura 5.31 Cdigo de la clase Empleado que hace referencia a la clase Departamento Como se muestra en la figura 5.32, si una clase serializable hace referencia a otras, todas las clases deben ser serializables. En este caso en particular, la clase Empleado hace referencia a la clase Departamento. Entonces ambas deben implementar la interface Serializable. De lo contario, cuando se quiera grabar en el disco el objeto, se generar la excepcin: java.io.NotSerializableException. Esta excepcin ocurre porque se intenta serializar TODA la informacin del objeto pero dentro de la informacin del objeto va tambin la informacin de los otros objetos a los cuales se hace referencia. En este caso, cuando se graba un objeto de la clase Empleado, se debe grabar la informacin del departamento al cual est asignado el empleado.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

159

Figura 5.32 Cdigo de la clase Departamento

Existe sin embargo, una excepcin a esta regla que consiste en utilizar la palabra transient en la declaracin del atributo que no se desea grabar. En este caso y slo en este caso, no es necesario que la clase de este atributo implemente la interface Serializable. Sin embargo, debe quedar muy claro que la informacin del atributo transient se perder cuando se elimine el objeto de la memoria heap. Para hacer esta prueba, el lector debe modificar la lnea 10 de la figura 5.31, escribiendo: transient Departamento departamento; Con esta modificacin ya no es necesario que la clase Departamento implemente la interface Serializable. Sin embargo, cuando se ejecute la clase LeeObjetos, se generar una excepcin pues ahora el atributo departamento est vacio, es decir, su valor es nulo y por lo tanto no es posible ejecutar el mtodo getNombre() que se utiliza en la lnea 22 de la figura 5.31. El Ejemplo de la Nomina RevisitadoRevisitado Revisaremos ahora el ejemplo de la Nomina pero ahora agregaremos que los objetos sean ledos del disco. Como vimos anteriormente, tenemos dos alternativas, utilizar archivos normales para guardar los atributos de los objetos o utilizar serializacin de objetos. Para ilustrar ambas alternativas utilizaremos dos clases diferentes que efectan la misma funcin. Debido a que hemos encapsulado el manejo de datos en la clase BaseDatos, todos los cambios que realizaremos sern en esta clase.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

160

Utilizando Archivos de Texto Modificaremos la clase BaseDatos para que lea un archivo de texto y por cada lnea del archivo se cree un objeto con los valores de los atributos escritos en el archivo. El archivo de texto se muestra en la figura 5.33.

Figura 5.33 Archivo Trabajador.txt El archivo mostrado en la figura 5.33 se utiliza para almacenar los datos de entrada del programa de nmina. Cada lnea del archivo Trabajador.txt corresponde a un trabajador. Los datos estn separados por comas. Recordemos que tenemos dos tipos de trabajadores: obreros y supervisores. El primer dato entonces es el tipo. Una S indica que el trabajador es un supervisor y una O indica que es un obrero. El segundo dato es el nombre, el tercer dato es el salario por hora. El tercer dato puede ser las horas trabajadas o el premio (si se trata de un obrero) o el descuento (si se trata de un supervisor). Recordemos que a los obreros se les otorga un premio y a los supervisores un descuento si es que solicitaron un prstamo. En el caso de que se especifiquen las horas trabajadas, entonces la lnea del archivo contendr 5 datos. En caso contrario, la lnea slo contendr 4 datos. En el caso de que no se especifiquen las horas trabajadas, se asumir que el trabajador labor 40 horas. Por ejemplo, la primera lnea del archivo de la figura 5.33 corresponde a un obrero, su salario por hora es de 60 pesos, trabaj 40 horas y tiene un premio de 100 pesos. La segunda lnea tambin corresponde a un obrero pero este labor 35 horas. A continuacin veremos el cdigo que permite leer el archivo y cargar loos datos en el arreglo de trabajadores. Las figuras 5.34 y 5.35 muestran el cdigo de la clase BaseDatos que lee la informacin de los trabajadores de un archivo de texto el cual puede ser creado con el block de notas o cualquier otro programa editor de textos. El cdigo de ambas figuras se debe escribir en un solo archivo. Observe que los nmeros de las lneas de la figura 5.35 continan a los de la figura 5.34.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

161

Observamos que en la lnea 6 de la figura 5.34 se importa la clase java.util.ArrayList. Esta clase nos permite definir arreglos de cualquier tipo de objeto y tiene la caracterstica de crecer dinmicamente. Esto significa que no tenemos que saber el tamao (o sea la cantidad de elementos que contendr el arreglo) al momento de su creacin. La lnea 16 de la misma figura crea el arreglo de trabajadores. Observe que en la declaracin del arreglo se utilizan los parntesis angulares o cuas para definir el tipo de los objetos que contendr el arreglo. Esta caracterstica de Java se llama tipos genricos o tipos parametrizados aunque su estudio est fuera de los alcances de este libro, podemos simplemente decir que nos permiten definir los tipos de datos que tendrn los arreglos u otro tipo de colecciones de datos. La lgica del cdigo de la figura 5.34 es bsicamente la misma de los cdigos que vimos anteriormente que leen flujos de datos. Esto es, se lee lnea por lnea hasta que se alcanza el fin del archivo. La lnea 23 llama al mtodo esttico creaTrabajador(String)el cual recibe el String que contiene la informacin del trabajador y devuelve un objeto de la clase Trabajador (aunque en realidad es un Obrero o un Supervisor, Recordemos el polimorfismo!). El mtodo creaTrabajador(String) est definido en la figura 5.35. Observemos que en la lnea 35 se llama al mtodo split(String) de la clase String. Este mtodo separa la lnea en varios Strings el argumento que se enva a este mtodo es el separador. En este caso le enviamos la coma (,) porque queremos que tome la coma como separador de los datos. El mtodo split(String)toma el separador y regresa a su vez un arreglo de Strings. Cada uno de estos Strings corresponde a un dato del objeto. El arreglo de Strings se guarda en el arreglo datos[]. Las lneas 43 y 44 de la figura 5.35 convierten los datos de tipo String a datos de tipo int. El mtodo trim() de la clase String asegura que no existan espacios en los Strings que se quieren convertir a nmeros pues de lo contrario, se generara una excepcin. Algo adicional que observamos del cdigo de la figura 5.35 es que dependiendo de la cantidad de datos de cada lnea del archivo y del tipo de trabajador, se hacen diferentes llamados a los constructores de las clase Obrero y Supervisor. Debido a que hemos utilizado un objeto de la clase ArrayList para almacenar a los trabajadores, estamos obligados a realizar unos pequeos ajustes al cdigo de la clase Main. La figura 5.36 muestra el cdigo de la clase Main que utiliza un ArrayList en lugar de un arreglo simple de trabajadores.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

162

Figura 5.34 Cdigo (Parcial) de la clase BaseDatos que lee los objetos desde un archivo de texto Ninguna de las dems clases: Impresora, Obrero, Supervisor y Trabajador sufre cambio alguno.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

163

Figura 5.35 Cdigo (Continuacin) de la clase BaseDatos que lee los objetos desde un archivo de texto La lnea 4 del cdigo de la figura 5.36 importa la clase archivosTexto.BaseDatos. Observe que se refiere al cdigo de la figura 5.34 pues en este paquete hemos puesto la clase BaseDatos. De esta forma, podemos tener clases que se llamen igual en un programa siempre y cuando no estn situadas en el mismo paquete. Tambin es importante observar que el arreglo de trabajadores est almacenado en un ArrayList y que este objeto lo regresa precisamente el mtodo cargaDatos() de la clase BaseDatos. Finalmente, vemos que tambin se ha cambiado el ciclo for de la lnea 12. Este tipo de ciclo for se le llama ciclo for mejorado y fue introducido a partir de la versin 1.5 de Java. El funcionamiento es muy simple: se declara una variable, en este caso la variable t, la cual debe ser del mismo tipo de los elementos del arreglo, en este caso de tipo Trabajador. Las instrucciones dentro del ciclo for (en este caso la lnea 13) se ejecutan tantas veces como
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 164

elementos existan en el arreglo. En cada iteracin, la variable declarada en el for cambia al siguiente elemento del arreglo.

Figura 5.36 Cdigo de la clase Main que utiliza un ArrayList de trabajadores Utilizando Serializacin de Objetos Finalmente, mostraremos la segunda alternativa para almacenar los datos de los trabajadores que consiste en almacenar los datos utilizando serializacin de objetos. Para ello, modificaremos de nuevo la clase BaseDatos de tal forma que se lean los datos de un archivo que contenga los objetos serializados. Para lograr la serializacin, tendremos que modificar las clases Trabajador, Obrero y Empleado pues ahora deben implementar la interface Serializable. La clase Main queda igual, excepto porque ahora importaremos la clase BaseDatos de un paquete diferente. Las figuras 5.37 a 5.41 muestran el cdigo de las clases modificadas para lograr la serializacin de objetos. Como puede verse en la figura 5.37, la clase BaseDatos utiliza ahora la serializacin de objetos para leer y cargar la informacin de los trabajadores en el arreglo. Tambin se tuvo que modificar la clase Trabajador agregando el mtodo esttico setNumTrabajadores que se llama en la lnea 21. Esto es debido a que cuando se leen los objetos con el mtodo readObject() no se ejecutan los constructores y era precisamente ah en donde se contaba el nmero de trabajadores. Ver lnea 14 de la figura 4.50. Algo interesante del cdigo de la figura 5.37 es que todos los objetos se leen con una sola instruccin de lectura, la cual est escrita en la lnea 15. Esto puede lograrse porque la clase
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 165

ArrayList implementa la interface Serializable y entonces es posible almacenar todos los objetos que contenga el arreglo en una sola instruccin de escritura como veremos ms adelante.

Figura 5.37 Cdigo de la clase BaseDatos que utiliza serializacin de objetos

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

166

Figura 5.38 Cdigo de la clase Obrero que implementa la interface Serializable

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

167

Figura 5.39 Cdigo de la clase Trabajador implementando la interface Serializable


Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 168

Figura 5.40 Cdigo de la clase Supervisor implementando la interface Serializable Finalmente, mostramos el cdigo de la clase GrabaEmpleados en la figura 5.41 el cual almacena el arreglo de trabajadores en un archivo. El funcionamiento de la clase GrabaEmpleados es muy simple. Se crea un arreglo de trabajadores utilizando la clase ArrayList. Este arreglo se serializa y se graba en el archivo Empleados.dat. Algo interesante que debemos mencionar es que podramos haber grabado objeto por objeto. Esto es, podramos haber escrito un ciclo que recorriera todo el arreglo de trabajadores y que fuera grabando trabajador por trabajador. Sin embargo, esto complicara el cdigo y adems tambin hara ms compleja la clase BaseDatos pues tambin tendra que leer trabajador por trabajador. Hemos aprovechado el hacho de que la clase ArrayList implementa la interface Serializable para que en una sola instruccin se grabe la informacin de todos los trabajadores en una sola instruccin, la cual est escrita en la lnea 27 de la figura 5.41. Aunque es mucho ms simple trabajar con serializacin de objetos, como lo muestran los cdigos anteriores, los programas que trabajan con muchos datos utilizan ms frecuentemente archivos o programas especializados que manejan informacin que se llaman Manejadores de Bases de Datos. stos ltimos tienen la ventaja de que traen incorporadas muchas funciones para el manejo de la informacin. Por ejemplo, se puede agregar, eliminar y modificar informacin de una manera muy sencilla. Adems manejan ndices para buscar y procesar informacin de una forma eficiente y rpida. Permiten tambin definir seguridad de los datos para que stos no puedan ser
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 169

alterados por personas sin los permisos correspondientes y muchas otras funciones relativas al manejo de datos. Lo lenguajes de programacin pueden comunicarse con estos programas de una manera muy sencilla.

Figura 5.41 Cdigo de la clase GrabaEmpleados Resumen del Captulo En este captulo vimos el manejo de excepciones y de flujos avanzados de datos. Las excepciones son situaciones extraordinarias que pueden ocurrir durante la ejecucin de los mtodos de los objetos o clases. Existen excepciones predefinidas en el lenguaje Java pero tambin es posible
Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 170

crear nuevas excepciones y utilizarlas en los programas. Vimos que cuando un mtodo hace un llamado a otro mtodo que puede provocar una excepcin, es necesario atrapar la excepcin mediante bloques try-catch o declarar que el mtodo llamador aventar a su vez la excepcin a quien lo llam utilizando la palabra throws en su declaracin. Finalmente, vimos el uso de flujos avanzados de datos. Los flujos son fuentes o destinos de datos y generalmente estn asociados a dispositivos de entrada salida. Vimos que existen flujos que graban y leen archivos en bytes, caracteres o lneas completas. Podemos utilizar flujos para grabar y leer informacin de archivos almacenados en el disco de la computadora. Tambin podemos utilizar flujos para leer informacin del teclado, enviar informacin a la consola, enviar y recibir informacin de otra computadora conectada a una red, etc. Utilizamos archivos para almacenar informacin de objetos y tambin utilizamos la serializacin de objetos para almacenar los objetos en el disco. A esto se le llama persistencia de objetos. Para lograr la serializacin, las clases deben implementar la interface Serializable. Esta interface no tiene mtodos que deban implementarse pero es requisito implementarla. Otra cosa importante que debemos recordar es que si una clase hace referencia a otra, es un requisito que ambas implementen la interface Serializable de lo contrario, obtendremos una excepcin. Si utilizamos la palabra transient podremos eliminar este requisito pero entonces los objetos referenciados se pierden y se asigna un valor de nulo a estos atributos.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

171

Ejercicios y Preguntas. 1. En el lenguaje Java se manejan excepciones (Exceptions) y errores (Errors). Describa la diferencia entre ambos conceptos. 2. Escriba la clase EnterosPositivos la cual tiene los mtodos estticos: suma(int,int), resta(int,int) y divide(int,int). Estas operaciones realizan la suma, la resta y la divisin de los enteros que reciben. Pueden recibir cualquier par de argumentos enteros pero el resultado debe ser un entero positivo menor o igual a 100, de lo contrario se generarn las siguientes excepciones: NumeroMuyGrandeException, NumeroNegativoException y NumeroDecimalException. Pruebe su cdigo con el siguiente cdigo:
public class EnterosPositivos { public static void main(String[] args) { try {suma(99,2); } catch (Exception ex) {ex.printStackTrace();} try {resta (3,4); } catch (Exception ex) {ex.printStackTrace();} try {divide(10,3);} catch (Exception ex) {ex.printStackTrace();} } // Definir las funciones y sus excepciones }

El resultado deber similar siguiente:


ejemplo.NumeroMuyGrandeException at ejemplo.EnterosPositivos.checa(EnterosPositivos.java:34) at ejemplo.EnterosPositivos.suma(EnterosPositivos.java:13) at ejemplo.EnterosPositivos.main(EnterosPositivos.java:7) ejemplo.NumeroNegativoException at ejemplo.EnterosPositivos.resta(EnterosPositivos.java:18) at ejemplo.EnterosPositivos.main(EnterosPositivos.java:8) ejemplo.NumeroDecimalException at ejemplo.EnterosPositivos.divide(EnterosPositivos.java:26) at ejemplo.EnterosPositivos.main(EnterosPositivos.java:9)

3. Escriba cdigo que provoque cada una de las siguientes excepciones: ClassCastException, ArrayIndexOutOfBoundsException y NullPointerException. 4. Modifique cdigo del ejemplo de la figura 5.3 de tal forma que el mtodo compraCoca() pueda aventar tambin las excepciones EnvaseRotoException y NoTieneGasException. Modifique el cdigo de la figura 5.4 para que maneje estas excepciones adicionales. 5. Describa la diferencia entre el bloque try y el bloque finally. En qu casos es recomendable usar el bloque finally. Escriba un ejemplo de cdigo que lo utilice adecuadamente.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

172

6. Explique la razn por la cual algunas excepciones deben ser atrapadas con el bloque catch y otras no. Cmo podra un programador crear excepciones que no tengan que ser atrapadas? 7. EL siguiente cdigo maneja las excepciones de manera incorrecta:

Explique la razn por la cual las excepciones no son manejadas correctamente y modifique el cdigo de tal manera que las excepciones se manejen de manera correcta. Puede utilizar comentarios que simulen acciones correctivas en los bloques catch. 8. El siguiente cdigo marca errores al compilar. Explique por qu marca error y corrjalo son agregar bloques try-catch.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

173

9. Describa que excepciones pueden suceder cuando se intenta abrir un flujo de datos asociado a un archivo. 10. Escriba un programa que lea un archivo de texto con informacin sobre la temperatura en varias ciudades de Mxico. Un ejemplo del archivo es el siguiente: Entrada.txt: Guadalajara, 28 Monterrey, 25 Veracruz, 35

El programa deber producir un resultado similar al siguiente: Nmero de Ciudades: 20 Temperatura ms alta: Veracruz, 35 Temperatura ms baja: Monterrey, 25 Promedio de Temperaturas: 30 11. EL siguiente cdigo almacena de manera permanente la informacin de los trabajadores del ejemplo de la nmina presentado en este captulo.
package serializacion; import import import import java.io.FileOutputStream; java.io.ObjectOutputStream; java.util.ArrayList; nomina.*;

public class GrabaTrabajadores { public static void main(String args[]) { try { FileOutputStream fos = new FileOutputStream("Empleados.dat"); ObjectOutputStream oos = new ObjectOutputStream(fos); ArrayList<Trabajador> trabajadores = new ArrayList<Trabajador>(); trabajadores.add(new Obrero("Armando Paredes", 60, 100)); trabajadores.add(new Obrero("Cindy Nero", 50, 35, 50)); trabajadores.add(new Obrero("Alan Brito", 40, 48, 0)); trabajadores.add(new Obrero("Marco Lpez", 55, 0)); trabajadores.add(new Supervisor("Rosario Mrquez", 180, 150)); trabajadores.add(new Obrero("Sergio Martnez", 75, 38, 120)); trabajadores.add(new Obrero("Luisa Domnguez", 50, 30, 110)); trabajadores.add(new Obrero("Petra Barrera", 55, 0)); trabajadores.add(new Obrero("Manuel Flores", 65, 35, 0)); trabajadores.add(new Supervisor("Alma Rios", 175, 0)); for (Trabajador t : trabajadores) { Conceptos de Programacin Orientada a Objetos Hctor A. Andrade G. 174

oos.writeObject(t); oos.flush(); } oos.close(); } catch (Exception e) { e.printStackTrace(); } } }

Cul es la diferencia entre este cdigo y el de la figura 5.41? Modifique el cdigo de la clase BaseDatos de la figura 5.37 para que lea la informacin almacenada utilizando este cdigo. 12. Escriba un programa en Java que lea un archivo de texto y muestre la cantidad de cada una de las vocales que tiene el archivo. Por ejemplo para el archivo: Hola La palabra murcilago tiene todas las vocales! La salida deber ser la siguiente: Nmero Nmero Nmero Nmero Nmero

de de de de de

as: es: is: os: us:

9 4 2 4 1

13. Dado el siguiente diagrama de clases, escriba cdigo que permita crear varios objetos de la clase Computadora y almacenarlos en un archivo utilizando serializacin de objetos.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

175

Observe que un objeto de la clase Computadora est compuesto a su vez por objetos de las clases Memoria, Monitor y DiscoDuro. Escriba tambin un programa que lea el archivo y despliegue la informacin de los objetos. La salida del programa deber ser la siguiente:
*** Caractersticas de la Computadora: HP dv2125 *** Monitor --> Marca: Samsung, Tamao: 21 pulgadas Disco Duro --> Marca: Seagate, Capacidad: 1000 gigas Memoria --> Marca: ScanDisk, Capacidad: 512 megas *** Caractersticas de la Computadora: LG xl123 *** Monitor --> Marca: LG, Tamao: 19 pulgadas Disco Duro --> Marca: Maxtor, Capacidad: 500 gigas Memoria --> Marca: Viking, Capacidad: 1024 megas 14. Describa las ventajas y desventajas que tiene el uso de la serializacin para lograr la persistencia de objetos en lugar de utilizar archivos de texto o de bytes.

15. Modifique el cdigo de la clase GrabaEmpleados de la figura 5.41 de tal forma que en lugar de asignar los datos de los trabajadores en el cdigo, stos sean ledos desde el teclado. Sugerencia: utilice el flujo de entrada System.in, el cual es un objeto de la clase InputStream y est asociado al teclado de la computadora.

Conceptos de Programacin Orientada a Objetos

Hctor A. Andrade G.

176

Anda mungkin juga menyukai