Descargado En

  • Uploaded by: Henry Torres
  • 0
  • 0
  • January 2021
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Descargado En as PDF for free.

More details

  • Words: 41,655
  • Pages: 214
Loading documents preview...
Descargado en:www.pcprogramasymas.com

Programación Orientada a Objetos con

“La novela”

Programación Orientada a Objetos con

“La novela” Nuria Medina Medina Ilustraciones: José Abraham Serrano Martínez

Diseño de colección, cubierta y pre-impresión: Grupo RC

Datos catalográficos Medina, Nuria Programación Orientada a Objetos con JAVA. “La novela” Primera Edición Alfaomega Grupo Editor, S.A. de C.V., México

ISBN: 978-607-622-596-7 Formato: 15 x 21 cm

Páginas: 216

Programación Orientada a Objetos con JAVA. “La novela” Nuria Medina Medina ISBN: 978-84-943450-5-0 edición original publicada por RC Libros, Madrid, España. Derechos reservados © 2015 RC Libros Primera edición: Alfaomega Grupo Editor, México, Febrero 2016 © 2016 Alfaomega Grupo Editor, S.A. de C.V. Pitágoras 1139, Col. Del Valle, 03100, México D.F. Miembro de la Cámara Nacional de la Industria Editorial Mexicana Registro No. 2317 Pág. Web: http://www.alfaomega.com.mx E-mail: [email protected] ISBN: 978-607-622-596-7 Derechos reservados: Esta obra es propiedad intelectual de su autor y los derechos de publicación en lengua española han sido legalmente transferidos al editor. Prohibida su reproducción parcial o total por cualquier medio sin permiso por escrito del propietario de los derechos del copyright. Nota importante: La información contenida en esta obra tiene un fin exclusivamente didáctico y, por lo tanto, no está previsto su aprovechamiento a nivel profesional o industrial. Las indicaciones técnicas y programas incluidos, han sido elaborados con gran cuidado por el autor y reproducidos bajo estrictas normas de control. ALFAOMEGA GRUPO EDITOR, S.A. de C.V. no será jurídicamente responsable por: errores u omisiones; daños y perjuicios que se pudieran atribuir al uso de la información comprendida en este libro, ni por la utilización indebida que pudiera dársele. Edición autorizada para venta en México y todo el continente americano. Impreso en México. Printed in Mexico. Empresas del grupo: México: Alfaomega Grupo Editor, S.A. de C.V. – Pitágoras 1139, Col. Del Valle, México, D.F. – C.P. 03100. Tel.: (52-55) 5575-5022 – Fax: (52-55) 5575-2420 / 2490. Sin costo: 01-800-020-4396 E-mail: [email protected] Colombia: Alfaomega Colombiana S.A. – Calle 62 No. 20-46, Barrio San Luis, Bogotá, Colombia, Tels.: (57-1) 746 0102 / 210 0415 – E-mail: [email protected] Chile: Alfaomega Grupo Editor, S.A. – Av. Providencia 1443. Oficina 24, Santiago, Chile Tel.: (56-2) 2235-4248 – Fax: (56-2) 2235-5786 – E-mail: [email protected] Argentina: Alfaomega Grupo Editor Argentino, S.A. – Paraguay 1307 P.B. Of. 11, C.P. 1057, Buenos Aires, Argentina, – Tel./Fax: (54-11) 4811-0887 y 4811 7183 – E-mail: [email protected]

Índice de capítulos

Prólogo......................................................................................... VII Guía didáctica.............................................................................. XI 1. Duda existencial ...................................................................... 1 2. El señor Paradigma................................................................ 4 3. Los justos y necesarios ......................................................... 9 4. Cuestión de atributos ......................................................... 13 5. Responsabilidades .............................................................. 18 6. Viaje astral .............................................................................. 23 7. Mi forma de hacer las cosas ............................................ 27 8. Curiosidades .......................................................................... 31 9. Madre, matrona y alumbramiento ............................... 37 10. Basura .................................................................................... 47 11. Ver mundo ........................................................................... 53 12. Helicóptero de viento...................................................... 62 13. Amor a primera vista ...................................................... 72 14. Detalles .................................................................................. 80 15. Sonríe y di “patata” .......................................................... 94 16. El método perdido......................................................... 102 17. Herencia............................................................................. 113 18. El árbol genealógico ..................................................... 129 19. Detenido por incumplimiento de contrato ......... 143 20. Vídeos polimórficos ...................................................... 153 21. Ligadura dinámica......................................................... 165 22. Reflexiones ....................................................................... 171 23. aDios .................................................................................... 182 Plantillas para escribir clases e interfaces en Java . 189 Índice de contenidos ............................................................ 199 V

Prólogo La programación orientada a objetos es un paradigma de programación que se gesta a finales de los sesenta (con Simula 67) y arranca en los años setenta (con Smalltalk), aunque no se populariza hasta la década de los noventa. En la actualidad, ningún programador que se precie puede vivir ajeno a dicho paradigma, ya que, muy posiblemente, sea el más utilizado. El núcleo del paradigma son los objetos y sus interacciones, al que se suman conceptos fundamentales como clases, encapsulación, polimorfismo o herencia. Esta filosofía de programación simula el principio de colaboración y responsabilidad que rige nuestra vida cotidiana, por lo que es bastante intuitivo. Este libro ofrece las claves del paradigma orientado a objetos y las particulariza en el lenguaje de programación Java. Sin duda, Java es el lenguaje de programación más popular en la actualidad (de acuerdo con el índice TIOBE, de junio de 2015). Y, según el citado índice (considerado casi un estándar de hecho), cubre el 17,8% de las referencias a lenguajes de programación en la Web frente al 7,8% de C++, que le sigue de lejos como el segundo lenguaje de programación más popular. Debido a su importancia y éxito, existen en el mercado numerosos manuales sobre Java. El problema es que a menudo estos manuales descuidan los principios que subyacen debajo de la nomenclatura del lenguaje, y el programador acaba escribiendo código Java, pero con un VII

NURIA MEDINA

© Alfaomega - RC Libros

diseño pobre o erróneo. Otras veces, los principios de la programación orientada a objetos se formulan como un recetario de conceptos que aburre al lector, quien no se esfuerza por captar la esencia del paradigma y olvida rápidamente lo aprendido. El lector descubrirá en el contenido del texto un enfoque totalmente diferente a lo que pueda haber encontrado antes sobre Java. Apostando por la diversión y la empatía como elementos motivadores del aprendizaje, es un propio objeto de un programa Java el que, inexplicablemente, toma conciencia de sí mismo. Durante su propia aventura, será este objeto quien descubra al lector, en términos de novela, todos los conceptos que articulan su mundo (por supuesto, con la rigurosidad imprescindible a la hora de transmitir la sintaxis y la semántica del lenguaje). Esta original obra puede ser usada para aprender Java, como recurso único o, mejor aún, combinado con otras fuentes formativas; pero también puede ser consumida por quienes ya conocen Java para reforzar los conceptos de la orientación a objetos o para, simplemente, pasar un buen rato leyendo. Acerca del autor La autora de este libro es titulada en Ingeniería Informática (2000) y doctora por la Universidad de Granada (2004). Actualmente, trabaja como profesora titular en dicha universidad donde imparte docencia de grado y de posgrado en distintos centros del complejo universitario. La Universidad de Granada (UGR) fue fundada en 1531 y cuenta con gran prestigio nacional e internacional. De hecho, según VIII

© Alfaomega - RC Libros

JAVA. LA NOVELA

el ranking de Taiwán 2014, ocupa la vigésima posición mundial en el campo Computer Science y es la primera universidad de España en investigación en informática. Desde 2001, cuando se incorporó a la plantilla de la UGR con una beca FPI (Formación Predoctoral de Investigadores), realiza productivas investigaciones en temas de hipermedia adaptativa, evolución del software y diseño de videojuegos educativos, principalmente. En términos de docencia, imparte habitualmente asignaturas relacionadas con la ingeniería del software y desde 2003 enseña programación y diseño orientado a objetos. Sus resultados han sido difundidos en la comunidad científica mediante la participación en numerosos congresos y la publicación de artículos en capítulos de libros y revistas de impacto, algunas de ellas situadas en el primer cuartil de sus respectivas categorías según el índice JCR (Journal Citation Reports). Asimismo, ha dirigido varios proyectos, tanto de innovación docente como de investigación, y en la actualidad es investigadora principal de un proyecto de excelencia de la Junta de Andalucía sobre videojuegos educativos. Adicionalmente, en términos de gestión, ha sido y es miembro de varias comisiones en el Departamento de Lenguajes y Sistemas Informáticos (al que pertenece) y en la Escuela Técnica Superior de Ingenierías Informática y de Telecomunicación; ocupando también el cargo de secretaria del Centro de Investigación en Tecnologías de la Información y las Comunicaciones de la UGR. En cuanto a movilidad, ha realizado varias estancias en la Universidad de Jaén y de Sevilla, así como tres estancias de investigación

IX

NURIA MEDINA

© Alfaomega - RC Libros

internacionales entre las que destaca la desarrollada en la Universidad de Boston (USA) en 2010. Agradecimientos A Pepe Parets, mi maestro, quien empujó con dedos de filósofo la ventana de la Orientación a Objetos para que pudiese contemplar el hermoso paisaje. A mis compañeros de la asignatura Programación y Diseño Orientado a Objetos: Ana Anaya, Zoraida Callejas, Miguel Lastra, María José Rodríguez y Paco Velasco, por enseñarme cada año cosas nuevas sobre Java y el trabajo en equipo. A María del Mar, compañera también de la asignatura, y una buena amiga dispuesta a ayudar incondicionalmente: gracias por la revisión de este texto. A mis estudiantes, pasados, presentes y futuros; y a todos los estudiantes de Java, por y para quienes este libro ha sido concebido. A mi editor, José Luis Ramírez, por creer en este proyecto.

X

Guía didáctica Apenas comiences a leer, notarás que este no es un material docente al uso. No se trata de un tutorial de Java, ni de un libro de transparencias de clase o de una colección de ejercicios de programación. Es, en realidad, una novela. Y, como todas las novelas, se nutre de personajes, escenarios, diálogos y acontecimientos. En este caso, todos estos recursos están dirigidos para, sin dejar de entretener, enseñar los conceptos que conforman el núcleo de la programación orientada a objetos. Con este fin, al hilo de un punto de partida inverosímil, se entreteje un entorno fértil para plantar con el mayor rigor docente todos los elementos que forman parte esencial de un programa orientado a objetos. Aunque la sintaxis utilizada es la de Java, la semántica de la mayoría de los conceptos (objetos, clases, interfaces, estado e identidad, diseño basado en responsabilidades, encapsulamiento, modularidad, herencia, ligadura, polimorfismo, reflexión…) puede ser aplicada con matices en otros lenguajes orientados a objetos. La novela puede ser explotada, a modo de complemento o recurso único, tanto para adquirir como para afianzar conocimientos sólidos de programación en Java. La metodología de enseñanza es indiscutiblemente sencilla, únicamente es necesario leer. No obstante, se recomienda que se realice una lectura activa, que propicie y tome por norma reflexionar y poner en práctica lo leído.

XI

NURIA MEDINA

© Alfaomega - RC Libros

Para facilitar la comprensión, las cuestiones sintácticamente más “farragosas” son presentadas en pies de página. De modo que, según el grado de conocimiento del lector, estas anotaciones se vuelven imprescindibles (para el novato en Java) o accesorias (para el experto). En el código al pie, como en Java, algunos comentarios son introducidos con la marca “//” (si tiene solo una línea) o delimitados con “/*” y “*/” (cuando constan de varias líneas). Finalmente, a modo de resumen, se adjunta un índice de contenidos y dos plantillas, una para escribir clases completas en Java y otra para interfaces. En el presente texto se han usado las comillas inglesas(“ ”) para enmarcar la reproducción de citas textuales y para indicar que una palabra o expresión es impropia, vulgar, se utiliza irónica o metafóricamente, o con un sentido especial. Mientras que las comillas latinas (« ») se han dedicado a encerrar, dentro de la narración, los textos que reproducen de forma directa los pensamientos de los personajes. Dicho esto, solo queda añadir: lee, disfruta y aprende.

XII

1. Duda existencial No vas a creerme: no sé quién soy. ¡Qué vergüenza! Nos acabamos de conocer y te suelto esto a bocajarro. Discúlpame si te he preocupado con mi fulminante comentario, a pesar de la turbación que me embarga no existen motivos de alarma: no sé quién soy, pero me encuentro perfectamente. La causa de mi duda vital no concurre en pérdida de memoria alguna. Lo he descartado completamente porque no tengo evidencias de ningún percance que pudiera haberme provocado el vacío que experimento; y, además, no estoy en blanco, conozco algunas cosas. Por ejemplo, sé a ciencia cierta que tengo dieciocho años y mi nombre es Juan Díaz Requeté. También sé cuántos hermanos tengo y de qué asignaturas estoy matriculado en la Universidad de Granada. Conozco esos detalles y, algunos más, como por ejemplo mi número de DNI, que, no te lo tomes a mal, reservaré para proteger mi privacidad. Sin embargo... ¡desconozco otros muchos datos acerca de mí mismo! Costumbres, gustos, manías... ¡nimiedades! No son relevantes, de acuerdo, pero las echo en falta. Para que me entiendas: ¿cuál es mi color favorito? ¿Cuánto peso? ¿Soy más de perros o de gatos? ¿Relamo la tapa del yogur cuando se acaba? No tengo ni idea y debería saberlo, ¿verdad? En fin... aparcando estas incógnitas que lucen absurdas una vez diluidas en tinta sobre papel, tengo que insistir en 1

NURIA MEDINA

© Alfaomega - RC Libros

que me hallo inmerso en fenómenos extraños y variopintos. En ocasiones, más que algo que me sucede es algo que intuyo fuera de lugar. No advierto el porqué, pero casi todo me escama, y he de admitir que esta sensación me sobreviene tan a menudo que la mosca que tengo detrás de la “oreja” ya parece un tatuaje. Fíjate, tengo dieciocho años, no dudo de eso, pero, ni de lejos, me parece haber vivido tanto... Y, ya puestos a engordar la suspicacia, te confesaré que tampoco sé nada acerca de lo que significa vivir. ¿Quién soy? ¿Por qué y para qué existo? Ni la más remota conjetura, pero el caso es que aquí estoy, rodeado de partículas de luz que revolotean como diminutas luciérnagas al compás del ruido de un ventilador que no acierto a vislumbrar; muy cómodo, eso sí, pues tengo bastante espacio a mi alrededor; y con los “brazos” cruzados, esperando vete a saber qué, mientras atisbo algunos otros “cuerpos” por allá arriba y por allá abajo. ¿Paranoico? No tengo orejas, pero puedo oír tus pensamientos. ¡Je, je! ¡No soy un paranoico!, es solo que estoy perdido. Bueno, metafóricamente hablando, porque es difícil estar perdido con una flecha apuntándome de forma perenne a la “espalda”. Ah... ahora he pasado de paranoico a loco, ¿me equivoco? Pues debo aclararte que el puntero no es, en absoluto, un producto de mi imaginación; la flecha está, ¡vaya que si está! Veo la punta perfectamente; y también alcanzo a discernir el otro extremo, procedente de la otra región. 2

© Alfaomega - RC Libros

JAVA. LA NOVELA

“La región de las flechas” (como la he bautizado porque allí se apilan todas ellas) se me antoja un casillero gigante bien organizado pero algo oscuro. De hecho, la penumbra ha resultado un nada despreciable inconveniente a la hora de investigar el origen del puntero. Tremendo esfuerzo que me costó leer el rótulo pegado en la casilla de donde parte la flecha que me apunta. Aún lo recuerdo... acabé exhausto, y, cuando lo consigo, decepción... La etiqueta tan solo pone: “var”. ¿“var”?, ¿debería decirme algo? Pues no, no me dice ni “mu”.

3

2. El señor Paradigma —Juan, ¿puedes oírme? —¡Juan!, escucha… —¡Juan! Oigo una voz en mi “cabeza”, no son elucubraciones, esta vez suena con un timbre distinto, grave, como el tono de un maestro. Apenas ha dicho seis palabras, pero promete ser interesante. Tengo que contestar. Sí, a riesgo de parecer ridículo, voy a contestar. —¿Quién eres? —pronuncio en alto y aguardo un momento que se me antoja eterno. —Juan, soy el señor Paradigma —responde cuando el susurro del ventilador se detiene para cederle la palabra. —¿El señor Paradigma? —Sí, el señor Paradigma, vengo a ayudarte con tus dudas. —Genial… —musito, descolocado. Si tuviese piernas me flaquearían de lo nervioso que me estoy poniendo. —Venga, chico, dispara —me increpa la voz. Tienen que pasar unos cuantos ciclos de reloj antes de que caiga en la cuenta de que lo que me está requiriendo es que le lance una pregunta. Debo haberle parecido un idiota, 4

© Alfaomega - RC Libros

JAVA. LA NOVELA

pero su “presencia” me impone y estoy más cortado que nunca. —Señor Paradigma, quiero saber quién soy. ¿Podría ayudarme con eso? —No, con eso no. —Su respuesta es delusoria y, curiosamente, el contratiempo me hace ganar seguridad. —¿Por qué no? —replico. —Porque es pronto para eso. Antes debes averiguar otras muchas cosas. El camino hacia el “yo” es un recorrido largo y transversal. —No conozco el término transversal, pero no voy a preguntárselo para quedar de inculto. Me mantengo callado, invitándole a continuar—: antes de saber quién eres, debes saber qué eres. ¿No crees? —Ajá —mascullo, cada vez más desorientado. —¿Quieres saberlo? —¿Cómo no iba a querer? —repongo impulsivo—. Adelante, dígame qué soy. —Eres un objeto. —¿¿Qué?? —No lo habré entendido bien. Soy Juan, un estudiante de dieciocho años. —Eres un objeto —confirma. —Por favor, explíquese —inquiero, mientras el “corazón” me trepa por la “garganta”. —Eres un objeto y estás dentro de un programa Java. 5

NURIA MEDINA

© Alfaomega - RC Libros

—¿Java?, ¿la isla? —Java, el lenguaje de programación. —¿Cómo puede ser? —lloriqueo, aunque en realidad empiezan a casarme muchas de las extravagantes piezas que no acertaba dónde colocar. —Tranquilo, no eres el único objeto del mundo, los demás también lo son. ¿Los ves? —Sí, allá arriba y allá abajo —respondo ágil, aunque no gimoteaba por eso, me da igual que haya otros objetos; “mal de muchos, consuelo de tontos”, no quiero ser un objeto y menos vivir en un programa. Súbitamente me surge otra duda y la curiosidad me repone un poco—: ¿ellos lo saben? —¿Quieres decir si saben que son objetos? —Sí, eso. —No, no lo saben, ni necesitan saberlo; actúan como están programados y no se cuestionan nada. —Entonces, yo… —Tú eres un objeto excepcional, muy de vez en cuando nace uno así, y claro, quiere saber… y bueno, ahí entro yo en juego —suspira cansado, y reparo en lo viejo que es—. Mi función es explicarte el paradigma de programación orientado a objetos para que no te rebeles a tu destino. —¿Por qué es tan importante que no me rebele?, quiero decir: soy solo uno y aquí debe haber cientos… —Hijo mío, el buen funcionamiento de un programa Java depende de la adecuada colaboración entre todos sus 6

© Alfaomega - RC Libros

JAVA. LA NOVELA

objetos. En este rebaño no puede sobresalir ni una oveja descarriada —suspira de nuevo. —Ah, ah —murmuro irónico, y es que tiene su gracia: convencido de que era un estudiante, me entero de que soy un objeto y, ahora, va y me llama oveja… —Comencemos a resolver tus enigmas —propone entusiasta, y ajeno a mi malestar le brillan los “ojillos”—. ¿Por dónde quieres empezar? Ahora quien suspira soy yo; debe ser que, como los bostezos, los suspiros se contagian. —Supongo que por el principio. ¿Podría aclararme qué es un paradigma? —Claro —ríe—. Ya veo que no quieres dejar pasar ni media. El término paradigma se origina en la palabra griega… —Espere —le interrumpo—. ¿Puede explicármelo sin mucho rollo? —De acuerdo, sin mucho rollo —acepta y parece hasta aliviado—. Un paradigma es una forma de hacer las cosas, un modelo contextual que nos indica qué hacer y cómo hacerlo. Así que un paradigma de programación establece un marco tecnológico y un estilo para programar. —Um, creo que lo entiendo, pero no estoy seguro —declaro con humildad. —No te preocupes, por ahora es normal, simplemente quédate con el núcleo del paradigma orientado a objetos. 7

NURIA MEDINA

© Alfaomega - RC Libros

—Y..., si se puede saber, ¿cuál es el núcleo del paradigma orientado a objetos? —pregunto ingenuamente. —Los objetos, claro 1 —responde el señor Paradigma y se echa a reír, conmigo y de mí.

Ilustración 1. Objeto apuntado por un puntero. En Java, los objetos son referenciados mediante punteros (siempre, por eso no hay que indicarlo sintácticamente).

1

Los objetos son el núcleo del paradigma de programación orientado a objetos, no las clases (concepto introducido en el capítulo 6). De hecho, existen lenguajes de programación orientados a objetos que no tienen clases, sino objetos prototipo

8

3. Los justos y necesarios Una vez que he aceptado que soy un objeto, me comienza a inquietar algo que antes daba por sentado: ¿quién es, entonces, Juan Díaz Requeté? Por su parte, el señor Paradigma aguarda mis preguntas con mucha paciencia, sin meterme prisa y dejándome clara su afable disposición con el bonachón gesto que ha congelado en su “rostro”. Aun así, yo no me atrevo a preguntarle por el tal Juan porque me parece que eso no debe caer dentro del paradigma de programación orientado a objetos. Y, entre pitos y flautas, mi indecisión crece al mismo ritmo que mi inquietud, estando cada vez más intrigado respecto a quién es Juan y más convencido de que preguntarlo sería inapropiado. —Bueno, Juan, ¿querrás saber quién es Juan, verdad? —el sinsentido rompe el silencio que se había instalado entre ambos. —Vaya... señor Paradigma, ¿puede leerme el pensamiento? —Por supuesto, pero tampoco era necesario, los objetos especiales siempre quieren saber a quién o a qué modelan. —¿Modelar? —Cada objeto modela un ente perceptible en el mundo exterior.

9

NURIA MEDINA

© Alfaomega - RC Libros

—¿Se refiere al más allá? —cuestiono con el respeto que me produce hablar de “los otros”. —Sí, al mundo que queda fuera del ordenador. —¡Toma ya!, ¡existe! —aplaudo. —Por supuesto que existe y desde mucho antes que el nuestro. Pero no me pidas que te describa cómo es ese mundo porque antes me has dicho que no querías rollos y ese sería un rollo muy largo. —Ok, siento la interrupción —me disculpo, reprimiendo mis ansias de conocer—. Continúe, por favor. —Como estaba argumentando, un objeto en un programa Java representa un objeto del mundo “real”. Ese objeto puede ser un objeto físico o un objeto conceptual. —¿Eh? —Para que me entiendas: una asignatura es un objeto conceptual, no se puede tocar; mientras que un profesor es un objeto físico, se podría tocar… —Bueno, no sé yo si tocar a un profesor... y encima llamarle objeto... —Dejando ese par de matices de lado2 , ¿lo has entendido, verdad?

2

Un objeto puede ser un objeto cotidiano como una impresora, pero también una pe un conjunto, etc.

10

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Sí, creo que sí, cualquier cosa que exista o se pueda imaginar en el otro mundo es un objeto en este, ya sean seres vivos o elementos inertes. —Agudizo la vista y oteo el horizonte intentando echar cuentas—. ¿Todos los objetos de ahí fuera caben aquí dentro? —A ver... en un programa caben muchos objetos, pero solo entran los que se necesitan; los justos y necesarios. Dicho de otro modo, los objetos que tienen significado en el dominio de la aplicación. —Me he perdido —confieso. —Te pondré otro ejemplo. En una entidad bancaria hay clientes, cuentas de ahorro3 , empleados, sucursales... pero también existen papeleras e interruptores de la luz. Evidentemente, estos dos últimos elementos no son relevantes para informatizar el banco y no serían objetos Java en la aplicación informática. —¿Qué es una entidad bancaria? —Olvídalo —se disculpa azorado el señor Paradigma—. Esos conceptos están fuera de tu dominio de aplicación. Y, aunque, paradójicamente, sabes qué es una isla o un yogur, desconoces la mayoría de los objetos y lugares que quedan fuera de tu dominio de aplicación. A todos los objetos excepcionales les pasa, tranquilo. —No, si estoy tranquilo, pero…, solo por concretar —persevero para llegar al fondo de la cuestión—: ¿cuál es mi dominio de aplicación? 3

Una cuenta de ahorro es otro ejemplo de objeto conceptual

11

NURIA MEDINA

© Alfaomega - RC Libros

—Este programa es una aplicación para gestionar matrículas y expedientes en la Universidad de Granada (UGR). —Entiendo... —Trago saliva, consciente de que estoy a punto de resolver el misterio—. Entonces, yo represento a un estudiante que asiste a esa universidad en el mundo exterior. —Exacto, tú eres Juan Díaz Requeté dentro del programa. —¡Gracias al cielo! —exclamo—. Me encantaba mi nombre.

Ilustración 2. Cada objeto del programa software refleja la imagen de un objeto conceptual o tangible que existe y tiene semántica en el dominio de aplicación de dicho programa.

12

4. Cuestión de atributos El señor Paradigma se ha marchado, asegura que más tarde regresará. En cierta medida lo agradezco, pasada la agitación inicial necesito meditar a solas. Además, creo que por mi cuenta y riesgo puedo hacer algunas averiguaciones más sobre el paradigma orientado a objetos y, ciertamente, me apetece emprender esta labor detectivesca. Para empezar, el conocimiento parcial sobre mí mismo creo que ya puedo razonarlo: conozco de Juan los datos que son necesarios para la aplicación informática de la que formo parte. Como dijo el señor Paradigma, los justos y necesarios. Conozco mi nombre4 , apellidos, fecha de nacimiento5 , DNI, número de hermanos 6 , asignaturas en las que estoy matriculado, expediente… pero no conozco mi color favorito, el nombre de mi mascota (si es que tengo algún perro o un gato, o quizá un canario), ni mis hábitos diarios. Es una

4

String nombre = “Juan”; /* el atributo denominado nombre está declarado de tipo String y contiene el valor “Juan” que es una cadena de caracteres */ 5 GregorianCalendar fechaNacimiento; /* el atributo fecha de nacimiento está declarado de tipo GregorianCalendar y en esta línea no contiene ningún valor válido o lo que es lo mismo su valor actual es null */ 6 int numeroHermanos = 2; /* el atributo número de hermanos está declarado de tipo int y contiene el valor entero 2 */

13

NURIA MEDINA

© Alfaomega - RC Libros

lástima, pero así es. Ojalá no fuese tan cotilla y me conformase con los atributos significativos, pero me temo que seguiré notando la falta de esos otros detalles sobre Juan que nunca conoceré. «¿Qué le vamos a hacer?, son gajes de ser un objeto excepcional», reflexiono presuntuoso. En cualquier caso, mi duda existencial persiste: ¿quién soy?, vuelve la burra al trigo. No creas que con la conmoción de los últimos acontecimientos, ahora sí, perdí la memoria. Sé cómo soy, es decir, mis atributos, los que ya enumeré arriba y otros. Pero estos no definen mi Ser. Algo en mi interior me grita que soy algo más que una colección de atributos. Vamos, que no me conformo con ser una fotografía del tal Juan, por muy bonito que tenga el nombre. —¡Te pillé! —¡Menudo susto me ha dado! —reclamo al señor Paradigma que acaba de irrumpir en la escena digital como un elefante en una cacharrería. —Lo siento, chico. Pero no pude evitar observarte mientras analizabas tu estado. —¿Observarme o espiarme? —refunfuño con descaro. —No seas quisquilloso, el ser omnipresente es lo que trae consigo. No puedo evitar estar al tanto de todo lo que ocurre en el programa. —Está bien, tendré que acostumbrarme. Por cierto, cambiando de tema, ¿ha dicho que yo analizaba mi estado?, ¿estado? 14

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Sí, tu estado, el conjunto de tus atributos. —Ah, eso... Me he dado cuenta de que cada atributo recoge una propiedad del objeto al que represento, en este caso, una característica de Juan que es relevante para la aplicación académica de la UGR. —Eso es —encomia el señor Paradigma, pero no se resiste a ampliar mi explicación—: por ejemplo, el DNI sirve para identificarlo, su nombre y apellidos para emitirle certificados, su número de hermanos para saber si pertenece a una familia numerosa y en tal caso recalcular las tasas de su matrícula, su dirección postal para enviarle correspondencia… —Pare…, que me aburro… —Vaya, si no soy de utilidad, me marcho —contesta notoriamente malhumorado y comienza a voltear su “cintura” filosófica para darme la “espalda”. —¡Alto!, que todavía tengo preguntas. —Ajá… —resopla engreído—, dime. —¿Mi estado puede cambiar? Es que juraría que primero mi dirección era “C/Elvira, 7” y ahora es “C/Camino de Ronda, 23”. —Bien apuntado. Efectivamente, has hecho mudanza y sin cargar un solo bulto —señala y se ríe—. Tu estado es variable y, por tanto, el valor de algunos atributos puede verse modificado a lo largo del tiempo. ¡Plaf!, se me viene a la “cabeza” mi estado de ánimo; ese, claro está, no es significativo para el programa, pero es tela 15

NURIA MEDINA

© Alfaomega - RC Libros

de variable: por la mañana me levanto de malas pulgas, al mediodía me almorzaba el mundo, a la tarde me pongo nostálgico y por la noche me entran ganas de fiesta. ¿Le pasará lo mismo al otro Juan? Ojalá pudiera escapar de este programa y de este ordenador para preguntárselo… —¡Espabila, que te has quedado ensimismado! —Ah, sí, disculpe —respondo y me ruborizo al recordar que el maestro puede leer mis pensamientos—. Ahora, si no le importa, puede darse la vuelta y hacer como que no escucha lo que pienso. Dicho y hecho, el señor Paradigma desaparece y consigo un poco de intimidad, la justa y necesaria, para retomar mis divagaciones existenciales. Estaba en lo cierto, no soy un estudiante de dieciocho años que vive en Camino de Ronda, eso es cómo soy, y dado que mi estado es variable no puede constituir mi esencia, porque la esencia debe ser imperturbable. ¡Qué lío! Estas meta-dudas son harto complicadas de resolver porque cuando descifras un misterio nacen cientos. Me recuerda a la pescadilla que se muerde la cola. Aunque: ¿qué es una pescadilla?, y, ¿una cola? Otra vez lo mismo, quiero gritar: ¡que alguien me ayude! Pero entonces el señor Paradigma reaparecería con su “bigote” de caballero impecable y me pediría tiempo, con palabras sofisticadas como transversal, y yo me callaría la “boca” y miraría al suelo... Desearía que hubiese alguien más a quien recurrir. Espera... eso es. Oye, se me está ocurriendo que quizá tú podrías ayudarme. 16

© Alfaomega - RC Libros

JAVA. LA NOVELA

Venga, deja a un lado qué eres: tu ocupación, tu edad, tu físico, tu familia, la ciudad en la que vives, el coche que tienes o que no tienes… y dime, por favor, con total honestidad: ¿qué queda? ¿Quién eres tú?

17

5. Responsabilidades El tiempo avanza con la inercia de una apisonadora, y los milisegundos se confunden con las horas. Aquí no pasa nada. Por pasar, no pasa ni una mosca. ¿Destino? El señor Paradigma me habló de mi destino, pero ¿a qué destino se refería?, ¿a cubrirme de telarañas? —Deja de quejarte, chico, tienes responsabilidades. Ya está aquí otra vez. ¿Por qué no avisará cuando llega? Menudo sobresalto. —¿Responsabilidades? —repito para asegurarme de que lo he escuchado bien. —Responsabilidades, tareas que debes resolver. Tareas en las que tú estás al mando. —¿Yo solito? —discurro, con cierta zozobra. —Si la tarea es compleja puedes pedir ayuda a otros objetos —suspiro durante la pausa teatral que el señor Paradigma imprime magistralmente—, pero la obligación de que se realice correctamente es tuya —sentencia. Me está tomando por un pusilánime, cree que voy a amedrentarme ante mis responsabilidades. Yo no puedo leer sus pensamientos, pero ya lo voy conociendo. No le daré el gusto. —Manos a la obra, entonces —exclamo, recién enfundado en mi “traje” de ejecutivo—. Voy a llevar a cabo una de esas 18

© Alfaomega - RC Libros

responsabilidades. ¿Cuál anudándome la “corbata”.

JAVA. LA NOVELA

me

aconseja?

—pregunto,

—¡Alto ahí! —El señor Paradigma me detiene—. No puedes realizar tus responsabilidades cuando a ti se te antoje. —Ah, ¿no? —replico perplejo. —No, debes esperar a que hagan falta. —Y, si no es mucho preguntar, ¿cómo sabré que una de mis obligaciones es requerida?: ¿sonarán trompetas?, ¿llorará un santo?, ¿un haz de luz garabateará mi nombre en el espacio? —Te llegará una petición —declara el maestro con una serenidad que contrasta con los clamores que venían emitiendo mis fantasiosas alternativas. —¿Me lo pedirán? —comprendo, pero—: ¿quién?, ¿quién me lo pedirá? —Otros objetos. —Vaya, pensé que podría ser Juan. —Bueno, digamos que algunos objetos están dirigidos desde el más allá. Pero a riesgo de desengañarte, te diré que no creo que sea el estudiante Juan quien use esta aplicación. Lo más probable es que sea un administrativo de la UGR; uno o varios. —¿Los administrativos son personas, verdad? —Eso dicen —susurra y me guiña un “ojo”. 19

NURIA MEDINA

© Alfaomega - RC Libros

—Entonces, ¿cómo manejan esas personas a los objetos?, ¿con un control remoto? —Algo parecido —sonríe con una mueca que afirma: «te queda mucho por aprender», y añade—: esos objetos se controlan a través de la interfaz de usuario. Esta permite la comunicación entre los humanos y el ordenador. —¡Qué chistoso! ¿Cómo se comunica un humano con un objeto, por señales de humo? —pregunto con guasa, pues creo que el señor Paradigma me está tomando el pelo. —Igual que dos objetos se comunican entre sí, pero usando de intermediaria a la interfaz de usuario —responde con su talante habitual—. Me voy, hay unos asuntos primordiales que debo resolver esta mañana. —¡Espere!, al final no me ha dicho cómo se comunican dos objetos. —Hablando se entiende la gente, ¿no? —¿Qué quiere decir? ¿Que los objetos hablan? —Tú no hablas, parloteas. Vaya, como las suelta el señor Paradigma... —En serio, explíquemelo, por favor. —Cuando un objeto necesita que otro objeto realice una tarea de la que es responsable, se lo pide enviándole un mensaje. El objeto receptor del mensaje resuelve la tarea y luego devuelve el control al objeto emisor. —Me he liado con eso del objeto receptor y emisor. 20

© Alfaomega - RC Libros

JAVA. LA NOVELA

—El objeto emisor es quien emite el mensaje y el objeto receptor 7 el que recibe el mensaje, el propio término lo indica. —Entonces, ¿quién tiene que ejecutar la tarea? —Estás un poco espeso —me regaña y no protesto porque razón no le falta—. Atiende. El objeto responsable de ejecutar la tarea es el objeto receptor, el que ha recibido el mensaje. Imagina que tú estás resolviendo una responsabilidad y le envías un mensaje a otro objeto para que te proporcione un dato que necesitas, tú serías el emisor y el otro objeto el receptor. —¡Ahora! —Sonrío feliz por haberlo captado—: los objetos se envían mensajes unos a otros para pedirse cosas. En cuanto a esto, me surge otra duda: ¿siempre que a un objeto se le envía un mensaje ejecuta la tarea que se le solicita?, ¿no puede negarse? —Siempre que la tarea esté entre sus responsabilidades la realiza. Por ejemplo, se le puede pedir a un bombero que apague un fuego, pero no se le puede pedir que baile la danza del vientre. —¿Cómo? —Ni caso a mi último ejemplo. El tema es que los objetos colaboran entre sí para alcanzar los objetivos de la 7

objetoReceptor.mensaje(argumento1,

siendo unaVar una variable que apunta a un objeto receptor capaz de resolver el método suma, y conteniendo las variables, x e y, los dos números enteros que se pasan como argumentos para ser sumados */

21

NURIA MEDINA

© Alfaomega - RC Libros

aplicación y, en esa colaboración, las peticiones de ayuda se realizan mediante envío de mensajes. —Como una comunidad perfecta: sin vagos, antipáticos, ni flojos. —No sé si perfecta, pero sí una comunidad bien avenida, eso desde luego. Qué idílico es todo. Me están dando ganas de vociferar: «¡Paz y Amor!».

Ilustración 3. Normalmente, cuando un objeto recibe una petición solicita ayuda a otros objetos para resolverla. Si la tarea es compleja, pueden involucrarse muchos objetos. 22

6. Viaje astral El señor Paradigma no cesa de consultar el reloj del sistema, está visiblemente nervioso por esos otros asuntos que desea resolver. A regañadientes, le dejo marcharse, no sin antes arrancarle la promesa de que volverá pronto. Cada vez tengo más ganas de seguir aprendiendo, aunque sea demasiado orgulloso para reconocérselo a él. En su ausencia, aguardo alerta por si me llega algún mensaje, pero no llega y del aburrimiento transito hacia la pereza. Obediente, me tiendo. El movimiento del aire conforma una vibración agradable y me dejo acariciar. Para matar el tiempo me fijo en las partículas de luz que iluminan mi estancia: brillan más refulgentes que de costumbre. El vaivén me resulta hipnótico y me dedico a contarlas. Al principio son decenas, luego se le unen centenas, ahora miles. ¿Qué está pasando? La explosión de claridad me ciega. Cierro los “ojos”, pero sigo viéndolas. Pizpiretas, comienzan a danzar ejecutando una coreografía que culmina con la creación de una espiral rutilante en la que yo soy el centro. La luz de la espiral reverbera y crece sin cesar. La expansión parece no tener límites, ni en altura ni en anchura; y así debe ser porque para cuando se detiene, el radio del rizo es infinito. Justo ahí empiezo a flotar y me desdoblo en dos entes, unidos por un “cordón umbilical” de unos tres milímetros de diámetro y apariencia de rayo. Mi yo de siempre se queda en 23

NURIA MEDINA

© Alfaomega - RC Libros

la estancia, que ahora es menos luminosa, con los “ojos” cerrados. Mi nuevo yo se eleva sobre el haz de luz ancestral. Empieza el viaje. Oteo los otros objetos alojados en mi región y también la región de los punteros. Luego, avanzo por el vacío, nadando en el aire, descubriendo mundos que jamás hubiera soñado. Me detengo. Una placa oxidada reza: “disco duro”. Me adentro en el enorme terreno con “pies” etéreos, no quiero estropear nada, pero mis pasos me dirigen insondables a un lugar que me atrae como un imán.

Ilustración 4. El código Java de las clases se almacena en el disco duro, cada clase en un fichero con el mismo nombre de la clase y extensión .java. 24

© Alfaomega - RC Libros

JAVA. LA NOVELA

Avanzo sin miedo. Me siento un gigante, un héroe, un conquistador... —¡Espera, chico! —me grita el señor Paradigma. No puedo creerlo, me ha seguido hasta aquí, y encima me llama “chico”, a mí, al más grande de todos los objetos—. ¿Qué haces en el código fuente? —¿Código fuente? —repito alelado, y se me bajan los humos de golpe. —El código fuente del programa, los ficheros .java. —¿Qué es un fichero .java? —Es un fichero que almacena las definiciones e instrucciones en lenguaje Java correspondientes a una clase. —¿Qué es una clase? —pregunto, pero enseguida cambio de opinión. Mejor, dígame: ¿cuál es el fichero .java de mi clase? Porque yo tengo clase, ¿verdad? —Sí, tienes clase y estilo, no hay más que verte —se monda de risa y no sé de qué, pero se lo paso por alto—. Y, también, tienes una clase. El fichero donde se almacena el código Java de tu clase se llama como tu clase, pero con la extensión .java. —Señor Paradigma, no dé tantos rodeos que parece un vaquero. ¿Cómo se llama el fichero de mi clase? —EstudianteGradoInformatica.java —Qué largo... —Me gusta mucho más Juan.

25

NURIA MEDINA

© Alfaomega - RC Libros

—El nombre de la clase debe ser significativo, por eso a veces queda un poquito largo. ¿Qué quieres que hagamos ahora? —Si le digo la verdad, maestro, tengo la mente en blanco. —Comprensible, si te parece bien damos un paseo, tomas el aire y de paso te muestro tus métodos. —De acuerdo, ya me dirá para qué sirven esos métodos. Pero, antes, una cuestión práctica: ¿tengo que ir arrastrando este “cordón” todo el tiempo? —Deberías, sobre todo si quieres regresar del viaje astral. —¿Viaje astral? —No sigas por ahí, esos temas son harina de otro costal y no pienso rebozarme.

26

7. Mi forma de hacer las cosas Menudo paseíto. El señor Paradigma no ha parado de hablar durante todo el camino. En ocasiones me ha metido un buen rollo pero, si te soy sincero, he desconectado y me he deleitado contemplando el código fuente mientras le asentía. Sé que no está bien fingir entendimiento, pero las palabras en Java son tan armoniosas que el poema que me recitaban sonó más fuerte en mi mente que la voz del señor Paradigma en mis “oídos”. —No me estabas escuchando. —A ratos —confieso, ¿para qué molestarme en mentir? —Anda, dime qué es un método para asegurarme de que lo has entendido a pesar de haber desatendido tres cuartos de mi explicación. —Un método es el bloque de código que se ejecuta cuando un objeto recibe un mensaje. Es la forma de resolver la petición que nos hacen a través de un mensaje. —¿Y? —El método tiene dos partes —refrendo como un papagayo—: cabecera y cuerpo. El cuerpo 8 es el bloque de

8

{sentencia1; sentencia2;...sentenciaN;} /* Cuerpo del método. Ejemplo: {int r; r=x+y; return r;} es un cuerpo con tres sentencias que son: una declaración, una expresión y una devolución de valor */

27

NURIA MEDINA

© Alfaomega - RC Libros

código; es decir, el conjunto de sentencias escritas en Java que se ejecutarán. Por su parte, la cabecera 9 es una declaración que define cómo debe invocarse ese método y por lo tanto debe “enganchar” con el mensaje. —¡Enganchar! ¿Pero qué palabreja es esa? —matraquea el señor Paradigma, aguantándose las ganas de propinarme un coscorrón. —No se ponga así —me defiendo—. Con “enganchar” quiero decir que el nombre del método debe ser igualito al nombre del mensaje para que casen. Y no solo eso, los argumentos del mensaje (datos de entrada) deben coincidir en número y tipo con los parámetros formales del método. Según he entendido, esto último significa que si para resolver la petición necesitas un número entero no sería válido que te pasaran una manzana. Lo cual, es totalmente comprensible —peloteo. —¿No se te olvida algo? —continúa incansable. Rebusco en mi memoria, pues la perorata del maestro fue dadivosa y, aunque no sé si se referirá a eso, decido tirarme a la piscina; incluso a riesgo de volver a enojarlo porque es más que evidente que hoy no está de humor. —Se me olvidaba... algunos métodos pueden devolver un valor como respuesta a la petición. Es decir, el objeto

9

respuesta nombreMetodo(parametro1, parametro2,...,parametroN) /* Cabecera del método. Ejemplo: int suma(int x, int y) es una cabecera que indica que el método, denominado suma, va a devolver un valor de tipo int y va a necesitar como argumentos dos valores enteros denominados x e y */

28

© Alfaomega - RC Libros

JAVA. LA NOVELA

receptor del mensaje devuelve un resultado al objeto emisor del mismo. —¿Siempre? —puntualiza, quisquilloso. —No, ya he dicho que un método puede no devolver nada y en ese caso la respuesta es void 10. —Bien, y, cambiando de tema: ¿dónde se almacena el método? —En la clase del objeto que tiene dicha responsabilidad. Por eso hemos venido hasta mi clase, para admirar el código de mis métodos. —Eso es, y ya casi llegamos —anuncia, algo más vivaz ante mis favorables progresos. En cuanto a mí, el resto del trayecto lo hago en silencio, mordiéndome las “uñas” y con la “respiración” contenida, ansioso por encontrarme con mis métodos; con mi manera de hacer las cosas, de cumplir mis responsabilidades. A cada paso me impaciento más, y para apaciguar mi excitación me concentro en repetir mentalmente los números de las líneas de código: 809, 810, 811... hasta que finalmente el señor Paradigma exclama:

10

void nombreMetodo(parametro1,...,parametroM) /* Cabecera del método. Ejemplo: void saludaPorPantalla(String saludo) es un método que imprime en pantalla la cadena de texto almacenada en el objeto saludo, pero no devuelve ningún valor */ objetoReceptor.nombreMetodo(argumento1,...,argumentoM); /* Envío de mensaje que no devuelve nada. Ejemplo: unaVar.saludaPorPantalla(“hola”); */

29

NURIA MEDINA

© Alfaomega - RC Libros

—¡Aquí están! ¿Qué te parecen? Trago saliva, me cuesta que salgan a flote las palabras teniendo la “garganta” tan seca como la tengo a causa de la impresión. —Hermosos. —Es todo cuanto puedo articular, manteniéndome de puntillas, en equilibrio, sobre el borde de la primera línea de código a partir de la cual se desparraman mis métodos. Y no es para menos: el horizonte de la tierra prometida es más lejano de lo que esperaba. Hay muchas cosas que puedo hacer. Me siento un héroe, un gigante, un conquistador...

30

8. Curiosidades —¡Juan, respira, que te estás poniendo morado! —me chilla el señor Paradigma perdiendo la compostura. —Tranquilo —enuncio apenas tomo un soplo de aire—, es que me he quedado “sin aliento” frente a la maravilla presente. —¿A qué maravilla te refieres? —A los caracteres, símbolos y espacios que se combinan tan exquisitamente para codificar mis métodos. —Entonces, ¿te gustan? —pregunta complacido. —Sí, me encanta Java. Gracias por traerme. —Oh, no, no... —reniega haciendo aspavientos con la “mano” al estilo de un conde francés—. El mérito no es mío. Dale las gracias a James Gosling. —¿James Gosling? ¿Quién es? —El creador del lenguaje. —No diga más, le mandaré un telegrama cerebral con mis agradecimientos —replico burlón y alzo la mirada al cielo binario. El maestro me da una palmadita en la “chepa” y finalizo la gracia con una pregunta—: ¿hace mucho de eso? —¿De qué? —Desde la idea feliz de James. —Bueno, depende de lo que consideres mucho. 31

NURIA MEDINA

© Alfaomega - RC Libros

—Está bien, el tiempo y el espacio son relativos; pero, por curiosidad, ¿en qué año aparece Java? —La empresa Sun Mycrosystems lo publicó en 1995. —¿Sun Mycrosystems? —Sí, la empresa para la que trabajaba el señor Gosling. —¿Trabajar? —Realizar tareas a cambio de un salario. —Vaya, vaya... por eso no me quería usted contar nada del mundo exterior —rezongo con el “ceño” fruncido—. Allí fuera pagan por realizar tareas y aquí la ejecución de responsabilidades es gratis. Y bastantes que tengo —añado mientras contemplo vanidosamente mis métodos. —No hay quien te entienda: hace un rato protestabas porque no te solicitaban tareas y ahora te quejas de tener responsabilidades. —Era una broma señor Paradigma —indico mientras meneo la “cabeza”—, pero si lo pienso despacio no estaría mal crear un sindicato de objetos trabajadores, lo llamaría... —Déjate de tonterías —me corta de raíz—, desde los años sesenta nadie había tenido el descaro de hablarme de retribuciones monetarias y sindicatos. —¿Los años sesenta?, ¡es usted un carcamal! Mirada fulminante. —Discúlpeme, quería decir que no me cuadra la década, ha dicho que Java se publicó en 1995, y además usted parece tan joven y enérgico...

32

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Déjate de pamplinas —segundo corte—. Java aparece en la década de los noventa, pero el paradigma orientado a objetos nace con Simula a finales de los sesenta. —¿Que no disimule?, ¿por qué me dice eso ahora señor Paradigma? Yo no estoy disimulando... —Simula 67, otro lenguaje de programación. —Ah... —susurro y me quedo con la “boca” abierta, sin llegar a salivar porque no tengo glándulas salivales; lo cual no es de extrañar, porque, por no tener, no tengo ni boca. En fin, el caso es que el señor Paradigma acentúa su mirada fulminante y yo rectifico la “cara” de bobo que se me había quedado, pero no encuentro qué hacer o decir para reparar mis meteduras de pata en cadena. Comienzo a silbar y con las “manos” a la “espalda” avanzo cabizbajo a través de mis métodos. Las líneas de código se suceden con una simetría casi perfecta. Llaves que cierran y abren bloques, y los punto y coma que finalizan sentencias. Paso de puntillas para no molestar, pero de vez en cuando acaricio un void en la cabecera de un método y abrazo a un return en el cuerpo de otro. El maestro me contó que los métodos que devuelven un valor lo hacen siempre con una sentencia de retorno 11. «No 11

return valor_respuesta /* Ejemplo: int suma(int x, int y){ int r; r = x+y; return r;//Devuelve la suma de los dos argumentos } int res = unaVar.suma(3,4); Devolvería como respuesta el valor 7 que se almacena en la variable res */

33

NURIA MEDINA

© Alfaomega - RC Libros

mentía», constato, mientras sigo el camino que cada vez me separa más de él y de su mirada fulminante. Tranquilidad total hasta que… me detengo en seco. Agudizo la vista. Y vocifero: —¡Señor Paradigma!, ¡venga aquí, rápido! —¿Qué quieres? —inquiere cuando llega a mi altura fatigado por la carrera. Ni rastro de su desafortunado semblante. La próxima vez que se enoje, ya sé qué hacer: ponerlo a correr. —Este método, mírelo, es distinto a los demás, pone static12 al principio de la cabecera. Ninguno de los otros métodos contenía la palabra static. —Eso es porque ese método no es tuyo, es de tu clase. —¿Qué quiere decir? —Que ese método no se resuelve a nivel de objeto, sino de clase. —Podría ser más explícito... —Lo intentaré —inhala—. Ese método requiere para ejecutarse que se le envíe un mensaje 13 a tu clase EstudianteGradoInformatica, no a ti ni a ninguno de los otros objetos de tu clase.

12

static respuesta nombreMetodoClase(parametro1, parametro2,..., parametroN) 13

EstudianteGradoInformatica.nombreMetodoClase(argumento1,. .., argumentoN) /* Ejemplo: EstudianteGradoInformatica.incrementaNumeroEstudiantesG I(); */

34

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Ya entiendo, esa responsabilidad es de mi clase, no mía. ¡Qué maja! Me entra la risa floja. No sé por qué, pero me entra. Y, de pronto, me pongo a bailotear como un loco. —¿Qué te hace tan feliz? Me paro para analizar la pregunta del señor Paradigma, o más bien, para analizar mi respuesta. En realidad, no sé qué ha sido exactamente, pero estoy seguro de que ha habido algo... —Por favor, podría repetir lo que ha dicho antes, con las mismas palabras que ha empleado, please. —¿Por qué? —No puedo precisarle pero, hágame el favor, es vital que pronuncie las mismas palabras. —Está bien —accede—. Dije que “un método static requiere para ejecutarse que se le envíe un mensaje a tu clase, no a ti ni a ninguno de los otros objetos de tu clase”. —¡Eso es! —me arranco ahora con unos pasillos de salsa—. Ha dicho que hay otras instancias de mi misma clase—. Agarro al señor Paradigma y le doy un par de vueltas y un beso en la “frente”. Él se suelta y me aparta con un gesto desagradable. No me achico por el desplante, la verdad es que no lleva el ritmo en la sangre. —Me voy hasta que se te pase la euforia —notifica muy dignamente.

35

NURIA MEDINA

© Alfaomega - RC Libros

Continuo sin echarle cuentas. En su lugar, comienzo a canturrear: «Otros como yo», «otros como yo», «otros como yo»... mientras mis “pies” danzan y se atreven ahora con una bachata.

36

9. Madre, matrona y alumbramiento Me tropiezo con el “cordón astral” y dejo de bailar el chachachá. Estoy sudando y la “cabeza” me da vueltas, metafóricamente hablando, como siempre. Debo sentarme. Busco el hueco de un tabulador y me acomodo. Cierro los “ojos” unos instantes y el movimiento creado por mi mente desacelera gradualmente hasta detenerse y desaparecer. Separo entonces los “párpados” y la quietud que reina alrededor me permite divisar al maestro. Oh, no, está ascendiendo. Realmente se marcha del código fuente. No puede ser, tengo muchas más preguntas que hacerle. —¡Alto ahí! —Me desgañito—. Tiene que contarme bien eso de que hay otros objetos de mi misma clase. El maestro emprende un mohín de resignación y deshace su marcha para plantarse frente a mí con los “brazos” en jarra. —Pregunta —ofrece generoso. —¿Cuántos hermanos tengo? —¿Hermanos?, ¿a qué viene eso? —Menuda “cara” de espanto. —Si la clase es mi mamá y hay otros hijos suyos, tengo hermanos —razono. 37

NURIA MEDINA

© Alfaomega - RC Libros

—¿Mamá?, ¿hermanos? —Sus “ojos” parecen dos imanes de nevera—. ¿Te has vuelto chiflado? La clase en Java es un patrón textual que define la estructura y el comportamiento de un conjunto de objetos. —Pues eso, mi madre. —Mira que eres cabezota. No es tu madre. Es una plantilla, un molde que declara tus atributos y establece los métodos para resolver tus responsabilidades, nada más. La clase no te ha creado. La clase es código Java y punto. —Pero... yo había entendido que me he creado a partir de ella. —Eso sí. Pero ella no te ha creado. —Entonces, ¿quién? —¿Quién, qué? —suena a trabalenguas. —¿Quién me ha creado? —Digamos que el intérprete de Java —concluye y se ríe para eliminar tensión. —¿Qué? —replico sorprendido ante la introducción inesperada de un nuevo concepto. —El intérprete es una implementación de la Máquina Virtual de Java. Antes de que me lo preguntes, te diré que la Máquina Virtual de Java es el entorno donde se ejecuta el programa Java. El mundo del que venimos, ¿recuerdas? —Me estoy perdiendo. ¿Qué tiene que ver eso con mi nacimiento? 38

© Alfaomega - RC Libros

JAVA. LA NOVELA

—El intérprete es quien ha ejecutado el método de tu construcción y por lo tanto quien te ha creado. —Y, ¿dónde está ese método? —consulto, en un intento de entender algo. —Ahí mismo —afirma, mientras señala el primer método de mi clase y añade con gravedad—: Juan, te presento a tu método constructor 14. Lo miro y remiro, pero no siento mariposas en el “estómago”, ni cosquillas en el “corazón”, ni quemazón en la “garganta”. Vaya... creí que sería emotivo contemplar el “vídeo” de mi alumbramiento. Me froto los “ojos” para ver si al menos consigo fingir un par de lágrimas, pero nada, no me salen. En aquel momento me convenzo de que debo ser práctico y, dejando a un lado la sensiblería que no germina, me concentro en el código del método. Ahí me percato de que el constructor es ligeramente diferente a los demás métodos de mi clase, y lo que más me llama la atención es que se llama exactamente como mi clase: EstudianteGradoInformatica. Luego, reparo en que no devuelve nada, ni un valor, ni siquiera void. Qué raro... —Señor Paradigma, ¿cómo es posible que no devuelva nada?

14 EstudianteGradoInformatica(String unNombre, int

unNumeroHermanos,...) {nombre = unNombre; numeroHermanos = unNumeroHermanos;...}, donde nombre y numeroHermanos son atributos declarados en la clase EstudianteGradoInformatica */

39

NURIA MEDINA

© Alfaomega - RC Libros

—Aunque no ponga ningún valor de retorno, el constructor claro que devuelve algo. ¿No imaginas qué? El maestro me mira de hito en hito, como si fuera un completo idiota. Por su expresión, la respuesta debe ser obvia, seguro que la tengo delante, pero no caigo. Me rasco la “coronilla”. —No caes, ¿no? —se burla el señor Paradigma, que como de costumbre me estaba leyendo el pensamiento—. Te daré una pista: la respuesta no la tienes delante, la respuesta está en ti. Caigo: —Ah… claro, el constructor devuelve el objeto construido. Es decir un nuevo objeto de la clase. —Excelente —me elogia—. Te ha costado trabajo, pero has atinado con la tecla. La salida de ese método, una vez, fuiste tú —sonríe mientras dos lágrimas navegan saladas y húmedas por mi “rostro” surcado de emociones liberadas. —Cuéntemelo todo —le ruego. Y, él, maestro al fin, se extiende en mil detalles que en algunas ocasiones podrían calificarse de “rollo patatero”. Pero yo, estudiante al fin, me quedo con lo esencial y presto verdadera atención cuando me cuenta que el constructor es especial también en su invocación 15, que no se le envía un mensaje ni a un objeto (como es lo habitual) ni a la clase 15

unaVar = new EstudianteGradoInformatica(argumento1,..., argumentoN); /* Ejemplo: EstudianteGradoInformatica var; var = new EstudianteGradoInformatica(“Juan”,...,“C/Elvira, 7”); */

40

© Alfaomega - RC Libros

JAVA. LA NOVELA

(como ocurre con los métodos static), sino que se usa un operador especial llamado new. Luego se empeña en indicarme el orden exacto en el que ocurre el parto. Uno-dos-tres. Se reserva espacio en memoria para guardar la instancia que va a nacer. Se inicializan los atributos de dicho objeto usando los argumentos del método constructor. Y, tres, se le asocia un nombre al espacio de memoria donde se ubica el nuevo objeto para poder referenciarlo después. Asiento como si estuviese perfectamente claro, pero la realidad es que me cuesta digerir tanta información y, para detener el dolor de “moroco” que ya me está mostrando la patita por debajo de la puerta, decido dejar la mente en blanco. Inmediatamente, se llena de luz. De hecho, comprendo por primera vez qué es luz: ausencia de oscuridad, verdad, brillo, energía, vida... —Señor Paradigma, ya sé por qué tengo dieciocho años y sin embargo no tengo la sensación de haber vivido tanto —anuncio agitado. —¿Sí?, dime —me insta a continuar, estampando un sello de calma con su ritmo pausado. —Cuando se invocó el constructor para crearme, el argumento que se usó para inicializar el atributo fecha de nacimiento establecía un día de hace dieciocho años: el día del cumpleaños de Juan persona. —Hago una pausa para recuperar el aliento—. Pero, eso no quiere decir que el constructor se ejecutase hace dieciocho años. Seguramente se haya ejecutado hace relativamente poco.

41

NURIA MEDINA

© Alfaomega - RC Libros

—Muy bien Juan, lo has comprendido. El estudiante que representas lleva viviendo ahí fuera dieciocho años, pero ni por asomo, el objeto Juan que lo representa aquí dentro, o sea tú, lleva vivo todo ese tiempo. —Se toca el “cordón astral” y con mirada de recelo propone de forma inesperada—: ¿nos marchamos ya? —No, espere, hay más. También creo que he descifrado el misterio de esa flecha que me apunta y que pone “var”. —¿Sí? —“var” es el nombre que se le ha dado a la región de memoria donde habito. Mi nombre de objeto —afirmo y me siento como un joven indio al que los espíritus le han revelado su nombre tribal. —Muy bien, “var”, ¿nos marchamos ya? —Puede seguir llamándome Juan. Y, por favor, aguante esa prisa que le ha entrado de repente. Déjeme hacerle algunas consultas más. —Adelante —consiente de mala gana. —¿Puede haber varios métodos constructores en una misma clase? —Sí, siempre que tengan distintos argumentos, claro está. —Y... ¿pueden construirse dos objetos con el mismo constructor y con el mismo valor en todos sus argumentos? —Sí, claro. —¿Seguro, señor Paradigma? 42

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Sí —reitera malhumorado. —Venga ya... ¿me está “barajando” para que le deje tranquilo? —No. —Entonces, ¿puede haber dos objetos idénticos? —No. —Me está volviendo majara. —No es mi intención. Solo te digo que no puede haber dos objetos idénticos, pero sí puede haber dos objetos iguales. —¡Explíquese! —le exijo. —Puede haber dos objetos de la misma clase con el mismo estado o lo que es lo mismo, con el mismo valor en todos sus atributos (iguales). —¿Como si tuviese un hermano gemelo? —Algo así. Aunque esto no ocurre con los objetos que representan personas, porque estos objetos suelen tener atributos únicos como, por ejemplo, el DNI. —Vale, vale, no entre en matices —le recrimino, como él a mí en ocasiones anteriores—. Me está confirmando lo que yo ya intuía, el estado no es sinónimo de identidad. Mi esencia no es mi estado. Comprendido. Pero… ¿cuál es, entonces, la identidad de un objeto? —Ponte en el caso de dos objetos de la clase Tiza que tienen el mismo estado (igual color, igual peso, igual tamaño). ¿Cómo sabes que son dos tizas y no una? 43

NURIA MEDINA

© Alfaomega - RC Libros

—Hombre, muy fácil, ocupan una posición distinta en el mundo: una está en un sitio y la otra en otro. —Me he tirado un farol, ni siquiera sé lo que es una tiza. — Voilà, la identidad de un objeto es su posición en memoria. No puede haber dos objetos en la misma posición de memoria. —La mera existencia nos da identidad. Grandioso —musito y me recreo en la reciente iluminación. No es necesario perderse buscando nuestro Ser. Simplemente por existir y ocupar un espacio en el mundo somos diferentes, somos especiales, somos nosotros mismos. —Baja de la nube, que te estás poniendo demasiado trascendental. —Maldita costumbre esa de leerme el pensamiento—... Lo siento, no puedo evitarlo —se disculpa—. ¿Quieres que veamos algo más en el código fuente de tu clase o nos vamos de una vez?

44

© Alfaomega - RC Libros

JAVA. LA NOVELA

Ilustración 5. La clase es una especie de molde o sello que define la estructura (atributos) y métodos que tendrán los objetos de dicha clase. A través del constructor se crean las nuevas instancias de la clase. Estas instancias pueden tener el mismo estado (2 y 3 en la imagen, p.e.) o distinto valor en sus atributos (4 y 5, p.e.); pero cada una tiene su propia identidad.

El señor Paradigma está visiblemente cansado y yo tengo ganas de orinar. 45

NURIA MEDINA

© Alfaomega - RC Libros

—Vayámonos —consiento—, pero… ¿me promete que me dejará regresar? —Prometido —accede visiblemente relajado ante la perspectiva de salir del disco duro. —Está bien, pero permítame ir contándole por el camino mi teoría sobre mi madre, mi matrona y mi alumbramiento. —Como quieras... Le echo el “brazo” por el “hombro” e insólitamente no se rebela, así pues, en esa fraternal tesitura avanzamos hacia el punto del que debe partir nuestro viaje de retorno. Durante la travesía, los roles se invierten: él escucha y yo me explico. Maestro al fin, se empeña en discutirme todos los detalles y es incapaz de asimilar lo esencial de mi discurso. No obstante, mi discurso, modestia aparte, ha sido soberbio. Sería una verdadera lástima desaprovecharlo. Por eso he decidido contártelo a ti que, por otro lado, seguramente serás mucho menos testarudo que el señor Paradigma. Ahí va: «La clase es mi madre porque define desde antes de mi nacimiento cómo voy a ser: qué cosas puedo hacer y cómo (métodos) y qué atributos me van a describir a lo largo de mi vida (variables para configurar mi estado). Además, la clase define el constructor, que codifica el alumbramiento del nuevo objeto. Y, ¿el intérprete?, ¿dónde queda el intérprete de la Máquina Virtual? Para mí es más que evidente, el intérprete es la matrona que asiste a mamá durante el parto, indoloro, a Dios gracias». ¿A que llevo razón? Ni se te ocurra discutirme... menos, ahora, justo antes del despeeeeeeeeeeeeeeeeeeeeeeegue. 46

10. Basura No atino a aventurar cuánto tiempo ha pasado desde que regresé del viaje, pero ha debido de ser bastante. Aterricé sin energía, flácido, como un muñeco de trapo. Y he dormido durante días, meses diría yo, años… me cuesta moverme. Tumbado, arrastro los “brazos” a la altura de mis “posaderas” para poder apoyar las “palmas”. Con la fuerza que ejercitan mis “brazos” levanto la “espalda” y más tarde alcanzo la postura de cuclillas. Desde ahí, mis “rodillas” se estiran como un muelle oxidado hasta coronar la vertical que me permite consultar el reloj. Imposible, ¡no ha transcurrido ni un milisegundo! —Durante los viajes astrales el tiempo se congela —explica el señor Paradigma que reaparece fresco como una rosa nofrost—. Debe ser así porque, en otro caso, algún otro objeto podría haberte enviado un mensaje y tú no habrías estado preparado para responder a su petición. —Sí, por supuesto, el principio de colaboración entre objetos —arguyo, a la par que me desprendo de una “legaña”—. ¡Siempre dispuestos a cumplir con nuestras responsabilidades! —exclamo, mientras alzo el “brazo”, aprieto el “puño” y me estiro con energías renovadas y desmedida grandilocuencia. —Intuyo que estás encantado de ser un objeto.

47

NURIA MEDINA

© Alfaomega - RC Libros

—¿Qué otra cosa podría haber mejor en este mundo? —pregunto retóricamente y me paro a pensar—: espera... sí que hay una cosa mejor. —¿Cómo? —El mejor trabajo del mundo. Acabo de averiguar cuál es. —Dime, me tienes en ascuas. A ver por dónde salta la rana. —Júreme que no se reirá. —Veo difícil reírme, no estoy de humor. —Prométalo —insisto. —De acuerdo, lo prometo. Sácame de dudas. ¿Cuál es el mejor trabajo del mundo? —interroga arrastrando los fonemas. —El único trabajo que se convierte en placer es... —me demoro a propósito, para avivar las ascuas. —¡Termina de decirlo! —exige. Parece que por alguna razón, algunos de mis pensamientos se le escapan y me da por pensar que podrían ser los más absurdos. —Tendrá que adivinarlo —le chuleo—. Empieza por la letrita “I”. —Idiota —suelta malhumorado y no sé por qué me extraño, si ya me avisó de sus malas pulgas. —No se ponga así, señor Paradigma, qué pocas ganas de juego tiene. Se lo diré sin adivinanzas porque menudo genio ha sacado. 48

© Alfaomega - RC Libros

JAVA. LA NOVELA

Escucha mientras se enrojece, progresivamente, sin decir ni media palabra. —Intérprete —digo. —¿Intérprete? —repite con entonación reflexiva. —Sí, quiero ser intérprete de Java. ¿Qué tengo que hacer? Ayúdeme a elaborar un currículum vítae de esos —le pido mientras doy saltitos a su alrededor como si estuviese bailando el “patio de mi casa”. —Tranquilízate chico. Pareces un crío y tú eres un objeto, y para tu conocimiento, te morirás siendo un objeto. No puedes ser intérprete ni compilador ni humano. —¡¿Morirme?! ¿Voy a morir?, ¿cuándo? —demando alarmado, ante la funambulesca revelación mortuoria. —Morirás cuando ya nadie te necesite. —Gracias por ser tan preciso —resuelvo irónico. —De nada —responde con sorna. Ahora sí le apetece jugar... —Vale, no me diga cuándo; así podré vivir sin esa presión. —Resoplo—. Pero, dígame al menos: ¿quién es la señora muerte? —Mira que suenas pedante cuando te lo propones. No hay señora muerte, se trata simplemente de la Máquina Virtual de Java y su recolector de basura automático. —Me mira por encima del “hombro” mientras añade—: el recolector de basura pasa cada cierto tiempo y libera el espacio de memoria ocupado por objetos a los que ya ninguna flecha 49

NURIA MEDINA

© Alfaomega - RC Libros

apunta. Objetos extraviados, inaccesibles..., objetos a los que nadie podría pedirles nada. —¿Recolector de basura? —balbuceo aterrado sin prestar atención a sus últimas palabras; y es que no puedo dejar de preguntarme—: ¿quién ha podido ser tan cruel para ponerle ese nombre? ¡¿Recolector de basura?! —Es cierto, el término suena un poco cruel. —Muy cruel. —Sí, muy cruel, sin duda —coincide, pero es obvio que no me comprende, en definitivas cuentas él no es un objeto; es un paradigma, y el paradigma orientado a objetos vivirá por mucho tiempo, de eso no me cabe duda. —¡Un objeto nunca es basura! —bramo—, aunque ya nadie lo requiera no es basura —concluyo consternado y con un tono de voz mucho más apocado. —Estoy de acuerdo, pero… vamos chico, no pienses en eso —me consuela. Me aparto. Quiero estar solo. Escondo mi “cabeza” tras el telón que configuran mis “manos” y permanezco en ese impasse el tiempo suficiente para llegar a la determinación a la que supongo que llega todo ser vivo que desea mantenerse cuerdo: no pensar en la muerte (ni en su cepillo). Cuando llegue, llegará; mientras tanto la ignoraré. Así lo decido y acomodo el recolector de basura en el último cajón del armario, dentro de la última habitación, del último piso, del último edificio, del último pueblo, de la última ciudad, del último país, del planeta más lejano del universo de mi Ser. 50

© Alfaomega - RC Libros

JAVA. LA NOVELA

Mientras tanto, el señor Paradigma no sabe dónde meterse y ejecuta todo tipo de monerías. Se lleva las “manos” a la “cabeza”, se frota la “barbilla”, se rasca la “nariz”, se alisa los cuatro “pelos” de la “calva” y se manosea los “dedos” de los “pies”, lo cual es un verdadero asco, pero no le digo nada porque es un señor Paradigma de Programación, y es de sobra conocido que los paradigmas de programación no tienen manos ni pies que tocarse. En fin… tras la procesión de alharacas, arranca de nuevo: —Bueno, dime por qué querías ser intérprete de la Máquina Virtual de Java. No he alcanzado a entender el empeño. —¿Por qué va a ser? Porque me encanta la sintaxis de Java. —Ya, pero el intérprete no trabaja con el código fuente. —¿Eh…? —El intérprete no interpreta el código Java sino un código intermedio que se llama bytecode java. —Me he quedado a cuadros… —reconozco—. ¿Por qué no iba a usar Java? Con lo lindo que es… —Porque usar un código independiente del hardware.

neutro

permite

ser

—Y, ¿eso significa? —Eso significa que un programa Java se puede ejecutar en cualquier plataforma. —¿Portabilidad? —Eso es, chico, muy bien —me aplaude. 51

NURIA MEDINA

© Alfaomega - RC Libros

—Gracias —respondo halagado—. Solo una cosa más: ¿quién genera el código intermedio a partir del código Java? —El compilador es el encargado de generar el bytecode, no sin antes, claro está, comprobar que el código fuente no contenga errores. —El compilador. Um. Creo que he escuchado antes esa palabra… —Es posible —disimula el señor Paradigma, rogando para que no tenga lugar en mi “cerebro” la asociación de ideas que me llevaría inevitablemente a volver a pensar en el tan cruelmente denominado recolector de basura—. ¿En qué piensas? —pregunta cuando llevo un rato callado. —En nada. —Dime —requiere. —Deme su palabra de que no me regañará. —Claro que no. ¿Por qué iba a hacerlo? Dime, ¿qué tienes en mente? —Es tan solo por asegurarme —aclaro y lanzo la cuestión—: ¿no podría estudiar para ser compilador? —¡No! —grita antes de que acabe, y me deja en la duda de si escuchó mi pensamiento o mi contestación. —No se ponga así, tenía que intentarlo —remato y, para devolvérsela, comienzo a manosearme los “dedos” de los “pies” con ímpetu. Y ¡qué se atreva a decirme algo!: si los objetos no tenemos pies, ¿cómo íbamos a tener pelotillas de basura entre los “dedos”?

52

11. Ver mundo El ombligo que no tengo es redondo o, mejor dicho, intenta serlo, porque si trazara una circunferencia usando el centro de mi “ombligo” como eje del compás, por más que me empeñase en que el radio de la figura se ajustase al radio de mi hueco, la superposición no quedaría jamás perfecta. Digamos, entonces, que mi “ombligo” es como la Tierra, redondo y achatado en los polos; así suena mucho mejor. Quizá te preguntes qué hago hablándote de ese trozo de carne que no tengo ni literal ni metafóricamente. Pues es fácil, el vacío de mi “ombligo” hace presente el vínculo que un día me unió a mi madre, y, sin engañarte ni exagerar, no he dejado de pensar en EstudianteGradoInformatica desde que la conocí; al igual que no he dejado de contemplarme el “ombligo”. Por eso, te puedo decir qué dimensiones tiene, los pliegues que se forman en el fondo, el color del borde y, gracias a la flexibilidad que concede la no materia, te puedo concretar inclusive su sabor. ¿Dulce o salado? No te lo cuento. ¡Ya está bien! Voy a dejar de lamerme el “ombligo”, de todo se cansa uno. Además, el señor Paradigma tenía razón, un objeto solitario no sirve de nada. Voy a explorar mundo, a mirar arriba, abajo y alrededor; a concebirme como una pieza del puzle infinito. Adiós “ombligo”. Fue dulce mientras duró. —¿Señor Paradigma? 53

NURIA MEDINA

© Alfaomega - RC Libros

—¿Señor Paradigma? —¡Señor Paradigma!, ¿dónde está? —Buenas chico. ¡Cuánto tiempo! —aparece sonriente. —Sí, he estado ocupado —apunto, mientras aparto la vista de mi “ombligo” (es difícil eliminar el hábito). —¿Te ha llegado algún mensaje? Madre mía, ¡qué gordo se ha puesto! Mientras yo me velaba el “ombligo”, él se llenaba la “panza”. Sonrío y respondo despreocupado: —No, no, ninguna petición. —¿Entonces? —pregunta con sorna. —He tenido otros menesteres entre manos. —Ya, ya —susurra, revelando que me ha estado espiando—. Dime, ¿qué quieres?, ¿por qué me llamabas con tanta insistencia? —Quiero comprender este mundo. —Un propósito demasiado ambicioso, ¿no crees? —Bueno, quizá no vaya a saberlo todo; pero cuénteme algunas cosas sobre él. —Está bien. ¿Por dónde empiezo? —¿Por qué tuvimos que hacer un viaje astral para llegar hasta mi clase? —llevo tiempo dándole vueltas. —Buena pregunta… A ver cómo te lo explico. 54

© Alfaomega - RC Libros

JAVA. LA NOVELA

El señor Paradigma saca una pizarra del bolsillo y esboza un círculo, casi tan amorfo como “el innombrable de mi ombligo”, el cual primorosamente titula: “disco duro”. Luego, dibuja una tabla, con una columna y muchas filas. Arriba escribe “memoria RAM”. —Ves —dice señalando el círculo—: este es el disco duro, donde se almacena el código fuente del programa java y, una vez compilado, también los ficheros .class. —¿.class? —No te lo comenté antes, pero cuando se compila una clase, el compilador genera un nuevo fichero con el mismo nombre, pero con la extensión .class en lugar de .java. —EstudianteGradoInformatica.class en mi caso, ¿es así? —Así es. —¿Qué contiene el fichero .class? —El código neutro; el bytecode correspondiente a la clase. —Entiendo... —Luego, cuando el programa se va a ejecutar, el bytecode debe almacenarse en la memoria RAM —explica repintando el borde de la tabla en la pizarra—. La RAM está dividida en celdas que se numeran consecutivamente —continúa y escribe un 0 al lado de la primera celda de la tabla, un 1 debajo (junto a la segunda celda); y así sucesivamente hasta que se cansa. —Entonces... si no yerro, mi mundo es la memoria RAM. —Correcto, estamos en la memoria RAM. 55

NURIA MEDINA

© Alfaomega - RC Libros

—Pero... aquí hay dos regiones. Esta y la otra, la de los punteros —afirmo resuelto, tomando conciencia de la punta clavada en mi “nuca”. —Sí, esta región es la memoria dinámica (heap) y la otra es la memoria estática (stack). —¿Por qué dos regiones?, ¿por qué las flechas?, ¿por qué...? —Demasiadas preguntas, quédate con una —apremia. Recapitulo y cambio el enfoque: —¿Estoy en el lado bueno del mundo? —Aquí no hay regiones buenas o malas, ricas ni pobres... Cada región es diferente y punto. —Ya, pero... ¿es mejor vivir en el heap?, reconozca que sí... —Digamos que es más flexible. —¡Toma ya! ¡Lo sabía! La región de las flechas es más oscura. —¿Oscura? Eso te lo parece a ti; lo que sí es, es más organizada. —¿Organizada? —Me refiero a que el stack sigue una estructura LIFO 16, mientras que el heap no posee ninguna estructura de asignación de espacios. Esto es debido a que se asigna al

16

last in, first out

56

© Alfaomega - RC Libros

JAVA. LA NOVELA

vuelo y, como consecuencia, no hay garantías de que los datos se almacenen contiguos. —¿Datos? —Objetos, en nuestro caso —aclara el maestro. —Me queda claro, jefe, a este lado los objetos y al otro lado las flechas. —Bueno, en el otro lado no solo hay punteros. —Eso me parecía. ¿Qué más hay? —También hay valores primitivos 17, como por ejemplo: números enteros, caracteres, valores de verdad, etc. —Ya, pero sobre todo hay punteros. —En este programa, sí. —Una curiosidad: ¿hay tantos punteros como objetos? —No. —¿No? —No, hay objetos que tienen varios punteros al mismo tiempo. —Vaya, qué coacción —discurro en alto—. Y, ¿puede haber un objeto sin punteros? —Sí. 17

int, char, boolean, float, long, short, byte, double /* valores de estos tipos primitivos son: 45, ‘a’, true, 1234.5, etc. */

57

NURIA MEDINA

© Alfaomega - RC Libros

—Libertad —asevero, mientras me rasco la “espalda”. El puntero pica. —Bueno..., cuando un objeto no es apuntado por ninguna flecha es porque no se va a necesitar más en el programa y, en ese caso, ya sabes... —el señor Paradigma no borda la frase pero realiza el gesto de rebanarse el “pescuezo” con la “mano”. No sé qué es peor… —Ni lo miente —le solicito con brusquedad, pero irremediablemente su nombre se visualiza en la pantalla de mi mente como los créditos de una película: “The killer, interpretada por el recolector de basura”. Meneo la “cabeza” para deshacer la imagen y continúo—: además, ahora que lo dice, ya lo sabía. Lo que no sabía es que un objeto puede ser señalado por varios punteros. ¿No veo para qué? —Cuando un objeto tiene varios punteros significa que hay varias variables del programa que referencian dicho objeto. —¿Variables? —Sí, variables; se llaman así porque pueden cambiar su valor a lo largo del tiempo y todas se almacenan en el stack. El valor de una variable18 puede ser un dato primitivo, pongamos 3, o puede ser un puntero a un objeto, digamos tú. Las variables deben ser previamente declaradas 19 según el tipo de objetos o de valores primitivos que van a almacenar.

18

var1 = 3; var2 = new EstudianteGradoInformatica(...); 19 int var1; EstudianteGradoInformatica var2;

58

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Mola, dentro de una variable se puede meter un objeto o un valor primitivo. Si se mete un objeto, en realidad lo que se mete es un puntero al objeto 20. —Ya lo tengo, jefe, se puede marchar a seguir comiendo. —¡Pero muchacho, ¿qué falta de respeto es esa?! —Si no he dicho nada, maestro. —No lo has dicho en alto, ¿querrás decir? —Disculpe —murmuro, muerto de vergüenza; tengo que aprender a controlar mis pensamientos—, quería decir que ya lo he comprendido gracias a su magistral explicación, cinturita de avispa. —Añado el piropo a sabiendas de que es excesivo, pero es lo mejor que se me ha ocurrido mientras reprimía la palabra “tamboril”.

20

En los métodos Java los parámetros siempre se pasan por valor (copia), Así, cuando se trata de un objeto se copia el puntero y dentro del método se trabaja con el propio objeto argumento (no con uno igual, como ocurre con los valores primitivos donde se copia el valor). Lo mismo ocurre con la asignación de variables

59

NURIA MEDINA

© Alfaomega - RC Libros

Ilustración 6. El valor de una variable que apunta a un objeto es la dirección de memoria donde está almacenado dicho objeto en el heap. Si una variable (declarada de una clase) no apunta a ningún objeto tendrá valor null. Si un objeto no es apuntado por ninguna variable será removido por el recolector de basura.

El señor Paradigma se aprieta el cinturón y, lejos de mostrarse halagado por mi descabellada alabanza, deshace a golpe de borrador todo lo previamente escrito en la pizarra. El polvo blanco nos cubre y estornudo tres veces seguidas (ahora ya sé lo que es una tiza). Cuando me calmo, creyendo que el señor Paradigma se ha marchado, lo encuentro cruzado de “brazos" delante de la pizarra. Me mira. Lo miro. Nos retamos con la mirada, y el duelo dura unos segundos interminables, hasta que, andando de lado sin perder 60

© Alfaomega - RC Libros

JAVA. LA NOVELA

contacto visual se aparta para dejar al descubierto la pregunta que ha debido formular en el encerado mientras yo estornudaba. —¿Qué es 0x0000812C? —Ni idea —respondo con franqueza. Me sacudo el polvo de tiza y de paso, se me caen los engreimientos—. No lo sé, maestro, por favor, explíquemelo. Le necesito. —Está bien. Haré algo mejor que eso —anuncia para mi asombro—. No preguntes nada. Cierra los “ojos” y déjate llevar. Nos vamos de viaje.

61

12. Helicóptero de viento El señor Paradigma no me deja abrir los “ojos”. Me ha dicho que voy a conocer la respuesta a su pregunta de primerísima mano y, que para ello, no tenemos más remedio que tomar un vuelo. A partir de ahí no me ha dejado abrir los “ojos”, casi ni la “boca”. Yo nunca he volado en helicóptero, por eso me ha resultado raro cuando me ha dicho que me agarrase del alerón. Debo parecerte rematadamente pueril, pero pensé que se volaría sentado. Desde luego, el vuelo no me está resultando nada cómodo. Entre la posturita, la velocidad, el viento, el ruido del motor y la obligación de tener los “ojos” cerrados, no estoy disfrutando la experiencia. Maldito zumbido. Al menos, el señor Paradigma está a mi vera, agarrado del otro alerón, supongo, porque no puedo verlo. Cuento hasta veinte, me imagino un lago en calma, tarareo letrillas ligeras de verbenas populares, incluso, al compás, agito mis “extremidades inferiores” con garbo y mucho cuidado de no soltarme, pero no me relajo. Qué va. Me duelen los “párpados” de mantenerlos apretados. Creo que voy a acabar con rozaduras en las “pupilas”. No aguanto más. Tengo que hacer algo: —Señor Paradigma, tengo miedo —afirmo. —Qué tontería dices, muchacho. —No es ninguna tontería, usted no sabe la impresión que supone volar en helicóptero a ciegas. 62

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Lo has prometido —me recuerda severo. —Sí, claro, pero me sentiría mejor si usted hiciera lo mismo. Al menos, así, podría comprender lo valiente que estoy siendo. Ponerse en mi “piel”. Comprender al alumno... —Bueno, si eso te ayuda, cerraré los “ojos” también. —Gracias —digo, y espero unos instantes antes de abrir los míos, como platos primero..., como planetas después. —Uooooooooooooooooooooooooooo, ¡no estamos volando en helicóptero, estamos colgados de un ventilador! —Serás tramposo —responde sin sangre—. Me dan ganas de tirarte un pellizco en el “sobaco”. —Por favor, no lo haga —suplico con voz cortada y pálido como el papel. Ahora sí que tengo miedo. —Por eso no quería que miraras —predica—. En cualquier caso, no te preocupes, ya estamos llegando. —¿Ya?, ¿vamos a aterrizar? —¿Acaso has visto alguna vez un ventilador aterrizando?, ¿qué cosas tienes? —Se coloca la “mano” libre en jarra y respira profundamente para soltar como si nada—: cuando yo diga tres, ¡salta! —¡Está usted loco! —¡Los dos estamos locos!, ¿por qué si no íbamos a estar agarrados al ventilador de la CPU? Anda, hazme caso, cierra los “ojos” y salta. Justo cuando voy a replicar, me doy cuenta de que no podrá escucharme porque: ¡ya ha saltado! 63

NURIA MEDINA

© Alfaomega - RC Libros

—¡Jerónimooooooooooooooooooooooooooooooo! —grito mientras caigo en peso muerto tras él. Por fortuna, el descenso de nuestros “cuerpos” se ejecuta a cámara lenta; concesión que me permite abrir los “ojos”. Primero un poco, luego del todo. Entonces, oteo el horizonte, sin gravedad, ni palabras. El paisaje es espectacular. A mano derecha, el montículo21 se divisa como si fuese el suelo desnudo de un desierto. Debido a la distancia, no me es posible identificar ni mi casa ni los otros objetos que se hospedan en el heap; pero sí que puedo admirar el color uniforme y cálido que conforman los objetos cuando se reducen todos a una única mancha. A la izquierda, bajo mis pies, se encuentra la pila 22, columna infinita que se irgue altiva hasta coronar el cielo de bits. En mitad, un océano de flechas que enlazan las dos regiones. La telaraña que une los dos mundos, de donde vengo y adónde voy. Como una pluma que se mece en la vertical, continúa mi descenso, hasta que, sin apenas darme cuenta, ruedo sobre el señor Paradigma que me sirve de colchón y agradezco los “cúmulos de grasa” que se le forman donde otros tienen cintura. Me sacudo y me incorporo. Acabamos de aterrizar en una celda del stack que almacena el número 0x0000812C. —Querido “Juan”, te presento a “var”.

21 22

heap stack

64

© Alfaomega - RC Libros

JAVA. LA NOVELA

De pronto no capto lo que me quiere decir el maestro, pero luego un soplo de perspicacia se cuela en mi “laberinto cerebral” y avanza empujado por el aliento de la inhalación profunda que acabo de realizar: —ajá, en ese caso... 0x0000812C es mi puntero, ¿verdad? El contenido de la variable “var” 23 —concluyo pensativo. Él afirma con la “cabeza” mientras insiste en alisarse con las “manos” las arrugas que han impreso mis “posaderas” sobre la tela de su camisa. —Pero, estoy un poco confuso. ¿Por qué los punteros son tan raritos? —Esos caracteres que te parecen tan raros conforman tu dirección de memoria RAM, en hexadecimal. —Mi dirección de memoria. Mi identidad —resuello para acabar la frase con bizarría. —Vaya, creía que lo habrías olvidado. —Qué va —revelo, agitando la “mano” con desdén—, tengo muy buena memoria, para lo que quiero. El señor Paradigma asiente ausente, sigue inmerso en su planchado manual. Mientras, yo me siento al lado de mi puntero y, silente, reflexiono sobre la importancia de esa celda.

23

var = new EstudianteGradoInformatica(“Juan”,...); /* La variable var (almacenada en el stack) guarda la posición de memoria (en el heap) del objeto que se acaba de crear: 0x0000812C */

65

NURIA MEDINA

© Alfaomega - RC Libros

Me resisto a verbalizar lo que estoy pensando, e incluso lucho contra mí mismo... pero pierdo y pregunto: —¿Qué pasaría si a esta variable se le asignara otro valor? —Ya lo sabes, es tu único puntero. Si se le asignara otro valor, ya sea un dato primitivo o un objeto o el contenido de otra variable 24, te quedarías sin ningún puntero. Desde ningún sitio del programa serías accesible. —La muerte. —Chico, no te obsesiones con eso. La muerte no es tan mala. —¿Cómo? —pregunto porque no puedo creer que haya dicho lo que he oído. —Te decía que la muerte no es tan mala —confirma—. Cuando se libera el espacio en memoria de un objeto, su estado se desglosa en sus atributos y cada atributo se descompone en átomos de vacío; y esos átomos de vacío se dividen en partículas subatómicas que luego se esparcen como ceniza antes de centrifugarse en proyectos pasados y futuros. —No he entendido nada —declaro muy serio. —Te resumo. Los objetos cuando mueren se transforman en pensamientos, justo lo mismo que sois antes de nacer.

24

var = 3; // o var=new EstudianteGradoInformatica(“Pedro”,...); //o var=otraVariable;

66

Libro disponible en: eybooks.com

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Pensamientos... —arguyo resignado—, suena mejor que lo de la ceniza. Por cierto, cambiando de tema: ¿cuando dos variables apuntan al mismo objeto, se dice que son iguales aunque tengan distinto nombre? —No me interesa, en realidad lo pregunto para escapar de mis obsesivos recelos. —Sí, claro, cuando dos variables almacenan la misma dirección de memoria son iguales e idénticas. —Iguales e idénticas... —repito con suspicacia—. Venga, que ya nos vamos conociendo... explíqueme el matiz; usted no gasta saliva por gusto. —Dos variables son idénticas 25 si su contenido es el mismo, ya sea un dato primitivo o la dirección de memoria de un objeto. Y dos variables son iguales 26, pero no idénticas, si apuntan a dos objetos diferentes que sin embargo son iguales. —Ja, ja, esto parece el “cuento de pan y pimiento”. —¿Qué cuento es ese? —No perdamos el tiempo en bucles infinitos —le exijo—. Dígame cuándo dos objetos son iguales, pero no idénticos. —Dos objetos son iguales cuando son de la misma clase y tienen el mismo estado, o sea, igual valor en todos sus

25

var1 == var2 //Ejemplo: 3 == 3 es true /* Ejemplo: Circulo var1, var2; var1=new Circulo(3); var2=var1; var1==var2 es true */ 26 var1.equals(var2)/* Ejemplo: Circulo var1, var2; var1=new Circulo(3); var2=new Circulo(3); var1.equal(var2) es true, pero var1==var2 es false */

67

NURIA MEDINA

© Alfaomega - RC Libros

atributos. Sin embargo, para que dos objetos sean idénticos tienen que ser el mismo objeto. —Ya, entiendo... —¿Ahora lo entiendes?, creía que lo tenías claro de antes. Hace tiempo que andamos con esto. —Sí, es verdad —alego azorado—, estoy algo espeso. —¿Espeso? —Quiero decir que tengo el “cerebro” sobrecargado con tanta información. —En ese caso, ¿de atributos complejos ni hablamos, no? —¿Atributos complejos? —Sí, te he dicho que dos objetos son iguales si son iguales todos sus atributos; pero sus atributos pueden ser a su vez objetos. —Ponga un ejemplo. —Un objeto de la clase Asignatura tiene un atributo que es profesor y otro atributo que es número de créditos. El atributo profesor será un objeto de la clase Profesor. —Hace una pausa para darse importancia y continúa imperturbable ante mi “jeta” de concentración extrema—: para que dos asignaturas sean iguales, tienen que tener el mismo número de créditos y el mismo profesor. Y para saber si tienen el mismo profesor, habría que comparar los dos profesores, recursivamente, comprobando la igualdad de todos sus atributos (nombre del profesor, DNI, etc.). —Vaya lío, no puede ser más complicado. 68

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Claro que sí —anuncia triunfal—. Un atributo también podría ser una colección de objetos 27. —Por favor, concrete —le suplico a punto de romper a llorar. Me ha entrado el bajón. —Imagina que una misma asignatura la pueden impartir varios profesores (cada uno se ocupa de una parte). En ese caso, el objeto asignatura tendría en su estado un atributo número de créditos, un atributo profesor responsable y un atributo colección de profesores para poder guardar todos los profesores que imparten la asignatura. Y para saber si dos asignaturas son iguales, habría que comparar también sus colecciones de profesores, lo que equivaldría a comparar uno a uno los objetos profesor que hay en dichas colecciones...

27

ArrayList, LinkedList, TreeSet, HasMap... son colecciones típicas en Java

69

NURIA MEDINA

© Alfaomega - RC Libros

Ilustración 7. Los atributos de un objeto pueden ser, a su vez, otros objetos. Así, la mayoría de los objetos son estructuralmente complejos.

—¡Por favor, pare! —solicito a punto de echarme a hervir—. Me está volviendo a doler la “cabeza”. —Será del viaje —apunta chistoso—. ¿Quieres que regresemos? No respondo, pero lo miro de soslayo y el señor Paradigma entiende el gesto. Silba y el ventilador desciende. Sin necesidad de que nadie me lo exija, cierro los “ojos”. A tientas me agarro al eje que antes creía un alerón. El ruido del motor se acrecienta y el aire se infiltra entre mis “pies” y el suelo, a bocanadas al inicio y a raudales después. 70

© Alfaomega - RC Libros

JAVA. LA NOVELA

Siento cómo crece la distancia que me separa de la celda “var” y, antes de que sea demasiado tarde, sacudo mis “piernas” ejecutando una tijereta a modo de adiós. Espero que 0x0000812C pueda haber entendido la inusual despedida, porque a estas alturas el “tipo” agarrado al ventilador, o sea yo, está precisamente cruzando el horizonte que separa el heap del stack; y, de ahora en adelante, nuestra relación quedará de nuevo reducida a la sensación de una púa de flecha que me roza continuamente la “espalda”.

71

13. Amor a primera vista Hace días que no veo al señor Paradigma. No lo he visto, ni he hablado con él, pero no puedo asegurar que no haya estado rondándome, porque la verdad es que no he tenido “ojos” para ninguna otra cosa que no sea ella. Me refiero a la chica que avizoré desde las alturas conforme me acercaba a mi casa en el montículo (para aterrizar no tuve más remedio que mirar y ahí estaba ella). ¿Cómo era? No podría describírtela porque no sé cuál es el color de sus “cabellos”, el tamaño de sus “ojos”, ni el bronceado de su “piel”. No sé nada de esa chica salvo que es hermosa. Miró hacia arriba cuando sobrevolé su “coronilla” y ni siquiera se inmutó por el hecho de que estuviese asido a un aspa de ventilador. Le puse “ojitos” y no reaccionó, agité el “brazo” y ni caso; tampoco tuve mejor suerte cuando le grité: «¡vaya cosita linda!». Más bien tuve mala suerte, porque el maestro se rio a carcajadas. Menudo ataque de risa. Nunca lo había visto así. Pero no lo critico, la situación era ridícula. Rio hasta toser y luego me explicó que no podía verme, que ella no era un objeto especial. Quise saber por qué yo tampoco podía verla y le exigí una explicación. Entiendo que esto puede parecer un sinsentido ya que acabo de decir que la vi, pero es que aunque la veía y sabía que era una estudiante como yo, era como si estuviese envuelta en una cápsula opaca que, a partir de ahí, no me dejaba conocer ni tan siquiera su nombre.

72

© Alfaomega - RC Libros

JAVA. LA NOVELA

El maestro, que todo lo sabe, me indicó que esa opacidad se llama encapsulamiento y que es una especie de mecanismo de defensa de los objetos. «¿Contra quién luchamos los objetos?», inquirí colocándome en guardia y rio otra vez. Afortunadamente, esta vez no necesitó toser para continuar y, cuando lo hizo, me indicó que simplemente los objetos tratan de proteger su privacidad para que no se pueda averiguar ni modificar su estado contra su voluntad. Empezaba a hartarme de las risotadas y generalidades del señor Paradigma y decidí ir directo al grano: —¿Qué debo hacer si quiero averiguar su nombre? —Si quieres conocer su nombre o el valor de algún otro atributo, pregúntaselo a ella con el correspondiente consultor. —¿Consultor? —Sí, en vuestra clase existe un método consultor28 para conocer el valor de cada atributo de los que conforman tu estado. —Espere un momento. Ella y yo pertenecemos a la misma clase. Eso significa... —Eso no significa nada, ella no es tu hermana porque tu clase no es tu mamá. Ya te lo aclaré; la clase es una definición textual, no es un elemento vivo en Java. —¿Cómo sabe lo que estaba pensando? —recapacité a tiempo y no le di opción a contestar. En su lugar, tramé mi venganza—: no me responda, había olvidado que puede 28

getNombre(), getDireccion(), getFechaNacimiento()...

73

NURIA MEDINA

© Alfaomega - RC Libros

escuchar mis pensamientos. Y, ¿sabe qué le digo? —Negó con la “cabeza”—, me siento violado; no tengo privacidad; ¡exijo mi encapsulamiento! —manifesté, fingiendo un enfado monumental. El señor Paradigma se quedó rígido y como un robot consiguió dar un paso para atrás mientras una gran arruga se formaba en sus “labios” compungidos. —No gimotee maestro, era broma. No quiero darle ningún mal rato. Pero le estaría bien empleado por reírse de mí. Ahí la arruga se hizo gigante y culminó con un estrepitoso sonido, no de llanto sino de sainete. Otra vez se había vuelto a quedar conmigo. Por supuesto que había tenido acceso a mi mente mientras trazaba mi maltrecho escarmiento. Menudo problema es esto de no tener encapsulamiento. —Usted gana —acepté—. Dígame, ¿cómo se llama el método que tiene mi clase para consultar la fecha de nacimiento de una de sus instancias? Quiero preguntarle también la edad porque, tendré que confesárselo, me gustan las chicas mayores y, si vamos a compartir “fluidos eléctricos”, quiero asegurarme de que no sea una pipiola. —Vuestro amor es imposible. —¿Por qué iba a serlo? —rebato con tono de fastidio. —Porque se sale de los requisitos funcionales de la aplicación. —Venga, recuérdeme de todos modos cómo se llamaban esos métodos —insisto con prisa—. Cuando estuvimos en mi código fuente no me fijé en los consultores y quiero aprender —apelo a su deber docente. 74

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Te lo diré, pero no los uses. No debes interferir en el programa con esas niñerías. —¿Niñerías? El amor no es ninguna majadería. El amor mueve montañas. —¿Amor? ¿Montañas? —El señor Paradigma se echa las “manos” a la “calva”—. El amor aquí dentro no tiene cabida. Sácate esas ideas de la “cabezota” y júrame que no te saltarás las normas: nada de mensajes fuera de la secuencia de ejecución programada. —Lo juro —respondo convencido. —El consultor para conocer la fecha de nacimiento de un objeto de la clase EstudianteGradoInformatica se llama getFechaNacimiento(), normalmente siempre es así: la palabra get (u otra similar) precediendo al nombre del atributo cuyo valor se quiere consultar. —Y getNombre() para saber cómo se llama. Lo tengo todo, gracias. Me quedo callado y un silencio incómodo se aposta entre ambos. La ausencia de sonidos revolotea sobre nuestras “cabezas” sin hacer ruido. El señor Paradigma se impacienta, desconfía, pero no se atreve a volver a insistirme ni puede exigirme que siga haciéndole preguntas. Así que espera un rato y luego desaparece como niebla temprana. Me quedo solo, y me repito que el maestro tiene toda la razón: el amor no es para los objetos, es para los humanos que se dedican a cambiar de sitio las montañas. Sin embargo, mi “patata caliente” palpita cuando recuerdo su imagen, la de la chica (no la del profe, claro está). 75

NURIA MEDINA

© Alfaomega - RC Libros

No puedo quedarme quieto, tengo que encontrarla y preguntarle qué edad tiene y cómo se llama. No se van a desmoronar los pilares de la RAM por eso, vamos, creo yo. Comienzo a caminar, la flecha me persigue, pero no me amedranto. Voy a llegar hasta ella. Dicen que cuando la niebla de la mañana es molinera, traerá lluvia; pero aquí dentro no ha llovido nunca. El programa no va a aguarse por un par de mensajes que naden a la deriva. Ya casi llego. Allí está. La “patata” se impacienta y aprieto el paso. Se me desencaja la “mandíbula” y me quedo con la “boca” abierta. Está radiante. «No, no, no», resuenan en mi juicio los gritos del señor Paradigma. Está escandalizado, pero yo también estoy fuera de mis casillas. No controlo mis pensamientos ni mis actos. Abro la “boca”, más si cabe, y le envío dos mensajes a la chica: el primero para conocer su nombre 29, el segundo para conocer su edad 30.

29 30

chica.getNombre(); chica.getFechaNacimiento();

76

© Alfaomega - RC Libros

JAVA. LA NOVELA

Ilustración 8. En el envío de mensajes, el receptor está explícito, pero no el emisor (el objeto que envía el mensaje desde uno de sus métodos).

Isidora, se llama Isidora y tiene 22 años. ¿Isidora? No me gusta el nombre. Y hago una barbaridad. Más por intuición que por conocimiento, más por atrevimiento que por necesidad, respiro hondo, saco “pecho” y digo en alto: chica.setNombre(“Helena”). —¡Estás loco de remate! —clama el señor Paradigma que surge de la nada, desbaratando la escena con unas tijeras de podar—. No te das cuenta de lo que tratabas de hacer. ¿Cambiarle el valor de un atributo a otro objeto del programa? Estás demente, si no llego a intervenir a tiempo habría aceptado tu mensaje. —Perdón —expreso trémulo. 77

NURIA MEDINA

© Alfaomega - RC Libros

—No te perdono. Es imperdonable. Ese objeto representa a una estudiante de ahí fuera, del más allá, del mundo de los humanos. No puedes rebautizarla —exclama. —Ha sido una temeridad, pensé que no se dejaría cambiar el nombre —musito, venido a menos. —Pues claro que se dejaría, el método modificador 31 es público. —¿Público? —Sí, me refiero a la visibilidad del método. —¿Visibilidad, qué significa? —Todos los atributos y métodos de una clase se declaran con una visibilidad de acceso. Esa visibilidad indica quién puede conocer el valor del atributo o solicitar la ejecución del método, respectivamente. —No me entero. —Si me prometes que dejarás en paz, de una vez por todas, a Isidora, te lo explico. —Prometido, si le digo la verdad ya no me gusta tanto; y si una piedra pesa lo suyo, imagínese una montaña... —¡Cómo sois los jóvenes! En cuanto se pierde el misterio se esfuma el interés.

31

chica.setNombre(“Helena”); /* Los métodos que modifican atributos se suelen denominar con la palabra set (u otra similar) seguida del nombre del atributo cuyo valor establecen o actualizan */

78

© Alfaomega - RC Libros

JAVA. LA NOVELA

Sonrío disimulado, lleva toda la razón. —Venga, prepárate para otro viaje —me indica. —Adiós, Helena —bromeo, aunque viendo la “cara” de perro del señor Paradigma, añado enseguida—: adiós, Isidora. Fue bonito mientras duró—, y alzo los “brazos” esperando que el maestro silbe para que descienda el ventilador, pero en lugar de eso me los baja y aprieta contra los “sobacos” con rencorosa antipatía. —¿Qué pasa? ¿Por qué no silba? —pregunto. —No vamos a montar en helicóptero, nos vamos fuera de la memoria RAM. Así que tendrás que prepararte para un nuevo viaje astral.

79

14. Detalles Las barreras físicas han desaparecido y nuestra energía se proyecta en todas direcciones. Nos fundimos con otras fuerzas etéreas y tan solo nos ancla al suelo el “cordón de plata” que ilumina nuestro trayecto a la altura de nuestros “ombligos”. El desplazamiento es vertiginoso pues la velocidad la marca nuestro propio pensamiento y los planos horizontales y verticales caen como las cartas de un castillo de naipes bajo el vendaval del plano astral. El tráfico de energía crece a medida que nos alejamos de la memoria RAM, se acelera y se vuelve puro bullicio hasta estallar en miles de partículas de luz que se reordenan cuando atravesamos la frontera invisible del disco duro. —Ya estamos aquí de nuevo. En el código fuente de tu clase. Fíjate bien, ahora, en todos los detalles —me suelta con tintes de amonestación. —Sí, lo haré, maestro. La otra vez admiré el cuadro grosso modo, vista de águila que se llama, pero empiezo a darme cuenta de que los detalles son importantes. —Por supuesto que lo son. En la implementación de una clase cada detalle cuenta. Observa el atributo nombre 32. ¿Lo ves? Lo primero que pone es private; eso significa que es un atributo privado. Es decir, que solo se puede acceder directamente a su valor desde el código de los métodos de

32

private String nombre;

80

© Alfaomega - RC Libros

JAVA. LA NOVELA

esta clase. Fuera de la clase EstudianteGradoInformatica no es visible y, por tanto, nadie podrá conocer su valor o asignarle un nuevo valor de forma directa 33. —Pero... todos mis atributos están declarados como private. —Así es y así debería ser para no violar el principio de encapsulación. Si algún objeto necesita conocer un atributo tuyo o modificar el valor de este, que te lo pida. ¿Qué menos?, ¿no? —Sí, claro —convino—. Y, en esas circunstancias, digo, cuando es necesario desde otra clase conocer el valor de alguno de mis atributos: ¿cómo se lograría? Póngase por caso que un profesor quiere saber mi nombre. ¿Cómo podría ese profesor saber cómo me llamo? —Chico, si lo has hecho tú mismo hace un momento. Tienes vista de águila, pero memoria de pez. Si otro objeto, digamos por caso, un objeto de la clase Profesor, quiere averiguar tu nombre, usará el método consultor correspondiente34.

33

nombre = “valor”; //Ejemplo: nombre = “Juanitín”; o nombre = otroString; //Ejemplo: nombre = otroNombre; o return nombre; //o

String otraVar = nombre; /* ninguna de estas instrucciones está permitida fuera de la clase EstudianteGradoInformatica porque el atributo nombre es privado */ 34 String n = var.getNombre(); /* var apunta al estudiante llamado “Juan” */

81

NURIA MEDINA

© Alfaomega - RC Libros

—Es cierto, qué tonto soy —admito y me sonrojo—. Solo a veces... —matizo mientras añado—: mire, allí está el consultor de mi nombre. —Efectivamente, y como podrás comprobar ese método está declarado como public. —Es cierto, todos mis métodos consultores y modificadores están declarados como públicos. De esta forma se podrán invocar desde cualquier otra clase del programa. —Correcto —proclama. —Sé que no le va a gustar lo que le voy a sugerir a continuación... —musito mientras me rasco la “sesera”. —Continúa, hay confianza —consiente. —... ¿y si no tengo ganas de decirle al profesor mi nombre? —Te jodes —Dios mío, el señor Paradigma ha soltado un taco, me deja estupefacto—. Es tu responsabilidad y tienes que ejecutarla. Así funciona todo, ¿recuerdas?: colaboración entre objetos. —Tranquilo, maestro. No se ponga así. Lo dije medio en broma. —Ya, ya... medio en broma, medio en serio —porfía con retintín. Trago saliva y lo observo. No sé si le ha molestado más mi actitud rebelde o que quisiera echar por tierra el principio fundamental de la orientación a objetos. Pero es 82

© Alfaomega - RC Libros

JAVA. LA NOVELA

incuestionable que tiene un cabreo colosal: ha arrugado el “morro” y fruncido el “ceño” y sus “brazos” están cruzados. En esa postura, su “cuerpo” se me antoja un trompo, pero no puedo permitirme mantener ese pensamiento porque me echaría a reír, y con el mal talante que está demostrando es capaz de soltarme una “galleta”. Por eso, desvío mi atención al código fuente de mi clase y, por fortuna, algo llama mi atención, justo antes de que mi mente se atreviera a bailar la perinola. —Un detalle, señor Paradigma: ¿por qué el consultor getFechaNacimiento() 35 no devuelve directamente mi atributo fechaNacimiento, sino una copia del mismo? —Bien apuntado chico —exclama el maestro mientras asiente con la “cabeza” y descruza los “brazos”—. Se devuelve otro objeto GregorianCalendar con igual estado pero distinta identidad. Esto garantiza el encapsulamiento al 100%. No lo olvides, en Java se trabaja con punteros y si se devolviese directamente el puntero al atributo fechaNacimiento, estaríamos dando acceso directo al atributo, con lo cual se podría modificar tu edad desde fuera sin usar tu modificador setFechaNacimiento. Es decir, sin pedirte permiso.

35

public GregorianCalendar getFechaNacimiento(){ int year = fechaNacimiento.get(Calendar.YEAR); int month = fechaNacimiento.get(Calendar.MONTH);

GregorianCalendar nF = new GregorianCalendar(year,month,day); return nF; }

83

NURIA MEDINA

© Alfaomega - RC Libros

—No sé si lo entiendo... Pero, ahora que me fijo, está claro que algo similar ocurre con el método modificador setFechaNacimiento 36 : se usa una copia del argumento y no el propio argumento. ¿Sucede así con todos los modificadores y consultores? —Con todos no tiene por qué. Por ejemplo, con los métodos que consultan o modifican un valor primitivo no sería necesario hacer copias 37, porque ahí estamos en el stack y la variable de instancia contiene el valor, no un puntero al valor (como el paso de parámetros es por copia, ya se devuelve por defecto una copia del valor). Por lo tanto, solo es conveniente trabajar con copias de los argumentos en los gets y sets cuando el atributo es un objeto o una colección de objetos y requerimos la mayor seguridad en su encapsulamiento —me corrige el maestro con apego. Es evidente que ha echado a la mar todos los pelillos que le faltan a su “calva” reluciente; y no queda en él el más mínimo rastro de enojo. —Es complicado. —Sí, no te preocupes, esto es para nota. Puedes pensarlo despacio. Te animo a ello.

36

public void setFechaNacimiento(GregorianCalendar nuevaFecha) {fechaNacimiento = new GregorianCalendar( nuevaFecha.get(Calendar.YEAR), nuevaFecha.get(Calendar.MONTH), nuevaFecha.get(Calendar.DAY_OF_MONTH));} 37 public float getPeso() {return peso;} public void setPeso(float nuevoPeso) {peso = nuevoPeso;}

84

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Me está “picando”, maestro. Sabe que soy orgulloso y no voy a parar de darle vueltas al “tarro” hasta que lo tenga tan claro como el agua. —Cuidado, el agua llena de pelos se vuelve turbia —comenta y sonríe. Otra vez lo ha hecho, ¡no tengo intimidad! Pero si él se ha tomado tan bien que le llame “calvorota” (de pensamiento), no voy a ser yo menos. —Ja, ja. Si le gustan las metáforas, le diré que las dudas me queman en las “manos” como si fueran bolas de fuego. No puedo evitar preguntarle sobre algo que ha dicho antes de pasada y que me ha sonado raro: ¿variable de instancia? —Ah, eso... Este balón es más sencillo de interceptar. Se llama variable de instancia a una variable que almacena un atributo de un objeto 38. De modo que el conjunto de variables de instancia guarda el estado de un objeto que, como recordarás, solía cambiar a lo largo de la vida del mismo. —Sí, lo recuerdo —afirmo, observando las líneas de código donde se han declarado mis atributos y una progresión de sensaciones acontece: surgen como unas 38

class EstudianteGradoInformatica{ private String nombre; //variable de instancia

private GregorianCalendar fechaNacimiento; //v.instancia ... /* declaración del resto de variables de instancia */ // declaración de los métodos }

85

NURIA MEDINA

© Alfaomega - RC Libros

cosquillas que se convierten en picazón para renacer como calor abrasador y crecer hasta quemarme las “palmas” de las “manos”. Palmoteo en el aire, sin éxito, la duda me consume; así que lanzo la bola de fuego y continúa el partido—: ¿el atributo titulación39 por qué es diferente? —Es cierto, ese atributo es private como los demás pero, aparte de eso, está declarado como final y como static. —Ya, ya, eso ya lo veo. Sé leer. ¿Qué significa? —insisto. —Vayamos por partes. El modificador final significa que una vez inicializada la variable titulación su valor no se puede modificar. —Ajá. Si un atributo está declarado como final significa que es constante. Es intuitivo, pero ¿qué significa que la variable es static? —Estás acelerado. Cálmate, pisa el freno y dime: ¿recuerdas qué significaba que un método estuviese declarado como static? —Creo que sí —confieso y respiro antes de tirarme a la piscina—: un método static es una responsabilidad que resuelve la clase y por lo tanto requiere que el mensaje (la petición) se le envíe a la propia clase, no a un objeto de esa clase. —Muy bien —me felicita—. Un método declarado como static es un método de clase, del mismo modo que una variable declarada como static es una variable de clase. 39

private final static TitulacionGradoInformatica titulación;

86

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Y la diferencia entre una variable de clase y una variable de instancia es... —Yo chamuscándome las “manos” y el señor Paradigma remoloneando. Mira que es puñetero. Respiro hondo y tres respiraciones profundas han de pasar antes de que continúe hablando. —La diferencia es que el valor de la variable de clase es el mismo para todos los objetos de esa clase. Por eso, se guarda una sola copia de la variable de clase, mientras que para las variables de instancia cada objeto almacena su propio valor. —¡Ahora sí! —manifiesto con júbilo y me soplo las “manos” que arrancan a enfriarse—. Todos los objetos de la clase EstudianteGradoInformatica tenemos la misma titulación, por eso es suficiente con una única variable controlada a nivel de clase. Por el contrario, cada estudiante tiene su propio DNI y habrá tantas variables de instancia DNI como instancias existan de mi clase. — Voilà. —Pues ya está. ¿Ahora no podrá decir que no me he fijado en todos los detalles? —aventuro desafiante. —Bueno, si ya está, dime: ¿aquel método que no está declarado ni como private ni como public?, ¿qué pasa con él? Me quedo parado y no es para menos, no me había dado cuenta de que había un método que no estaba declarado como public. —Ni idea —reconozco—. No sé si será private o public. Supongo que es public porque los atributos deben ser privados para proteger su encapsulación, pero los métodos 87

NURIA MEDINA

© Alfaomega - RC Libros

deberían ser públicos para que objetos de otras clases nos puedan pedir cosas. —Tus razones están acertadas, pero no tu respuesta. En Java, si no se pone nada, por defecto un método o una variable está declarada como package. —¿package? —Sí, package, en Java existen cuatro modificadores de acceso para establecer la visibilidad, o sea, quién puede acceder a la variable o al método. Estos son: private, public, package (por defecto) y protected. —“Solo sé que no sé nada” —parafraseo cual discípulo de Sócrates—. Ilumíneme, ¿qué significa package? —De acuerdo, te explicaré quién puede invocar un método que está declarado como package, pero tengo que comenzar la historia por el principio. —Me mira en busca de aprobación y asiento con un vaivén de “barbilla”—. Las clases se agrupan en paquetes. Un paquete incluye un conjunto de clases relacionadas semánticamente. Mira allá arriba, justo encima de la cabecera de tu clase —me pide mientras señala una instrucción que reza: package docencia; —¿La cabecera de mi clase? —pregunto, desorientado, sin saber adónde mirar.

88

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Sí, la cabecera, donde pone: public class EstudianteGradoInformatica40 —reclama incómodo por tener que rebobinar la historia más atrás de lo que esperaba—. La clase, al igual que los métodos, tiene dos partes, pensé que ya te habrías dado cuenta. La cabecera es donde se declara la clase y el cuerpo, que va entre {}, es donde se definen sus atributos y métodos. —Ok, ya distingo la cabecera. Al principio del fichero, donde pone el nombre de la clase, EstudianteGradoInformatica, después de la palabra reservada class. —Eso es. Observa que la cabecera de la clase empieza con el modificador de acceso public, eso establece que la clase EstudianteGradoInformatica será visible desde fuera del paquete donde está incluida. —Entiendo, el paquete es como un cajón para organizar las clases, pero habrá algunas clases que no pueden “salir” del cajón porque son privadas. Como si fueran trapos sucios. 40

package docencia; /* La clase pertenece al paquete docencia */ public class EstudianteGradoInformatica /* cabecera de la clase */ { //cuerpo de la clase (código entre llaves) private String nombre; /* declaración de variables de instancia y de clase */ ... public EstudianteGradoInformatica(...){...} /* declaración de constructores */ ... public String getNombre(){...} /* declaración de métodos de instancia y de clase */ ... }

89

NURIA MEDINA

© Alfaomega - RC Libros

—Eliminaría la calificación de “trapos sucios” y añadiría que el paquete es un nivel más de modularidad. —¿Modularidad? —A estas alturas, de tantas dudas que tengo, ya no me queman las “manos”; directamente, el que está quemado soy yo. Pero no pierdo el ánimo, la madeja debe tener un final. Aunque los objetos hablen, el hilo debería seguir siendo finito. —Modularidad es la propiedad que permite subdividir una aplicación en partes más pequeñas. En nuestro caso, el programa se divide en paquetes, cada paquete se divide en clases y cada clase se divide en atributos (estructura) y métodos (funcionalidad). —Ya, ya, continúe. Es evidente que todo está muy bien organizado gracias a la modularidad. —¿Por dónde iba...? Él también parece cansado, las “ojeras” le llegan al suelo y temo que pierda el hilo y se líe de nuevo la madeja. En ese hipotético caso, tendré que controlarme, porque soy capaz de meterle las agujas de tejer crochet por el... —Ah, sí —retoma el discurso el señor Paradigma, poniendo a salvo sus posaderas (metafóricamente hablando, no quiero que haya malos entendidos)—, cuando un método está declarado como package puede ser invocado por cualquier clase que pertenezca al mismo paquete que la clase actual, pero no por las clases que quedan fuera. —Siendo prácticos, señor Paradigma, en mi caso: el método que no tiene ningún modificador de acceso, y que por tanto tiene visibilidad package, podrá ser solicitado desde todas las clases incluidas en el paquete docencia. 90

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Eso mismo —suspira y suspiro. Tú no suspires, que ya queda menos... —Vale, y si se trata de un método público no hay problema en llamarlo desde una clase de otro paquete —recapitulo. —Eso mismo, pero como pertenece a otro paquete antes se debe importar la clase.

Ilustración 9. Un elemento (atributo o método) privado no es visible desde fuera de la clase donde está definido. Un elemento público es transparente desde cualquier clase. Un elemento package es visible para las clases del mismo paquete, pero opaco para el resto. 91

NURIA MEDINA

© Alfaomega - RC Libros

—¿Importar una clase?, ¿cómo se hace eso? —pregunto bostezando. —La clase que quiere usar una clase de otro paquete debe poner antes de su propia cabecera la sentencia de importación correspondiente, en este caso 41 : import docencia.EstudianteGradoInformatica; —responde el señor Paradigma al que le he contagiado el bostezo. —Uff, y así una a una, todas las clases de los otros paquetes que se necesiten. ¡Qué cansado! —opino frotándome los “ojos”. Me da pereza imaginar cuánto hay que escribir cuando se quieren usar todas las clases de otro paquete. —También se puede importar el paquete entero, usando el símbolo *42 en lugar de poner el nombre de una clase concreta. —Mucho más cómodo, pero supongo que costará más caro importar el paquete entero que solo una clase. —Vale lo mismo —explica mientras esboza una sonrisa—, cero euros en ambos casos.

41

package administracion; /* La clase SecretarioCentro pertenece al paquete administracion */ import docencia.EstudianteGradoInformatica; public class SecretarioCentro{ ...cuerpo de la clase... //puede usar EstudianteGradoInformatica } 42 import docencia.*;

92

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Genial —refiero con menos énfasis del que se merece la oferta, sin duda, debido al cansancio—. Los paquetes ya no son ningún misterio. Cuénteme ahora qué clases podrían acceder a un método o a una variable declarada como protected —le pido en un susurro, mientras estiro los “codos” por detrás y ejecuto un nuevo bostezo. —Ni hablar —responde—. Ahora nos vamos a echar una siesta. —Cierra los “ojos” y se encorva como un ovillo de lana (sin agujas). No le contradigo. Han sido demasiados detalles, por muy preciosa que sea la sintaxis Java. Y me consta que quedan carretones llenos de ellos. No me estreso. Ahora voy a descansar. Después de la siesta, cogeré el toro por los cuernos. Me acurruco junto al señor Paradigma y su acompasada respiración me sirve de nana. En un momento estoy dormido. El abrazo de Morfeo es dulce y calienta, pero no quema. Estamos en paz y en nuestra mente la calma es absoluta; aunque nuestros ronquidos deben escucharse, incluso, desde la memoria RAM.

93

15. Sonríe y di “patata” Me despierto sobresaltado. Despego la “cabeza” del señor Paradigma de mi “hombro” y observo con cierto repelús las babas que ha fabricado y distribuido sobre mi “persona” durante el sueño que se resiste a interrumpir. Ronca como un caballo. Seguramente más fuerte, pero no puedo compararlos con justicia porque nunca he visto a un caballo roncar y para serte sincero no tengo la más remota idea de lo que es un caballo. Lo que sí sé a ciencia cierta es que algo está cambiando en el código fuente. Para empezar, el sonido del ventilador emite a intervalos un crujido tenebroso que las líneas de código bailan pavorosas. Cada vez, el quejido es más longevo y los renglones digitales se tuercen, y la “tinta” de los caracteres se derrite como si una combustión fantasmagórica los hiciese sudar. Comienzo a transpirar a pesar de que los escalofríos ascienden por mi congelada “espalda” como lagartijas sedientas de sangre. Chorreones rojos, líquido infernal en el que se ha transfigurado la coloración de las sentencias Java. Junto a mí, el maestro duerme tan plácidamente como un niño, ajeno a la zozobra que me embarga y a la oscuridad que nos sobreviene. En la penumbra advierto, o más bien siento, cómo su “pecho” crece y decrece cadencioso y cómo, acompasadamente, el oxígeno binario juguetea con sus “fosas nasales”: templado en la inhalación, ardiente en la exhalación. 94

© Alfaomega - RC Libros

JAVA. LA NOVELA

Sin prisa pero sin pausa, el humo que exhala el señor Paradigma recubre todo con vapor, haciendo más espectral la negrura que nos envuelve. Me repliego sobre mí mismo y me abrazo las “rodillas” llevándomelas sobre el “pecho”. Estoy aterrado. Nunca había sentido pánico y la primicia incrementa mi terror. Es horrible. Debo calmarme, pero no puedo. Transito de un estado de parálisis a otro de exaltación en un ciclo interminable que acabará por destrozar mis nervios. Para tratar de tranquilizarme, me concentro en el maestro. Sigue durmiendo. No entiendo cómo puede, teniendo en cuenta lo enérgica que repiquetea, ahora, la pérfida sinfonía de fondo. Pero él, como si fuera un recién nacido, luce una sonrisa plácida; muy al contrario mía que he crispado arrugas que todavía siquiera se habían sembrado en mi “rostro”. Debo calmarme y voy a hacerlo. Tengo fuerza de voluntad y ha llegado el momento de demostrarlo. Voy a imitar su postura. Suelto mis “rodillas” y libero las tensiones de mis “músculos”, a duras penas, pero de forma efectiva. Adquiero su posición, tumbado y con la “cabeza” ladeada hacia la izquierda. Las “piernas” abiertas al ancho de las “caderas”, las “palmas” de las “manos” vueltas hacia arriba, y el el “cordón de luz” que nace de su “ombligo”. No puedo copiarlo porque el suyo se iza infinito mientras ondula con parsimonia; y el mío, simplemente, ha desaparecido. ¡He perdido el “cordón astral”!, noooooooooooooooooooooooooooooooooooooooooooooo, no puede ser. 95

NURIA MEDINA

© Alfaomega - RC Libros

Grito, lloro y aúllo; y aun así el maestro no se despierta. Estoy perdido, no podré regresar a la memoria RAM ni, por tanto, a mi programa. Estoy destrozado, no solo por fuera, lo que es evidente pues mi “cordón astral” se ha roto y desintegrado, sino inclusive más por dentro: he perdido todo cuanto tenía. Me está bien empleado por creerme especial. ¿Por qué no habré sido más humilde? ¿Por qué no habré sido un objeto como los demás? —¿Por qué no me avisó de que el viaje astral era tan peligroso? —recrimino al maestro, mientras lo zarandeo. Mi dolor es más llevadero si le echo la culpa a otro—: ¿por qué me ha traído hasta aquí? —le exijo explicaciones al bello durmiente. A pesar de mis esfuerzos, no abandona su letargo, y tanta tranquilidad ya me escama. De perdidos al río: lo sujeto por ambos “hombros” y lo agito con violencia: —Despierte, maestro. ¡Despierte! —chillo en su misma “oreja”. Sin embargo, no se inmuta. Reparo en que su “cuerpo” no pesa. No es que haya adelgazado. A pesar de su generoso volumen, su “cuerpo” no pesa ni un gramo. El mío tampoco. Es increíble, pero cierto. No tenemos materia, pero no sé de qué me extraño: nunca la hemos tenido. Como consecuencia, ascendemos cual pelusas, girando livianas, y una vez bien arriba, comenzamos a gravitar con brío. Nos hemos convertido en satélites de un agujero negro que hasta el momento se había conformado con ingerir el vaho procedente de nuestras férvidas respiraciones. Ahora no se conforma. El agujero está hambriento y nos atrae irremediablemente. Mientras, el maestro sigue 96

© Alfaomega - RC Libros

JAVA. LA NOVELA

durmiendo. Berreo. No me oye, pero ahora es lógico, ni siquiera yo escucho mi propia voz. La radiación es constante en torno a una curvatura espacio-tiempo de la que no podremos escapar. Yo, mucho menos; desprovisto de mi “cordón astral” estoy completamente indefenso. No tengo ninguna oportunidad: ¿para qué tomarme la molestia de desgañitarme? Seguro que no sirve de nada. El núcleo que nos atrae es ciclópeo y mis peticiones de auxilio resuenan en sus fauces tan imperceptibles como la súplica de una larva de mosquito. La culpa la tiene el estrépito que origina la palabra que se repite sin descanso a 100 decibelios: NullPointerException, NullPointerException, NullPointerException... Nunca antes la había oído, pero me hace temblar. Frente a todo pronóstico, no me desmorono. Tengo fuerza de voluntad y ahora es el momento de demostrarlo. Tiro de mi “masa” en dirección contraria a la órbita de atracción, con todas mis fuerzas y, con las mismas, grito como un descosido: —!Socorro! —!Quiero vivirrrrrrrrrrrrrrrr! Me despierto sobresaltado. Despego la “cabeza” del señor Paradigma de mi “hombro” y me limpio el líquido viscoso del cuello de la camisa. Estoy empapado en sudor y el maestro me mira con “cara” de preocupación absoluta. —¿Qué te ocurría? Jadeabas y gritabas pávido. ¿Has tenido un mal sueño? —pregunta paternal. No le respondo. Respiro profundo y despacio; bajo la mirada, poquito a poco, hasta llegar a mi “ombligo”. Allí está: el bendito “cordón”, justo en su sitio. 97

NURIA MEDINA

© Alfaomega - RC Libros

—Vámonos de aquí. He tenido una pesadilla horrible. Vámonos ahora —le ruego. —Tranquilo, no pasa nada. Todo está bien. Hacer un viaje astral tiene algunos riesgos, pero estamos actuando con precaución. —Es peligroso. Quiero marcharme ya. —Menudo sueño has tenido. Agradezco poder escuchar tus pensamientos, pero no tus quimeras. Nos vamos en cuanto tú me digas, pero ten en cuenta que quedan detalles en tu clase por conocer y luego, seguramente, requerirás volver pero te dará más miedo. —Ni loco. —Vaya, lo tienes claro. ¿Pasas de saber más cosas? ¿Has aborrecido la sintaxis de Java? Me derrumbo. Y una tristeza insólita me alcanza como una bala perdida. El impacto es certero y doloroso, arde. Me encanta Java, me siguen fascinando sus maravillosos sustantivos y verbos. Pero, tengo miedo, he visto las orejas al lobo y no quiero que me muerda. Como dice el señor Paradigma, mi obligación como objeto es cumplir con mis responsabilidades en el programa y no puedo ahogarme dentro de un agujero negro. No, al menos, mientras alguien me necesite. —Nada de eso, maestro. Adoro Java. Ojalá existiese alguna forma de contemplar el código fuente sin arriesgar nuestras vidas en el disco duro.

98

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Creo que estás exagerando, suenas melodramático. —Se queda absorto y añade con la mirada perdida—: pero bueno; podemos buscar alguna alternativa. —¿Alguna alternativa? ¿Existía una alternativa a desdoblarnos de nuestros “cuerpos”?, ¿a jugarnos la existencia en una partida a los chinos? ¡No puedo creerlo! ¿Por qué no lo había dicho antes? —Yo también soy un poco melodramático, en el fondo, y el viaje astral era más teatral —responde con irreverente guasa. —Déjese de tonterías —no tengo “cuerpo” para bromas—. Adelante, cuénteme cuál es esa alternativa. —Podemos usar la cámara fotográfica. —¿Cámara fotográfica? —Mira, aquí mismo la tengo —dice como si nada, mientras la saca del bolsillo. Es una cámara de fotos, de última generación. Un oasis en el desierto. Tiene más luces y botones que una atracción de feria y un diseño muy cool. Como no puede ser de otro modo (me encanta la tecnología), hago un amago de tomar la cámara de sus “manos” para trastearla un poco por mi cuenta, pero la retira bruscamente. Qué poca cortesía. —Es muy delicada, como no sabes usarla lo más fácil es que la acabes rompiendo, y peor ahora con ese tembleque que tienes. Será mejor que yo tome las fotos —resuelve para mi decepción. —Vale —consiento. 99

NURIA MEDINA

© Alfaomega - RC Libros

El maestro realiza varias fotografías de EstudianteGradoInformatica.java. Cuando saca la instantánea de la cabecera se esmera por incluir en el recuadro también a las sentencias package e import que la preceden. Y, luego, sin prisa, se asegura de registrar todas las variables y métodos que conforman el cuerpo de mi clase. Se agacha, se pone de puntillas y pone “ojillos” de japonés para que queden perfectamente retratadas tanto las declaraciones de los métodos (modificadores de acceso, tipo devuelto, nombre del método y tipo y nombre de los argumentos) como los bloques de sentencias que los implementan. Todo, todito, hasta la última llave. —¿Ya podemos irnos? Lo tiene todo, ¿verdad? —pregunto ansioso. —Sí, tengo tu clase de cabo a rabo —confirma mientras pasa las fotografías y las visualiza en el display de la cámara—, pero creo que deberíamos fotografiar también el código fuente de algunas otras clases que están relacionadas con la tuya. Puede que cuando se te vaya el susto desees saber más cosas. —Puede, pero no aguanto aquí ni un minuto más. Tendré que resignarme, qué otra cosa puedo hacer si no me llega la camisa al “cuerpo” —confieso, mientras no aparto la vista de mis “manos” que sujetan trémulas el “cordón astral”. —Bueno, como quieras. —Gracias por no tratar de convencerme. Deben ser numerosas las clases que habría que visitar, y no creo que pudiera resistirlo.

100

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Sí, son unas cuantas. Pero lo tuyo ya es fobia. Sería un agradable paseo por el código y el “cordón” no se va a romper, puedes soltarlo. —No lo voy a soltar —replico con genio—, y ¿ve?, ya me está haciendo sudar otra vez. ¿Qué hago?, ¿aprieto los “dientes” y seguimos? o ¿levantamos de una vez el vuelo? Desde luego me lleva al límite de mis fuerzas... —aseguro, mientras me aliento a tirar para adelante, luchando ferozmente contra mi resiliente cobardía. Creo que me voy a desmayar. —Espera, hay otra alternativa. —¿Hay otra alternativa? ¿Por qué no lo dijo antes? —le vuelvo a increpar—. ¿No me diga que su cámara tiene un botón para fotografiar de un plumazo todas las clases relacionados con la mía? —concluyo irónico. —Por supuesto. —¿Eh? —Sí, la cámara tiene una función para fotografiar un conjunto de clases de un solo disparo. Es una cámara muy especial. —Usted sí que es especial, señor Paradigma, me hace sufrir por gusto —digo, pero no se disculpa. En su lugar, se sopla el “pulgar” y acto seguido pulsa el botón mágico. —Listo. Prepárate para regresar —sonríe blandiendo la cámara en alto. Nos cogemos de las “manos” y ascendemos, dando esquinazo, por esta vez, al agüero negro de mis peores sueños. 101

16. El método perdido Una vez en “casa”, embutido dentro de mi “cuerpo físico”, me repongo con relativa facilidad; e incluso me complazco de haber vivido una experiencia tan fantástica, pero me mantengo firme en mi propósito de no volver a realizar un viaje astral. Gracias a mi recobrado ánimo, consigo desplegar una sonrisa y mis mejores artimañas dialécticas para convencer al señor Paradigma de que me preste la cámara fotográfica. «La voy a cuidar bien», le prometo; y el tira y afloja culmina cuando accede de mala gana a mis súplicas. Eso sí, dejándome muy claro que solo me permite visualizar y ampliar las fotografías; nada de tomar instantáneas nuevas ni modificar los parámetros ópticos. El índice ISO, el balanceo de blancos, la abertura de diafragma y la velocidad de obturación, ¡ni tocarlos!, me amenaza mientras me apunta con “dedo” acusador. Es evidente que está presumiendo de saberes fotográficos, pero no hago aprecio a sus palabras. Estoy tan contento que cuando me guardo la cámara en el bolsillo izquierdo, saco del bolsillo derecho una duda que mi agitación por escapar cuanto antes del código fuente casi consigue soterrar: —Ahora que estamos a salvo en la RAM, maestro: ¿le suena de algo la palabreja NullPointerException? —Sí, claro. Es un error que se lanza en tiempo de ejecución cuando en una aplicación Java se intenta pedir algo a una variable que no contiene ningún objeto. Lógico, si le envías un mensaje a una variable vacía (null) se producirá 102

© Alfaomega - RC Libros

JAVA. LA NOVELA

un error en tiempo de ejecución, porque el objeto receptor no existe y por lo tanto no se puede resolver la petición. —Ah, es eso. Qué mal suena. —Sí, es un error feo. Tranquilo, tu programa no lo tiene. —Qué alivio. Pensé que podría ser una especie de premonición. —¿Ahora eres vidente? Te digo yo que esta aplicación está muy bien depurada. Pero, es cierto, en otros programas ocurre. Mayoritariamente se debe a que se declara la variable pero no se le asigna ningún objeto 43. Eso daría error en tiempo de ejecución, en el preciso momento en que se le envía un mensaje a la variable; pues, como te dije antes, dicha variable no apunta a ningún objeto que pueda ejecutar la responsabilidad solicitada. —Blanco es y la gallina lo pone. Lo correcto sería introducir un objeto en la variable 44. ¿Cómo se puede olvidar lo más importante: crear el objeto? —pregunto perplejo ante semejante despiste. —Bueno, no hay que ser tan intransigente. Todos cometemos fallos —apunta condescendiente—. En concreto, este, algunas veces, se debe a un “cruce de cables”, pues existen otros lenguajes de programación donde al declarar una variable se crea automáticamente un objeto de la clase 43

Empleado unEmpleado; //unEmpleado es null … //no se introduce ningún objeto en unEmpleado unEmpleado.trabaja(); /* daría NullPointerException, NO HAY OBJETO QUE PUEDA RESPONDER */ 44 unEmpleado = new Empleado(“Ricardo Álvarez, 33,...);

103

NURIA MEDINA

© Alfaomega - RC Libros

declarada. Pero como ya sabes, en Java, para crear un objeto hay que invocar el constructor que se encarga de inicializarlo adecuadamente para que no existan “objetos zombis” danzando por ahí sin ser Halloween. —Entiendo… Pero, ¿qué es Halloween? —Olvida lo de Halloween. Otra causa común del NullPointerException es que al trabajar con colecciones de objetos se sobrepasa el límite de la colección y se está accediendo a una posición vacía. Eso también suele ocurrir. —Ya veo… —Creo que has dejado de escucharme —señala el señor Paradigma y razón no le falta. He introducido la “mano” en el bolsillo izquierdo para acariciar la cámara—. Pues quiero que sepas que me parece una falta de respeto para la clase NullPointerException. —¿Clase? —Sí, existe una clase llamada NullPointerException, ya que los errores de este tipo son tan objetos como tú. —Anda, ¿qué curioso?, ¿hay objetos que representan errores? —Así es. —¿Y qué atributos tienen?

104

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Bueno, hay distintos tipos de errores, por eso existen distintas clases para modelar excepciones 45, y cada una tiene los atributos propios del tipo de error; pero un atributo común en todas las excepciones es un mensaje de error. —Ya veo… ¿Para qué existen los objetos de error?, ¿cuál es su razón de ser? —La mayoría de las veces se crean excepciones para manejar situaciones incorrectas en el programa, evitando así que la ejecución del programa acabe abruptamente. Esto se conoce con el término: manejo de excepciones. Cuando un método detecta una condición anormal, crea un objeto excepción y lo lanza hacia arriba 46. Esa excepción es recogida por el método que lo llamó. Dicho método puede, a su vez, volver a lanzarla o tratar la excepción 47 . —¿Y si todo el mundo escurre el bulto? Menudo partido de pelotas... —Todos los métodos pueden lanzar la excepción siempre que lo declaren en su cabecera 48; excepto el método main 45

CloneNotSupportedException,IOException,FileNotFoundException, EmptyStackException, etc. 46

throw new Exception(“Mensaje de error”); /* o por ejemplo: */ throw new FileNotFoundException(“no hay ningún fichero con ese nombre”); 47 try{...código que puede lanzar una excepción...} catch(Exception e) {...código para tratar la excepción recogida en la variable e...} 48 public void metodoX(...)throws Exception {...cuerpo del métodoX, el cual contiene una sentencia throw o llama a un método que en su cabecera ha declarado throws Exception...}

105

NURIA MEDINA

© Alfaomega - RC Libros

que es el método principal del programa y, por tanto, no es invocado desde ningún otro sitio. —Ya veo... —remato sin ganas, ha dejado de interesarme el tema a medida que se lanzaban los balones fuera. —Tercer ya veo. Me voy —anuncia el maestro, algo molesto, y se pira sin decir adiós. Me quedo solo y entonces, como si tal cosa, ocurre algo grandioso. Me llega un mensaje: addAsignaturaMatricula(unaAsignatura)49. No sé de dónde procede, pero lo ejecuto a las mil maravillas, tal y como está codificado en mis “genes”. Qué subidón. Sonrío de “oreja” a “oreja” cuando el señor Paradigma reaparece. —Maestro, ¡he respondido a una petición! —exclamo eufórico. —Ya lo sé, por eso me marché sin despedirme —justifica. —¿Lo ha visto? —Claro, soy omnipresente. —¿Lo hice bien? —De maravilla —confirma—. No podía ser de otro modo. —¿Vio quién me envió el mensaje?

49

var.addAsignaturaMatricula(unaAsignatura);

106

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Sí, claro, soy omnipotente. —¿Quién fue? —No te diré quién fue, no soy un chivato —sonríe pícaro—, pero te explicaré quién puede ser. —¿Quién puede ser? —Sí, te voy a hablar de los canales de comunicación entre objetos. —Adelante —propongo—, me conformaré con el botón de muestra. Y el señor Paradigma se explaya, con un rollo como no se marcaba hacía tiempo. Yo, como he aprendido a hacer en estas situaciones, configuro una mueca de interés perenne, me llevo una “mano” a la “barbilla” y asiento periódicamente; mientras, a la más mínima oportunidad, trasteo la cámara fotográfica bajo la tela del pantalón. Su tacto me hipnotiza, y el contraste entre el aluminio de la carcasa y el cristal líquido de la pantalla, me invita a rodar las “yemas” de una parte a otra del aparato sin tener el cuidado prometido. Pese al manoseo, la explicación del maestro no cae en saco roto, y entiendo perfectamente los diferentes canales de comunicación. El primero, el más fuerte, es el canal <> que permite a cualquier objeto enviarle mensajes a sus atributos (solo a los atributos que sean objetos, no a valores primitivos, como es evidente). Gracias a ello, yo mismo podría ser el objeto emisor de un mensaje que pudiera enviar a mi atributo fechaNacimiento,

107

NURIA MEDINA

© Alfaomega - RC Libros

convertido en objeto receptor, para que me devolviese mi año de nacimiento 50. Otro es el canal <<self>> que permite a un objeto enviarse un mensaje a sí mismo51 , convirtiéndose en emisor y receptor de dicha petición. Aunque, como ha insistido el profesor, más utilizado es el canal <<parameter>> que permite a un objeto enviar un mensaje a cualquier otro

50

public class EstudianteGradoInformatica{ ... GregorianCalendar fechaNacimiento; /* variable de instancia */ ... public int calculaEdad(){ ... int year = fechaNacimiento.get(Calendar.YEAR); /* el objeto emisor de get (Calendar.YEAR) es un objeto de la clase EstudianteGradoInformatica y su atributo fechaNacimiento es el objeto receptor */ ... } ... } 51 public class EstudianteGradoInformatica{ ... public void unMetodo(){ ... int edad = this.calculaEdad(); /* this es una pseudovariable que representa al objeto receptor del mensaje unMetodo(). Dicho objeto pertenece a la clase EstudianteGradoInformatica y es, a su vez, el emisor y receptor de calculaEdad(). Equivalente habría sido poner únicamente calculaEdad(); (sin receptor explícito se sobreentiende el receptor del mensaje actual)*/ ... } ... }

108

© Alfaomega - RC Libros

JAVA. LA NOVELA

objeto pasado como argumento en uno de sus métodos 52. Y, finalmente, el canal <> que es el más flexible, pues permite enviar un mensaje a cualquier objeto obtenido localmente en uno de los métodos del objeto emisor 53. —Vamos, que cualquiera puede enviarme un mensaje —meto la cuchara en cuanto el señor Paradigma termina su perorata. 52

public class EstudianteGradoInformatica{ GregorianCalendar fechaNacimiento; ... public void otroMetodo(GregorianCalendar otraFecha){ ... if (otraFecha.before(fechaNacimiento)){...} /* el emisor de before es un objeto de la clase EstudianteGradoInformatica y el receptor es el argumento del método otroMetodo */ ... } ... } 53 public class EstudianteGradoInformatica{ GregorianCalendar fechaNacimiento; ... public void imprimeFecha(){ ... String fecha = fechaNacimiento.toString(); String fechaFelicitacion = fecha.concat(“happy birthday”); /* el emisor de concat es un objeto de la clase EstudianteGradoInformatica y fecha, el objeto receptor, es una variable local del método imprimeFecha */ ... } ... }

109

NURIA MEDINA

© Alfaomega - RC Libros

—Cualquiera, cualquiera, no. Cualquiera que utilice uno de los cuatro canales de comunicación posibles, y siempre que tenga acceso al método solicitado. Recuerda que esto último depende del modificador de acceso declarado para el método y de la estructura de paquetes —recalca. —Sí, por supuesto —coincido apresuradamente para que no reinicie la clase magistral y, aprovechando el lapsus, extraigo el precioso aparato de fotografía de mi bolsillo—. Ahora, si le parece, voy a buscar el método asociado a la petición que acabo de resolver en el código fuente de mi clase. Enfrascado en tal labor, avanzo fotografías, una tras otra, sin dar con lo que espero hallar. El señor Paradigma asiste sonriente a mi infructuosa búsqueda; aparentemente, sin reparar en el soponcio que me estoy llevando, ya que no encuentro el método addAsignaturaMatricula en el cuerpo de mi clase, y eso solo puede tener una imperdonable explicación: he roto la cámara. —Maestro —sueno apenado—, tengo que confesarle algo. —Dime. —He cometido una imprudencia… —respiro para aflojar la congoja. —Continúa —exige. —He roto la cámara —asevero mientras cierro los “ojos” para no ver la que se me cae encima. —No has roto la cámara, zoquete, pero sí que no has dejado de manosearla. Hay más dedos en la pantalla que en una convención de mecanografía —me reprende burlón. 110

© Alfaomega - RC Libros

JAVA. LA NOVELA

—¿Cómo lo sabía? Espere... ¿también puede ver a través de mi ropa? —Instintivamente me cubro la “entrepierna”. —No me hacen falta rayos X para darme cuenta del meneo que te traías en el bolsillo. —Disculpe —musito avergonzado mientras descruzo las “piernas”—. Pero, de verdad, la he fastidiado. Estoy seguro. —¿Por qué estás tan seguro? —pregunta con tono de mofa. —Porque no aparece por ningún lado un método con el mismo nombre del mensaje que acabo de responder. Quizá no la he roto, quizá solo he borrado esa foto. Pulsaría un botón sin querer... —No busques la quinta pata al gato. No aparece el método addAsignaturaMatricula(Asignatura nuevaAsignatura) en la clase EstudianteGradoInformatica pero ello no se debe a ninguna catástrofe —anuncia presuntuoso—, aún te quedan muchas cosas por aprender. Ha llegado el momento de hablarte de la herencia —concluye, y me deja boquiabierto. —¿Herencia? —Herencia, el más poderoso mecanismo de reutilización de código entre clases. —¡Guau! —exclamo—. Pensaba que el mecanismo de reutilización más importante en orientación a objetos era el uso de clases. Quiero decir: la estructura de la clase (declaración de variables) y sus métodos se escriben solo una vez, en la clase, aunque luego sean usados por 1000 instanciaciones de dicha clase y cada uno de esos 1000 objetos tenga su propio estado. 111

NURIA MEDINA

© Alfaomega - RC Libros

—¿1000? —Señor Paradigma, digo 1000 por decir un número. Supongo que habrá clases con más instancias que otras. —Sí, sí, claro... Razón no te falta. El uso de clases es un mecanismo de reutilización fundamental, sobre todo cuando hay muchos objetos del mismo tipo, como es el caso de estudiantes del Grado en Informática en la UGR. Pero la herencia es reutilización a nivel de clase, no de objeto. —No entiendo el matiz. —Palmario, no te lo he explicado. Siéntate, hay muchos matices que debo enseñarte a distinguir. —Levanto la “barbilla” y me dispongo a llevarme la “mano” al “mentón” cuando, el señor Paradigma añade—: nada de fingir profuso interés, ni de asentir mientras piensas en las musarañas, que ya nos vamos conociendo... Me desarma la gesticulación y me concentro en su explicación. ¿Qué remedio queda?

112

17. Herencia El señor Paradigma sostiene un brillo especial en la mirada y es que se nota que esto de la herencia es muy importante para él. No escatima en ejemplos y luce sus mejores galas docentes durante una exposición a la que, en mi opinión, le sobran tres kilos de chorizo. El concepto es poderosamente simple, no requiere de tanta palabrería.

Ilustración 10. La clase hija reutiliza la estructura y funcionalidad definida en la clase padre y puede incorporar extensiones (atributos o métodos) o volver a definir los heredados (redefinición). 113

NURIA MEDINA

© Alfaomega - RC Libros

«La herencia es el mecanismo de reutilización por el que una clase hija hereda la estructura (o sea, la declaración de variables de instancia y variables de clase) y el comportamiento 54(métodos de instancia y métodos de clase) de una clase padre», concluye el maestro a modo de resumen. Y luego saca el escudo, porque presiente la batalla que se avecina. «¿No acepta que la clase EstudianteGradoInformatica es mi “mamá” y ahora me habla de padres e hijos?». Me parece un descaro. Desempolvo mis antiguos argumentos y la discusión renace. Pero él se mantiene en sus trece. La clase en Java es únicamente un patrón textual porque Java no es un lenguaje orientado a objetos puro 55 , es decir, hay elementos que no son objetos como pueden ser las clases, los valores primitivos o el operador new (entre otros). —Por ese motivo, la clase no es la madre de los objetos que la instancian —dictamina. —Por ese mismo motivo —recalco—, una clase no puede ser padre ni hijo de otra clase. Nos enzarzamos en una controversia que solo termina cuando el maestro levanta la voz: —Vale, aceptamos pulpo como animal de compañía. Tú ganas: la clase es tu “mamá”, metafóricamente hablando. Aunque en el paradigma de programación orientado a objetos ese término no esté aceptado. Al contrario de lo que 54

Los métodos constructores no se heredan En los lenguajes orientados a objetos puros todo es un objeto (incluidas las clases). Ejemplos de este otro tipo de lenguajes son Smalltalk y Ruby 55

114

© Alfaomega - RC Libros

JAVA. LA NOVELA

ocurre con la herencia, donde se suele llamar clase padre a la clase base que se reutiliza para crear la clase derivada, comúnmente denominada clase hija. Está rojo como un tomate y resopla. Pobrecito, que a “pecho” se lo toma todo. —Tranquilo, maestro, si es una cuestión de terminología no se hable más. Usted tiene razón —cedo, y le propino unas palmaditas en la “espalda”—. Prosiga con su explicación. El señor Paradigma respira hondamente para recobrar el aliento y continúa más calmado. Para compensar su embarazosa subida de tono, ahora habla tan bajito que me cuesta trabajo seguirlo. Pero no me preocupo. Repite muchas cosas de las que ya me contó, e incide en que la clase hija tiene definidos automáticamente todos los atributos y métodos declarados en la clase padre sin necesidad de volver a escribirlos. Se vuelve especialmente pesado cuando enfatiza que la clase hija puede añadir nuevos atributos y métodos, o redefinir los heredados. Todo eso ya lo había dicho. La clase hija es una extensión de la clase padre. —¿Qué significa redefinir? —pregunto para constatar que es lo que me imagino. —Redefinición de métodos, como su propio nombre indica, consiste en volver a definir los métodos. Es decir, si la clase hija no está de acuerdo en cómo está implementado uno de los métodos que ha heredado de su clase padre puede escribir un método con igual cabecera pero distinto cuerpo. Vamos, que se puede cambiar la implementación de un método heredado en la subclase. —¿Subclase? 115

NURIA MEDINA

© Alfaomega - RC Libros

—Otra forma de nombrar a la clase hija es con el término subclase. —En ese caso —supongo—, la clase padre se llamará superclase. —Sí, pero no fantasees con que es un superhéroe, ni nada parecido —previene el señor Paradigma y reanuda su instrucción—: cuando se redefine un método en la clase hija conviene colocar una declaración @Override delante de la cabecera del método redefinido. —¿Para qué? —Principalmente por claridad. El código debe ser legible. Además, así el compilador controlará que la redefinición sea correcta. —Vale, vale —acepto y pregunto—: para que una redefinición sea correcta, ¿la cabecera del método sobrescrito debe ser igual a la cabecera original, verdad? —El método redefinido debe tener el mismo nombre y el mismo número y tipo de parámetros (en el mismo orden aunque el nombre de los parámetros puede variar). Respecto al modificador de acceso, este puede cambiar siempre que la redefinición de visibilidad sea menos restrictiva. Es decir, si el método está declarado como public en la superclase no se puede redefinir como protected en la subclase, pero si es protected en la clase padre sí se podría redefinir como public en la clase hija. —¿Protected? —Protected es un modificador de acceso, ¿recuerdas? No llegué a explicártelo porque aún no conocías la herencia 116

© Alfaomega - RC Libros

JAVA. LA NOVELA

entre clases, pero dicho modificador denota que el método o la variable así declarada puede ser accedida desde la propia clase, desde otras clases del mismo paquete y desde las subclases de la clase actual, independientemente del paquete en el que se encuentren. —Ya veo... protected es más abierto que package, pero menos que public.

Ilustración 11. Un atributo o un método declarado en una clase como protected puede ser accedido de forma directa desde determinadas clases que quedan fuera del paquete de la clase actual, siempre y cuando dichas clases hereden de ella. Por el contrario, por defecto (package), la visibilidad se limita a las clases del mismo paquete.

—Yes, aunque el nombre pueda despistar, protected ofrece menos encapsulamiento que package —asiente para cambiar de tema en redondo y nunca mejor dicho—: por cierto, ¿crees que estoy gordo? No contesto, no respiro, no me muevo... esta pregunta tiene trampa, seguro. 117

NURIA MEDINA

© Alfaomega - RC Libros

—Espera... —recompone la frase— le daré la entonación adecuada, no es una pregunta, es una afirmación: crees que estoy gordo. —¿Yes? —musito algo acobardado, rindiéndome ante la evidencia. —¿Debería hacer ejercicio? Digo: debería hacer ejercicio. —Podría ser saludable —respondo, parco en palabras. La conversación me tiene mosca. —Mens sana in corpore sano —afirma mientras calienta “tobillos”—. Aguarda aquí, ahora vuelvo —solicita y sale corriendo. Qué insecto le habrá picado. Me ilusiono pensando que me va a llegar un nuevo mensaje, pero parece que en esta ocasión, esa no ha sido la causa de su repentina marcha. Para no aburrirme, saco la cámara fotográfica y me dispongo a rastrear cualquier viso de herencia en el código Java de mi clase. Empiezo por el principio, y voy leyendo líneas, despacito y con buena letra, hasta encontrar la pista que buscaba. Ahí andaba, en la misma cabecera 56, después del nombre de mi clase. Se iluminan dos palabras que antes había pasado por alto: extends EstudianteGrado. Sin duda, eso debe significar que la clase padre de EstudianteGradoInformatica es la clase EstudianteGrado. O sea, EstudianteGradoInformatica extiende a EstudianteGrado. Buceo entre las fotografías tomadas, en busca de mi “abuelito” y rezo para que el señor Paradigma no esté 56

public EstudianteGradoInformatica extends EstudianteGrado {... cuerpo de la clase...}

118

© Alfaomega - RC Libros

JAVA. LA NOVELA

escuchando mis pensamientos. Le daría un bitango si me oyera hablar de abuelos. Me río. Y tras la algazara, llega al visor la foto de la clase EstudianteGrado. Hay varias instantáneas, pero en ninguna de ellas encuentro el método perdido. «¿Tendría yo razón y he estropeado el reportaje gráfico?». No creo, el maestro parecía muy seguro y con lo sieso que es, si hubiese existido la más mínima posibilidad de que hubiese metido la pata no habría escatimado en restregármelo. Algo falla, voy a seguir investigando. —¡Aquí está el quid de la cuestión! —exclamo cuando reparo en que en la cabecera de EstudianteGrado 57 también está presente la palabra extends. En este caso, la superclase de EstudianteGrado es EstudianteUGR—. ¡Toma ya!, la herencia es transitiva, como la suma. Alentado por la emoción, localizo las fotografías de la clase EstudianteUGR en un periquete, mi bisabuelo («un placer conocerlo»), y eureka: en el cuerpo de la clase aparece el método addAsignaturaMatricula(Asignatura nuevaAsignatura)58. Escudriño la implementación encerrada entre llaves y coincide fielmente con los pasos que ejecuté para resolver la petición: introducir la nueva asignatura (pasada como argumento) en un atributo de tipo colección llamado matricula.

57

public EstudianteGrado extends EstudianteUGR {...cuerpo de la clase...} 58 public void addAsignaturaMatricula(Asignatura nuevaAsignatura){ matricula.add(nuevaAsignatura); }

119

NURIA MEDINA

© Alfaomega - RC Libros

Este atributo, matricula, forma parte de mi estado pero está declarado en la clase EstudianteUGR59 , lo que significa que también ha sido heredado por mi clase (a través de la clase EstudianteGrado que hereda de EstudianteUGR). El señor Paradigma no exageraba, esto de la herencia es fascinante. «Mira, hablando de Roma, por ahí viene. Pero ¿qué hace?». No camina, se aproxima dando saltos, “rodillas” al “pecho”, “talones” al “culete”. Detiene la carrera continua y se hace unas flexiones y unas abdominales. Se incorpora y continúa saltando, abre “piernas”, “brazos” en cruz, toca techo, toca suelo… «¿Se habrá desquiciado?». —¿Qué miras muchacho? —pregunta cuando se detiene frente a mí, trotando en el sitio—. ¿Se te ha desencajado la “mandíbula”? No es para menos. No se le ha perdido ningún “quicio”, sino que se ha echado encima unos cuantos y regresa convertido en un nuevo “Arnol Suarseneguer” paradigmático. Madre mía, está enorme, pero no a lo redondo, sino a lo cuadrado. Se ha colocado una camiseta de tirantes roja y los “músculos” le sobresalen por doquier. Está bronceado y tiene los “bíceps” más torneados que he visto. ¿Qué digo bíceps?: “deltoides”, “bíceps”, “tríceps”, “romboides”… Y eso que casi no me atrevo a mirarle las “piernas”. ¡Qué “muslamen” le marcan esos pantaloncitos cortos! Duele la vista. —Habla muchacho, ¿te ha comido la “lengua” el gato? —pregunta sonriente, mientras estira el “psoas ilíaco”. 59

private List matricula;

120

© Alfaomega - RC Libros

JAVA. LA NOVELA

—¿Cómo se ha puesto usted así? Yo también quiero —exteriorizo mi mezcla de sorpresa y envidia. —El sacrificio es la clave del éxito —asegura. —Pero si ha desaparecido solo un momento… —Un momento, un año, un siglo, un suspiro… El tiempo no es más que un artificio para justificar los cambios —afirma filosófico, dejándome claro que ha cambiado por fuera, pero no por dentro—. Aunque, por lo que veo, aquí también han ocurrido cambios significativos. Has averiguado por tu cuenta cómo se implementa la herencia en Java. —Sí —admito complacido—. Es muy sencillo. —Claro que sí, la mayoría de las ideas revolucionarias son magistralmente sencillas. Qué musculitos tan transcendental... No sé si podré soportar otra parrafada así, pero… ¡cómo para llevarle la contraria ahora! Menudo sopapo me podría meter. —Muchacho, sigo siendo el mismo. Recuerda que nuestros atributos no definen nuestra esencia. —No, claro. Pero sí imprimen fuerza al golpe —bromeo, atrevido. —Déjalo ya, no voy a darte —formula cual macarra—. Vamos a seguir hablando de la herencia, si te parece. —Sí, claro. Tengo algunas preguntas. —Dispara.

121

NURIA MEDINA

© Alfaomega - RC Libros

—Vale, disparo, pero por favor termine ya con los estiramientos. Me desconcentra. —Perdón, soy todo “oídos” —dice, aunque sus “orejas” son minúsculas en relación con su robusto “cuello”, plagado de “venas” henchidas. —¿Una clase puede heredar de varias superclases? —No, en Java la herencia entre clases es simple, lo que significa que una clase hija solo puede tener una clase padre. Esto es así para eliminar los problemas de ambigüedad y repetición que surgen si se trabaja con herencia múltiple. —¿Repetición? ¿Ambigüedad? —Cuando una clase hija hereda de varias clases, puede que existan en esas clases padre atributos o métodos que coincidan en nombre y que, para “fastidiar”, tengan definiciones diferentes. —Vaya conflicto —suspiro. —Sí, pero no te preocupes, en Java no existe ese problema, la herencia es simple. Cada subclase tiene una única superclase. —Ya… —añado pensativo, escrutando una foto que ha llamado mi atención—, pero acabo de encontrar una clase que no tiene ningún extends en la cabecera. Entonces, ¿esa clase no hereda de ninguna otra?, ¿se ha creado desde cero? —No. —¿No?, ¿de quién hereda entonces? 122

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Si no se dice nada sobre la herencia en la cabecera de una clase, esa clase hereda de Object. Object es una clase que recoge características comunes a cualquier objeto, y por eso es la raíz de la jerarquía de herencia. —Me cuesta trabajo creerlo. —Déjame demostrártelo —dice mientras que arranca la cámara de las “manos” como quien quita un caramelo a un infante—, echa un vistazo a esta clase de acá, la que no tiene extends, hay un método llamado clone(). ¿Lo ves? —Sí, claro, no estoy ciego. —Fíjate que tiene la cláusula @Override delante. Eso significa que el método clone() está redefinido y eso es porque dicho método está implementado en Object. Aunque no se diga nada, se está heredando de Object. —Anda, pues es verdad. Además, en la clase EstudianteGradoInformatica pasa lo mismo, aparece el método clone() con un @Override delante de la cabecera. Eso es porque la herencia es transitiva, con lo cual, mi clase también acaba heredando de Object. Pero, ya puestos, ¿para qué sirve ese método? —El método clone() hace una copia del objeto receptor. Es muy útil para facilitar la creación de nuevos objetos iguales o muy similares a otros existentes. También para proteger la privacidad de los atributos de un objeto. —¿Cómo se conseguía esto último?

123

NURIA MEDINA

© Alfaomega - RC Libros

—Muy fácil, en el consultor no se devuelve el atributo sino una copia del mismo 60, así no lo podrán alterar desde fuera. —Recordaba que me dijo que para asegurar al 100% el encapsulamiento había que devolver copias de los atributos. Esa copia se puede hacer con el clone() o usando el constructor por copia 61 si existe, ¿verdad? —Efectivamente, muchacho. Lo has comprendido y esto era para nota —admite satisfecho—. Pero, ten en cuenta que la vida es equilibrio, a veces puede ser más adecuado asumir cierto riesgo en la seguridad del encapsulamiento y evitar tener muchas copias de determinados objetos. Y, por otro lado, cuando los atributos no representan características intrínsecas al objeto sino relaciones con otros objetos puede ser interesante devolver el objeto original 62 y no una copia. Me he ido. ¿Soy yo o también se ha hecho un blanqueamiento dental? Paso página: —Otra duda, señor Paradigma —no voy a preguntarle por la blancura de sus “dientes”, descuide—: ¿por qué el método clone() redefinido en mi clase declara en la cabecera que 60

public Profesor getTutorTrabajoFinGrado() { return tutorTFG.clone();} /* tutorTFG es un atributo de EstudianteGrado y un objeto de la clase Profesor */ 61 public Profesor getTutorTrabajoFinGrado() { return new Profesor(tutorTFG);} 62

public Profesor getTutorTrabajoFinGrado(){return tutorTFG;} /* El tutor del estudiante, atributo tutorTFG, se devuelve por valor (en Java todo se devuelve por valor). Como es un puntero, lo que se copia es la dirección de memoria (valor), dando acceso directo al objeto original tutorTFG almacenado en el heap */

124

© Alfaomega - RC Libros

JAVA. LA NOVELA

devuelve un Object y no un EstudianteGradoInformatica? Ahí se ha metido la gamba. —No, está correcto. Deja a las gambas que naden tranquilas en el océano. El método está declarado originalmente en la clase Object con esa cabecera y con esa misma cabecera se tiene que redefinir 63, si se cambiase el tipo devuelto ya sería otro método diferente. Y eso no sería redefinición, sino sobrecarga. —Me estoy agobiando, no lo entiendo. Por favor, explíqueme la diferencia entre redefinición y sobrecarga. —La sobrecarga de un método ocurre cuando en una misma clase se definen varios métodos con el mismo nombre, pero distinto número y/o tipo de argumentos 64. Al sobrecargar un método se puede cambiar también el tipo del valor devuelto; y en dicho mecanismo no interviene la herencia. —Respira—. En cambio, la redefinición implica que se vuelve a definir el mismo método, no otro, que se ha heredado. Por esto, como te dije antes, al redefinir el método clone() lo más que puedes cambiar en la cabecera es el protected original por el modificador de acceso public que es más flexible, pero nada más.

63

protected Object clone() /* Cabecera del método en Object */ 64 public int suma(int n1, int n2){...} //y public float suma(float f1, float f2){...} //y public int suma(int n1, int n2, int n3){...} /* son sobrecargas del método suma */

125

NURIA MEDINA

© Alfaomega - RC Libros

—De acuerdo, aceptamos pulpo... —concedo, copiándole la frase— pero ¿cómo es posible que si en la cabecera se dice que se devuelve un Object luego se devuelva un objeto de la clase EstudianteGradoInformatica65 ? ¿Quién miente? —No miente nadie, eso es perfectamente válido debido a la regla de compatibilidad de tipos que se utiliza en orientación a objetos. —¿Regla de compatibilidad de tipos? —La regla de compatibilidad de tipos en orientación a objetos establece que cuando una variable es declarada de una clase determinada, dentro de dicha variable podemos introducir cualquier objeto de esa clase o de cualquiera de sus subclases. Por lo tanto, como Object es la raíz de la jerarquía de herencia... —... dentro de una variable declarada de tipo Object puede meterse un objeto de cualquier clase —termino la frase—. ¡Soberbio!

65

@Override

protected Object clone() { return new EstudianteGradoInformatica(new String(nombre),..., matricula.clone(),...); /* se crea un nuevo estudiante con una copia de cada atributo del estudiante receptor del mensaje de clonación */ }

126

© Alfaomega - RC Libros

JAVA. LA NOVELA

Ilustración 12. Una variable declarada de tipo Object es como un saco flexible donde se puede meter cualquier cosa.

—Sí, la herencia es muy generosa. Si una variable puede alojar a un EstudianteUGR, también podrá alojar a un EstudianteGrado y a un EstudianteGradoInformatica, porque un EstudianteGradoInformatica es un EstudianteGrado y un EstudianteGrado es un EstudianteUGR. —Parece un trabalenguas. —No, cuando le pillas el truco fluye solo. Si alguna vez tienes duda sobre si compete una relación de herencia entre dos clases, utiliza las dos palabras: “es un” (subclase es un superclase) y comprueba si la frase tiene sentido. Y ahora, si me disculpas, voy a tomarme un batido energético porque de tanto hablar de pulpos y gambas me ha entrado hambre. —¿Hambre? ¿Qué es eso? —Olvídalo —barbulla mientras bebe—, prosigamos. ¿Tienes más dudas o puedo continuar con mi entrenamiento? —Solo una cosa más. Mire aquí, este método —le pido, al tiempo que le muestro la fotografía del método con expresión de perplejidad. —¿Qué le ocurre al método? 127

NURIA MEDINA

© Alfaomega - RC Libros

—Es un método de mi clase y, sin embargo, no accede directamente al valor de mi atributo matricula, sino que utiliza el método consultor para obtenerlo. ¿Para conocer mi propio atributo es lógico usar un consultor? —En este caso es obligado hacerlo así. El atributo matricula es un atributo heredado y fue definido originalmente en EstudianteUGR como private: solo en el código de la clase EstudianteUGR puede usarse directamente. En tu clase, EstudianteGradoInformatica, dicho atributo está disponible gracias a la herencia, pero es necesario emplear el método getMatricula(), también heredado, para conocer su valor y el método setMatricula(Matricula nuevaMatricula) para modificarlo. Ambos métodos son públicos, por supuesto. —Fíjate, qué curioso, el private es privado a más no poder. —Sí —ríe enérgico y, sin venir a cuento, añade—: La vita è bella. Luego, se marcha trotando, aunque se detiene a intervalos regulares para hacer flexiones o para seguir moldeando su “tableta de chocolate” con una prolífera serie de abdominales.

128

18. El árbol genealógico Me he vuelto un auténtico cotilla, tengo que reconocerlo. Llevo horas estudiando el código fuente de las clases que emparentan con EstudianteGradoInformatica y me regodeo cada vez que las sentencias de sus métodos me transmiten algún chismorreo. Me da cierto reparo admitirlo, pero qué carajo, en los días de lluvia es lo que pega y hoy llueve a cántaros. La tormenta viene del más allá, aunque eso no impide que escuche el tintineo de las gotas que impactan contra el cristal y que la humedad cale mis “huesos”, auditivamente hablando. Como estoy inusualmente sensible a los sonidos que se producen fuera de la carcasa, los truenos me están provocando una jaqueca terrible. Pero no voy a pedir remedio ni ungüentos al señor Paradigma. Esta magnificada capacidad extrasensorial no puede significar nada bueno. Suena a luz al final del túnel. —Chico, ¿otra vez pensando en la muerte? —Me sorprende el señor Paradigma que reaparece saltando a la comba al estilo Rocky Marciano. Según él, se ha fabricado la cuerda con un cablecito que andaba suelto por ahí. Miedo me da… —No se preocupe, ya la miro con otros “ojos”. —Pues no la mires tanto, que eres un bisoño y lo que tienes que hacer es aprender de la vida y disfrutar.

129

NURIA MEDINA

© Alfaomega - RC Libros

—Usted sí que está rejuveneciendo, y deje de saltar que le tiembla la voz y apenas le entiendo. ¿Por qué iba a disfrutar yo explotando una mina? El maestro me hace el gusto y guarda la comba, muerto de risa. —Olvide lo de la mina, quiero contarle un chisme. —No me interesan las miserias ajenas, pero cuenta, cuenta... —responde mal disimulando su curiosidad. —He encontrado un método que calcula el sueldo de los profesores. —Anda, mira tú, menudo cotilleo más insustancial —arguye. —Pues yo creo que tiene su morbo —replico colorado—, sobre todo porque hay una cosa muy extraña en el código. Seguro que es un asunto espinoso. —¿Qué dices?, ¿espinas...?, ¡serán minas...! —No sea mordaz —solicito—, se trata de una palabra que no sé lo que quiere decir. —Será el nombre de una variable. —No puede ser una variable porque no está declarada por ningún lado, ni se introduce como argumento en el método. —No des más rodeos y dime de qué palabra se trata.

130

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Empieza por la letrita “s” —contesto con zumba, sin hacer aprecio a las malas experiencias previas con el “veo, veo”. —¿super? —Vaya, me estaba espiando... —Qué va, chico, ahora tengo que entrenar, ¿recuerdas? —asegura mientras se acaricia el “torso”, aceitoso como un pescado de freidora—. He estado levantando pesas de 50 kilos. No le pregunto con qué ha fabricado las pesas. No tiene más remedio que ser un farol. —Me he imaginado que sería super porque comienza por “s” y, la verdad, es lo primero que se me ha venido a la mente. —Vale, vale, no se justifique más. Explíqueme qué es super. —super es una pseudovariable, al igual que this. —¿Pseudovariable? —Se usa el término pseudovariable porque su valor no es constante, pero tampoco puede ser un valor cualquiera. Cuando en un método aparece la palabra reservada this está haciendo alusión al objeto receptor de dicho mensaje. Y, como estarás comprendiendo, el objeto receptor varía en función de quién ha recibido la petición. —¿Y super?

131

NURIA MEDINA

© Alfaomega - RC Libros

—Cuando la palabra reservada super aparece en el cuerpo de un método se puede sustituir por el objeto receptor del mensaje. —Ha dicho dos veces lo mismo —impugno. —Ya, this y super referencian al mismo objeto, el objeto receptor del método actual —afirma complacido, no hay otra cosa que le guste más en el mundo que llevar la razón. —Venga, desembuche, ¿cuál es, entonces, la diferencia? —La diferencia radica en que cuando se usa super, el mensaje que se le envía al objeto receptor (denominado con super) será resuelto usando el correspondiente método de la superclase, no el de la clase actual (aunque se haya redefinido dicho método en la subclase). —A ver si me clarifico, el método calculaSueldo() de la clase Profesor devuelve $$$$ euros —desvelo mientras las “pupilas” me hacen chiribitas—, pero ha sido redefinido en la clase ProfesorFuncionario de la siguiente manera 66 : super.calculaSueldo()+this.calculaComplementos(); —hago una pausa para hipar, no es fácil leer código de corrido. Y para no perderme, me centro en preguntar lo que realmente 66

public class ProfesorFuncionario extends Profesor{ ... @Override

public float calculaSueldo(){ return super.calculaSueldo()+this.calculaComplementos(); } ... }

132

© Alfaomega - RC Libros

JAVA. LA NOVELA

quiero saber—: ¿cuánto gana un profesor funcionario? —De momento, el this y el super me traen sin cuidado. —Eres muy indiscreto —me regaña—, pero para satisfacer tus ansias de fisgoneo no te quedará otra que entender las pseudovariables porque yo no te pienso responder en euros. Así que presta atención —exige notablemente disgustado—: en este caso, super y this hacen referencia al mismo objeto de la clase ProfesorFuncionario (el que recibió la petición calculaSueldo()). Pero —pausa ampulosa—, el método calculaSueldo() que se ejecuta con super no se busca en la clase ProfesorFuncionario, sino arriba, en la clase Profesor de quien hereda ProfesorFuncionario. Mientras que —otra pausa— el código del método calculaComplementos se busca en la propia clase ProfesorFuncionario. —Ya entiendo —confirmo, mientras hecho cuentas—. Un profesor funcionario cobra lo mismo que cualquier profesor ($$$$ que devuelve el método calculaSueldo() de Profesor) más unos complementos de funcionariado (que devuelve calculaComplementos() de ProfesorFuncionario). —Deja los salarios tranquilos y testifica: comprendido la diferencia entre this y super?

¿has

—Sí, lo juro —afirmo con mis inexistentes “manos” sobre la inexistente Biblia— aunque no veo la diferencia entre poner this.calculaComplementos() y poner, a secas, calculaComplementos(). Aunque está claro que hay una diferencia y usted se encargará de restregármela por la… —No hay diferencia —me interrumpe.

133

NURIA MEDINA

© Alfaomega - RC Libros

—Entonces, ¿para qué se usa this? No le veo el gusto —confieso contrariado. —Normalmente se usa la pseudovarible this para resolver la ambigüedad cuando al inicializar un atributo, la variable que contiene el valor a establecer tiene el mismo nombre que el propio atributo 67. En estos casos, el atributo se nombra como this.nombreAtributo. —Ajá, ya le voy encontrando la gracia. Aunque casi prefiero cambiarle el nombre al argumento y listo.

67

public class ProfesorFuncionario extends Profesor{ ... private float complementoDocencia; ... public setComplemento(float complementoDocencia){

this.complementoDocencia = complementoDocencia; /* el primero hace referencia al atributo y el segundo al argumento del método */ } ... }

134

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Como gustos, colores. Por cierto, casi se me olvidaba comentarte que super() se suele usar en los constructores de las subclases para invocar al constructor de la superclase con el fin de inicializar los atributos heredados 68. —Muy inteligente, así se reutiliza la inicialización especificada en el constructor de la superclase, aunque no se herede. Pero, entonces, ¿solo se inicializan los atributos heredados? —No seas burro. Por supuesto que no. Después de inicializar los atributos heredados con super(...) se inicializan los atributos que se han añadido nuevos en la subclase como de costumbre. —Perfectamente claro —musito y me siento. 68

public class ProfesorFuncionario extends Profesor{ ... private float complementoDocencia;

private float complementoInvestigacion; ... public ProfesorFuncionario(String nombre, GregorianCalendar fechaNacimiento,..., float complementoDocencia, float complementoInvestigacion,...){ super(nombre, fechaNacimiento, ...);/* con el constructor de Profesor se inicializan todos los atributos heredados de Profesor y luego se inicializan los atributos nuevos: */ this.complementoDocencia = complementoDocencia; this.complementoInvestigacion = complementoInvestigacion; ... } ... }

135

NURIA MEDINA

© Alfaomega - RC Libros

Sigue lloviendo afuera y empiezo a estar empapado, de humedad auditiva y de pseudovariables. Para colmo de males, la lluvia me pone nostálgico. Me acurruco y le pido al señor Paradigma que me deje solo. La morriña me recoge y el maestro se va encantado, tiene prisa por seguir entrenando. Creo que se está obsesionando con sus “músculos”. Pero me ha venido bien que se marchase sin rechistar. En días como este es cuando más echo en falta el calor de una madre y el maestro se empeña en que EstudianteGradoInformatica no es mi “mamá”. Me pone muy triste esa cabezonería suya, y que solo me haya dicho: «aceptamos pulpo» por callarme la “boca”. Espero no estar obsesionándome. ¿Tú qué crees? Es mi madre, ¿verdad? ¿Ves?, tú sí que me comprendes. Beso las fotografías de mi clase, una por una, con devoción y dulzura. El cariño, cariño es; aunque se encierre en un microchip y se codifique en unidades. La quiero. Es así desde que la conocí, durante mi primer viaje astral, y mucho más ahora que la estoy comprendiendo. Todo lo que soy, se lo debo a ella; sangre de mi sangre, amantísima “mamá”. Rompo a llorar y las lágrimas voltean por el visor de la cámara, confundiéndose con las gotas de lluvia que entran por mis “oídos” y se escurren tras mis “párpados”. Doy gracias de que el maestro esté entretenido haciendo press de banca. Pero a ti te lo puedo contar, porque tú sí que me comprendes. Me restriego los “ojos” y me sueno los mocos. He decidido elaborar un árbol genealógico. Tendrá frondosas ramas y un tronco corpulento, de corteza lisa, como la del baobab. No 136

© Alfaomega - RC Libros

JAVA. LA NOVELA

me preguntes cómo sé tanto de árboles si nunca he visto uno. No puedo responderte, estoy dibujando. Comienzo por mi madre, sigo por mi abuelo (la clase padre de mi madre), y voy subiendo hasta llegar a Object. Aquí está mi familia. Mis antepasados definen mis genes, y puedo verme reflejado en sus ramificaciones aunque no cuelgue mi fotografía de ninguna de las hojas. No puedo incluirme en el árbol porque ellos son clases y yo soy un objeto. Suspiro, primero. Gimo, después. Y, más tarde, arranco a lloriquear. ¿Tendrá razón el maestro? —Venga chico, anímate, que estás muy ñoño. —Ha vuelto a darme un sobresalto —reconvengo mientras recojo el dibujo del árbol genealógico que se me ha escapado de las “manos”—. ¿No puede acostumbrarse a llamar? —En la memoria RAM no hay puertas ni timbres. ¿Qué te pasa? —Bueno, por lo menos salude —protesto. —Anda, ven aquí —dice mientras me rodea entre sus animosos “brazos”—, vamos a echarle un vistazo a la jerarquía de herencia de Java, al completo, así podrás contemplar un árbol selvático. —¿Tan magnánimo es? —pregunto al tiempo que separo un poco su “brazote” de mi “tórax”, la presión me estaba asfixiando. —Ya lo creo, en Java existen muchos paquetes de clases predefinidas. Y luego están las clases propias de cada programa que pueden agruparse en uno o varios paquetes. 137

NURIA MEDINA

© Alfaomega - RC Libros

—Sonríe—. Mira —dice mientras que enseña un impenetrable entramado de clases que cuelgan de Object—, no cabe ni un alfiler. —Es precioso. —Bello, diríase —coincide el señor Paradigma con “ojillos” de ensoñación. —Sí, belleza es la palabra, belleza salvaje. Salvaje porque el número de clases es bárbaro y, además, el árbol está desequilibrado. Hay algunas clases que tienen muchas clases hijas y otras de las que no hereda nadie. ¿Es normal? —Claro, de hecho habrá algunas clases que no podrán ser extendidas nunca. —¿Cómo? —Las clases declaradas como final no pueden reutilizarse mediante la herencia. Esto pasa por ejemplo con la clase String69 . ¿Ves que String es un nodo hoja de la jerarquía de herencia? —Lo veo. ¡Mire! —exclamo—, en esta otra clase aparece un método declarado como final70 . —El modificador final puede aplicarse en la cabecera de la clase y también en la cabecera de un método. En este segundo caso, ¿adivinas lo que significa?

69 70

public final class String {...} public final void metodoFinal(...){...}

138

© Alfaomega - RC Libros

JAVA. LA NOVELA

—A ver... —murmuro mientras me chupo el “dedo”, me ayuda a pensar—: ¿que ese método no se puede redefinir en las clases hijas? —respondo con una pregunta. —Eres un genio —proclama y me propina un sonoro beso en la “frente”—. Un método declarado como final no puede volverse a escribir en las clases que hereden de la clase actual. —¿El modificador final también puede aplicarse a las variables de instancia? —Sí, por supuesto, el modificador final es válido para variables de clase y de instancia; y significa que una vez inicializado el atributo su valor permanecerá inmutable 71. —Como si fueran constantes, en lugar de variables. Está bien; cambiemos de tema antes de que caiga en la cuenta de que esto ya me lo había explicado —digo en alto, total, lo mismo da—. Fíjese en esta otra clase —le pido mientras señalo la clase AbstractAction—. Tiene muchísimas subclases. —Sí, además coincide que es una clase abstracta 72, lo que significa que ha nacido para ser extendida. —¿Perdón?, me he perdido. —Pues encuéntrate —responde cortante, en línea con su bipolaridad. 71

private final int atributoFinal = 10; /* atributoFinal siempre valdrá 10 */ 72 public abstract class AbstractAction {...} /* aclaración: la clase no tiene que llevar la palabra Abstract en el nombre */

139

NURIA MEDINA

© Alfaomega - RC Libros

—¿Significa que ha sido creada para crear subclases a partir de ella? —aventuro. —Sí. —Pero ¿por qué? —Vale, esto no es tan intuitivo. Te ayudaré a encontrar el camino. Una clase abstracta no puede ser instanciada. No se puede crear ni un solo objeto de una clase abstracta. —¿Para qué sirve una clase de la que no se pueden crear objetos? —consulto extrañado. —Para crear subclases —afirma contundente—. Estás más “espeso” que unas natillas. Lo acabamos de decir. —Ya, lo sé. Pero... ¿por qué crear una clase abstracta y no directamente las subclases concretas? —Porque en la clase abstracta se introduce la estructura y el comportamiento común a todas sus subclases concretas y luego cada subclase añade o redefine lo que considere oportuno. ¿Reutilización?, ¿te suena? —Ya está bien, señor Paradigma, no me trate como a un tonto —le recrimino ofendido ante lo borde que se estaba poniendo. —Disculpa, Juan, es que saber reutilizar código es muy importante, no solo por ahorrar esfuerzo sino para ganar en fiabilidad, el código reutilizado suele estar mejor depurado. —Me ha llamado Juan, hacía tiempo que no me llamaba por mi nombre. —¿Estará cogiéndome cariño? Ahora su 140

© Alfaomega - RC Libros

JAVA. LA NOVELA

mirada tiene una pose paternal. ¿Estaré yo cogiéndole cariño? Quita, quita. Con lo sieso que es. —Si no te gusta que te llame Juan, me lo dices —me indica afectuoso. ¿A quién quiero engañar? Le estoy cogiendo muuuuuuuuuuucho cariño, con bipolaridad incluida. —Da igual, sigamos —sugiero sin revelarle mis pensamientos. ¡Oh, no!, por la “cara” que está poniendo, ya sabe que lo aprecio. Mecachis...—. Lo he cazado —farfullo—, una clase abstracta define un comportamiento que deberá ser extendido por sus subclases, pero no se pueden crear objetos de la clase abstracta. —Para ser verdaderamente precisos, dentro del comportamiento de la clase abstracta debe existir, al menos, un método sin implementar —añade el maestro con mirada tierna. —¿Un método sin cuerpo? —Sí, para que no genere ningún error hay que colocar el modificador abstract 73 en la cabecera de cada método abstracto. Aunque debe haber como mínimo uno, pueden ser varios. —Entendido. ¿Qué pasaría si la subclase de una clase abstracta no redefine los métodos abstractos?

73

public abstract int metodoAbstracto(); /* no tiene cuerpo */

141

NURIA MEDINA

© Alfaomega - RC Libros

—Que también la subclase sería abstracta. La subclase de una clase abstracta tiene que redefinir todos los métodos abstractos para poder ser instanciada. —¡Ajá! Por mí, el coto de caza se cierra. Tengo todos los pajaritos en el bote. —¿Todos, todos? —pregunta con retintín. —Sí, todos —respondo. —Pues, aunque me alegra que sepas que te quiero como a un hijo, sácame del bote —me suelta, inesperadamente, el señor Paradigma. Lástima que, entre nosotros, la lectura de pensamientos no sea bidireccional. Si hubiese podido leer su mente, no se me habría quedado esta “cara” de bobo. Y, sobre todo, él no habría adquirido aires de sabelotodo cuando le he respondido con el pensamiento: «Yo también le quiero».

142

19. Detenido por incumplimiento de contrato Está saliendo el sol y el calor del abrazo del señor Paradigma me comienza a incomodar. «Ñoñerías, las justas», resuelvo mientras el maestro deshace con lentitud nuestro “nudo corporal”. Durante el chaparrón, el afecto que hemos desparramado se ha descompuesto en millares de trizas que la lluvia ha filtrado por los “poros” de nuestra “piel” como si fuésemos coladores; y, de aquí en adelante, el cariño que nos profesamos no debería necesitar de más demostraciones para alimentarse, la certeza, por sí sola, empacha. Trago saliva para quitarme el regusto dulzón y miro alrededor con todos los sentidos concentrados en la tarea. Está dejando de llover e imagino el astro amarillo, ahí afuera, despuntando entre los pellizcos borrascosos que salpimientan el cielo de los otros. Escuchar cómo amaina el temporal me relaja y masajea mis “oídos”. Además, aquí adentro, las motas luminosas que suelen revolotear sobre nuestras “cabezas” se han vestido de colores, configurando un arco multicolor, rojo en la parte de arriba, violeta en la parte interior. El espectro de frecuencias de luz se me antoja un collar gigante (colocado del revés) y su esplendor masajea mi halagada vista. Desde aquí, un rosario de relajación acontece: el “cuerpo” me pesa. No siento las “piernas” y mi “cerebro” se derrite...

143

NURIA MEDINA

© Alfaomega - RC Libros

—¡Muchacho, que te duermes! —exclama el señor Paradigma. —Qué puñetero es usted. Me ha cortado el relax. —Por supuesto, no es momento, aún —afirma con tono misterioso. —¿Aún? —interpelo receloso. —Vamos, pregúntame más cosas. —¿Más cosas? Ahora mismo no se me ocurre nada. Estoy cerrado por vacaciones. —¡Espabila, entonces! —exige, mientras me arrea un cogotazo. —¿Qué ocurre?, ¿por qué se enfada tanto porque tenga la mente en blanco? Es agradable desconectar de vez en cuando. —Vamos al tajo —formula con una resolución que me sigue mosqueando—. Mira aquí —dice mientras rebusca entre las fotografías de la cámara—, el atributo matricula, su declaración, seguro que deseas preguntarme algo sobre esto. —La verdad es que no. Ya sé que es un atributo declarado en la clase EstudianteUGR y que mi clase lo ha heredado a través de dos generaciones. También sé que está declarado como private y, que por lo tanto, en EstudianteGradoInformatica, aunque se hereda hay que usar los consultores y modificadores para trabajar con su valor. Lo cual no es ningún problema porque esos métodos también se han heredado y en este caso son públicos, así que se usan directamente. 144

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Magnífico resumen, pero te he dicho que te fijes en la declaración. En el tipo declarado. —Déjeme ver... —escudriño el código en la foto—. Tampoco veo nada en particular. Está declarado como List aunque luego se introduce un objeto de la clase ArrayList. Eso me dice que ArrayList será una subclase de List, porque según la regla de compatibilidad de tipos: en una variable declarada de una clase caben instancias de esa clase o de cualquiera de sus clases hijas. —Muy bien, muy bien —repite con sonsonete. —¿Qué pasa?, ¿me he equivocado?, ¿no es así la regla de compatibilidad de tipos en orientación a objetos? —La regla es así, por descontado. —¿Entonces? ¿Por qué utiliza ese “tonillo” irónico? Desembuche o uno de los dos acabará escaldado. Cada vez soporto menos las indirectas —concluyo airado. —Tranquilo, chico, el problema es que List no es una clase. —¿Ehhhh? —bisbiseo confundido—. ¿Qué si no? —List es una interfaz. No una interfaz de usuario, sino una interfaz de Java. —Explíquese. —El arcoíris se diluye. El rojo viene a parar a mis “mejillas”, ingenuas. Y el resto de colores confluyen en el foco de luz que alumbra al maestro, henchido como acostumbra cada vez que se dispone a sacar de paseo su magnánima sabiduría. —Una interfaz es una declaración de intenciones. 145

NURIA MEDINA

© Alfaomega - RC Libros

—Por favor, en cristiano —protesto. —Una interfaz agrupa la declaración de un conjunto de métodos que todas las clases que implementen la interfaz se comprometen a codificar. Una interfaz es un contrato. —No he entendido nada, pero así a bote pronto: ¿esas interfaces Java no tienen atributos? Ha hablado solo de métodos... —No, la interfaz no contiene declaración de atributos porque los atributos son propios de los objetos, y las interfaces no pueden instanciarse. —Vamos, que no sería posible crear un objeto de la interfaz List 74 —subrayo mis pensamientos en alto para ir peinando mi confusión. —Por supuesto que no, ni de List, ni de ninguna otra interfaz se pueden crear objetos. —Bien, ¿qué más diferencias existen entre una interfaz y una clase? —cuestiono mientras me cruzo de “brazos”—. Quizá por esta otra vía desenrede los nudos que restan.

74

List matricula = new List(); /* no está permitido hacer el new List() porque List es una interfaz */

146

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Hay bastantes cosas que las distinguen —afirma y se dispone a enumerar—: para empezar, en la cabecera de la interfaz75 aparece la palabra reservada interface en lugar de class. Siguiendo, una interfaz no declara atributos, solo constantes si acaso, mientras que una clase puede definir las variables de instancia y de clase que sean necesarias. —Se repite como un loro—. Además, como también te he dicho antes, en la interfaz, los métodos únicamente se declaran, no se implementan. Y, para remate, una interfaz puede heredar de varias superinterfaces porque, al no haber variables ni implementación, los problemas de la herencia múltiple se eliminan. —Vaya, las interfaces también heredan unas de otras... —observo fascinado—, reutilización a tope. —¿Reutilización “a tope”?, serás hortera... —desaprueba el señor Paradigma el vocablo, aunque no me quita la razón en el trasfondo de mi flamante expresión. —Disculpe por ser moderno —le suelto—. Y, antes de seguir, en la declaración de la interfaz List75 hay una cosa rara, rara, rara... Me refiero a que el nombre de la interfaz es 75

public interface List<E> extends Collection<E>{ boolean add(E e); void add(int index, E element); ...

void clear(); /* declara el método, pero no lo implementa */ ... E get(int index); ... }

147

NURIA MEDINA

© Alfaomega - RC Libros

List<E>. ¿Todas las interfaces llevan esa “E”, no debería ser una “I”? El maestro se descojona. —¿Por qué se ríe? —Lo siento —dice mientras se enjuaga las lágrimas—, es que me ha hecho gracia la asociación que has dado por sentada: la <E> no tiene nada que ver con que List sea una interfaz. Por ejemplo, la clase ArrayList también incluye el parámetro <E> en su declaración 76. Esto es porque es una clase parametrizada77 . —¿Clase parametrizada? —Las clases que admiten un parámetro de tipo en su declaración se denominan clases parametrizadas o clases genéricas. Son otro mecanismo de reutilización y cuando se declara un objeto de una clase genérica, hay que darle valor al parámetro de tipo para concretar la clase. El valor del parámetro de tipo debe ser una clase, no puede ser un tipo primitivo. Así, se podría crear un ArrayList o un ArrayList, pero no un ArrayList. En el caso de ArrayList, en el código, el parámetro formal E será sustituido por el tipo concreto Asignatura, quedando todo perfectamente “atado”. Y yo que pretendía desatar nudos...

76

public class ArrayList<E>...{... el parámetro E aparecerá en algunas declaraciones de variables del cuerpo de ArrayList...} 77

En el caso de List, una interfaz parametrizada

148

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Ya veo, es como si existiesen infinitas clases ArrayList. Una donde los objetos que se almacenan en la colección son asignaturas, otra donde los objetos que se almacenan en la colección son “integers” 78... —Otra donde los objetos de la colección son peras —me corta el maestro—. Si son infinitas, ¿te parece que dejemos de listarlas? —Ok —«corta-rollos», añado de pensamiento y nuestras miradas chocan en un “desafío champions”. A pesar de su increíble masa muscular, el señor Paradigma pierde la batalla y baja la vista—. Retomemos el tema de las interfaces. —Sí, mejor será —refiere, parpadeando sobre sus derrotadas “pupilas”—. Aunque antes debo matizar que la clase ArrayList puede usarse sin parametrizar. —¿De qué tipo son entonces los objetos de la colección declarada como ArrayList? —¿Tú qué crees? —Ni idea. —¿Ni idea? Vaya... no eres tan fuerte mentalmente —declara y saca bíceps “encefalótidos”. Pienso y ambos nos echamos a reír, no puedo decirte por qué. Ha sido un pensamiento fugaz, pero totalmente descalabrado.

78

Integer es una clase que sirve para envolver al tipo primitivo int

149

NURIA MEDINA

© Alfaomega - RC Libros

—Piensa, muchacho —me reta el maestro, mientras controla las carcajadas. No puedo culparle: era muy estrafalario ese pensamiento mío. —¿Object? —pruebo, reprimiendo la risotada fácil. —Oui —anuncia—. Un ArrayList sin parametrizar almacena objetos de la clase Object, o lo que es lo mismo, almacena objetos de todo tipo. Me guiña un “ojo”. Él y yo sabemos por qué, y nos volvemos a partir de la risa. Lástima no poder compartirlo contigo, es muy fuerte... Me duele el “abdomen” de los retortijones. —Pongámonos serios, maestro, estábamos hablando de las interfaces —recapitulo—: ¿por qué dijo que eran contratos? —Cuando una clase declara que cumple una interfaz 79 (lo cual se consolida a través de la palabra reservada implements) está obligada a implementar todos los métodos declarados en la interfaz. Ahí está el compromiso. —¿Con la misma cabecera? Quiero decir, ¿los métodos deben ser implementados en la clase con exactamente la misma cabecera que presentan en la interfaz? —Sí, como ocurre en la redefinición de métodos heredados.

79

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable /* en este caso, la clase ArrayList<E> implementa varias interfaces, entre ellas List<E> */

150

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Y, ¿con el código qué pasa? En la clase se podrá escribir un código cualquiera para el método definido en la interfaz, ¿verdad? —Nop. —¿Nop? ¡Pero si la interfaz no impone ningún código en los métodos... el cuerpo de los métodos está vacío! —me quejo. —Ya, los métodos solo se declaran en la interfaz, pero debería adjuntarse una documentación que indique lo que ese método debe hacer y devolver. Es decir, en la interfaz se especifica el qué pero no el cómo. —Ahora lo pillo. Si una clase implementa la interfaz List se sabe de antemano qué responsabilidades tendrán sus objetos: añadir un elemento al final de la lista (add), vaciar la lista (clear), devolver el elemento que hay en una determinada posición (get), devolver el número total de elementos (size)...; otra cosa es cómo se codifiquen esas responsabilidades. —Exacto —coincide—. Por ejemplo, las clases ArrayList y LinkedList implementan la interfaz List cada una a su manera. No obstante, en ambos casos, el cumplimiento del contrato está garantizado. La mayoría de las veces, el cómo no nos interesa. —Es verdad —reflexiono y me surgen nuevas cuestiones—: ¿qué pasaría si una clase no implementa un método incluido en la interfaz que ha declarado cumplir? —La policía vendría a detenerla por incumplimiento de contrato. 151

NURIA MEDINA

© Alfaomega - RC Libros

—¿La policía? —Olvídalo, era una broma mala. Si le falta por implementar algún método declarado en la interfaz, la clase no tendría más remedio que ser declarada abstracta. —Anda —expreso extasiado ante lo relacionado que está todo en Java—. Y... se me ocurre...: ¿sería posible que una clase implementase varias interfaces? Debería serlo porque una clase podría cumplir varios contratos —opino. —Y es posible —confirma el maestro—. Una clase puede implementar cuantas interfaces quiera. Ahora, si falta un único método de los declarados en tales interfaces, será una clase abstracta. —¡Oído cocina! —exclamo, para hacer patente que todo ha quedado blanco sobre negro. —Bien, bien —retoma el tono irónico—. Entonces ya habrás adivinado que el uso de interfaces permite simular la herencia múltiple. —Sí —elevo la voz y finjo agarrar un micrófono—, la herencia múltiple se puede simular en Java de tres formas:1) una clase que hereda de otra clase e implementa una interfaz, 2) una clase que implementa varias interfaces o 3) una clase que implementa una interfaz que, a su vez, hereda de varias interfaces —recito de corrido y añado—: ¿oído cocina? —Oído, oído —musita el señor Paradigma mientras parpadea sobre sus derrotadas “pupilas”. Otro pensamiento fugaz y ambos caemos rodando al suelo, destornillándonos ante la disparatada escena que tiene lugar en nuestras sincronizadas mentes. 152

20. Vídeos polimórficos —¿Hola? —¿Juan? —¿No hay nadie? Camino hacia delante, a la derecha, vuelta atrás y a la izquierda cerrando el cuadrado imaginario. No lo veo por ningún lado… —Deja de jugar al escondite, muchacho. No hay tiempo. —¡¿Hola?! —¿Dónde te has metido? —¡¿Dónde te has metido?! —¡¿Dónde te has metiiiiido?! Me estoy poniendo muy nervioso (con lo relajado que estaba en la posición de La Vela). Mejor será que deje de gritar porque tengo la “boca” reseca y el “corazón” acelerado y me está dando vértigo. Detengo mi correteo de aquí para allá y me siento. Respiro lento y coloco las “palmas” de mis “manos” formando un triángulo bajo el que cobijo mi “nariz”. Luego, con los dos “dedos” que conforman el vértice del triángulo me masajeo el “tabique nasal” y asciendo obrando presión en el “entrecejo” hasta alcanzar la “frente”. Aprieto en el 153

NURIA MEDINA

© Alfaomega - RC Libros

centro, en el denominado tercer ojo o ajname. Esto consigue frenar mi preocupación. Aunque el problema persiste: —No encuentro a Juan. Hace demasiado rato que no escucho sus pensamientos descarriados. No tenía que haber bajado la guardia. Mientras practicaba yoga he desconectado de la frecuencia de su mente y, ahora, no consigo recuperar la señal. La meditación me ha liberado del yugo de la superficialidad corporal, pero me he metido en un buen lío por descuidar mis responsabilidades. —¿Puedes echarme una mano? —¿Eoo? Te hablo a ti. —¿Lo has visto? —¿Dónde está Juan? El objeto. Ya sabes... Grillos. —¿No sabes nada? Vaya. ¿Dónde diantres se habrá metido? Es el objeto más especial que he tenido la oportunidad de tutelar. Jamás otro me dio tantos quebraderos de “cabeza”, ni tantas satisfacciones. Es inteligente el chico. Lástima que le quede tan poco. Le echaré de menos, cuando se vaya. Porque… no puede haberse ido aún. No. Por favor. Todavía no… «Debo pensar en positivo», me aconsejo y le propino un rumboso empujón a mis temores. No puede haberse marchado todavía. Voy a pensar, mejor, en cómo aprovechar el tiempo que nos queda juntos. Idearé un buen plan. Pero 154

© Alfaomega - RC Libros

JAVA. LA NOVELA

eso será en cuanto lo encuentre, porque ahora bastante tengo con sostenerme sobre las “piernas” que no dejan de temblarme. —Mira, ufff, por allí viene. Tras el resoplido inicial hago un esfuerzo considerable por borrar cualquier signo de ansiedad. Él, sin embargo, marcha tan feliz y campante. Creo que no me ha visto. Ajá. Ahora sí me vio, esboza una sonrisa triunfal y conforme se aproxima es más evidente que ha hecho una de las suyas. ¿De dónde vendrá? —Señor Paradigma, desaparezco un momento de la escena y me roba la narrativa —le reprocho mientras le abrazo, estirando mucho mis “extremidades superiores” para poder abarcar el titánico “torso”—. Por favor, deje de hacer body-pump que parece un armario ropero de tres puertas en lugar de un paradigma de programación orientado a objetos. —Tus deseos son órdenes. Me he pasado al yoga —sonríe y me achucha—. ¿Dónde has estado? —me pregunta, visiblemente aliviado por nuestro reencuentro. —No le va a gustar, pero se va a quedar de piedra. —A estas alturas no hay nada que pueda sorprenderme. —¿Seguro? —Seguro —me desafía. —Agárrese los machos que voy... —Déjate de vulgaridades y explícate —exige. 155

NURIA MEDINA

© Alfaomega - RC Libros

—Bien, no voy a andarme por las ramas que me duelen las “plantas de los pies” de tanto caminar. Aunque permítame comenzar por el principio: después de reflexionar sobre la regla de compatibilidad de tipos en orientación a objetos y deducir que una variable declarada de tipo List puede apuntar a cualquier objeto cuya clase implemente la interfaz List… —Es verdad… —me corta—. No te expliqué eso. ¡I’m sorry. Sorry. Sorry! —Se disculpa, cansino—. Si el tipo declarado para una variable es una interfaz, en la variable puede almacenarse cualquier objeto cuya clase implemente esa interfaz. —Agua pasada no mueve molinos, eso ya lo había averiguado yo solito —presumo—. En fin, el caso es que tras comprender esto, entré en un estado de aburrimiento considerable. Así que, como no sabía qué hacer, se me ocurrió adelantar el “pie” derecho y, motu proprio, el izquierdo lo siguió. El mismo movimiento se repitió, encadenándose un paso tras otro... —¿Me estás tomando el pelo? ¿Tanto preámbulo para decirme que vienes de dar un paseo? —me corta desesperado el maestro. —Si prefiere que vaya directo al grano, me salto de un brinco los millares de pasos que me encaminaron hasta el límite. —¿El límite? ¿El límite de qué? Me estás asustando... —El límite de la zona de memoria RAM destinada a nuestro programa. 156

© Alfaomega - RC Libros

JAVA. LA NOVELA

—¿Te has colado en la memoria RAM de otro programa en ejecución? —Eso mismo —admito con orgullo. Se lleva las “manos” a la “cabeza”; el que decía que nada podía sorprenderlo, míralo, si parece una estatua de sal. —¿Dónde exactamente te has metido? —¿firefox.exe?, ¿le suena? —Es un navegador web. —Lo sé. —¿Cómo que lo sabes? —balbucea el señor Paradigma arrastrando las palabras con formalizado pavor. —Me lo ha dicho un amigo. —¿Amigo? —susurra en lo que viene siendo un alarido contenido. —Mire, señor Paradigma, para serle franco, cuando lo conocí me dio una miaja de susto. Tenía una “boca” tan grande que parecía que iba a tragarme. Pero, inmediatamente, me preguntó con desbordante amabilidad: ¿qué deseas buscar? y desde entonces nos hemos hecho inseparables. Le lanzo una cuestión a su “bocaza” rectangular, se la traga, la digiere y vomita un montón de información. —Has estado usando un buscador... —Sí y me he “hinchado” a ver vídeos en youtube —anuncio emocionado. 157

NURIA MEDINA

© Alfaomega - RC Libros

¡Cataplum! —Tranquilo, señor Paradigma, respire. —El maestro se ha desplomado y trato con todas mis fuerzas de colocarle las “piernas” en alto. Ahora le doy aire con ambas “manos”. Pobrecito—. ¡Respire, respire! —Parece que vuelve en sí. Recuesto al maestro sobre su “espalda” sin dejar de abanicarlo y le sigo explicando lo acontecido, ahora con bastante más mano izquierda. Me ha hecho jurar que únicamente he visto vídeos que trataban temas de orientación a objetos. Que Dios me perdone. Le he mentido. Imagina. He visto de TODO. —Muchacho, eso que has hecho está muy mal. No forma parte de tus responsabilidades. ¿Por qué lo hiciste? —Solo quería sentirme libre y como le he empezado a contar: adelanté un “pie” y el otro se empeñó en acompañarlo... Ha venido todo rodado. —¡No retomes esa línea de defensa, que me exasperas! —Me silencia de malos modos, y añade con fingida desidia—: anda, desembucha: ¿qué es lo que más te ha llamado la atención de esos vídeos tutoriales? —Una grabación que se titulaba: “Compilación de un programa en Java”. —Le miento de nuevo porque lo que más me ha llamado la atención ya te lo puedes figurarrrrrrr. —Borra esa “cara” de vicio y detállame lo que has aprendido del compilador —sugiere a la par que me propina un sonoro manotazo. —¡Ay! —me quejo—. Ha sido interesante ver al compilador en acción, pero casi todo lo que salía en los 158

© Alfaomega - RC Libros

JAVA. LA NOVELA

vídeos ya lo sabía gracias a usted —admito mientras le hago una reverencia—. Incluso he pillado al compilador en varias equivocaciones. —¿Equivocaciones? ¿El compilador? ¡Venga, ya! Especifica. —Sí, había casos en los que el compilador debía dar un fallo y no lo daba, y otros donde sí que lo daba sin existir tal error —declaro con aires de grandeza. —Vete al caso concreto, por favor —solicita el señor Paradigma con muy poca paciencia, como si no tuviésemos por delante todo el tiempo del mundo para tratar estos y otros temas. Es pensar esto último y sentir una lagartija de piel húmeda y fría ascendiendo por mi “columna vertebral”. ¿De dónde habrá salido? Me doy una palmada en la “espalda” para espantarla, pero el bicho no respira. La “cara” del maestro es un poema fúnebre; la mía, más propia del tenor de una ópera trágica. Meneo la “cabeza” para espantar los fantasmas. Tampoco existen, como la lagartija. Eso me anima un poco y continúo relatándole al señor Paradigma las meteduras de pata del compilador: —Había una clase abstracta llamada FiguraGeometrica de la cual heredaban las clases Circulo y Cuadrado (entre otras) 80 . Cada

80

abstract class FiguraGeometrica{...} class Circulo extends FiguraGeometrica{...} class Cuadrado extends FiguraGeometrica{...}

159

NURIA MEDINA

© Alfaomega - RC Libros

subclase redefinía el método abstracto area() de una forma diferente. En el caso del círculo como PI*radio2 y en el caso del cuadrado como lado2 . —¿Otra vez yéndote por las ramas? —protesta—. Dime si Circulo y Cuadrado eran abstractas o no. —No, ambas clases eran concretas puesto que en la clase FiguraGeometrica, el método area() era el único sin implementación. Bueno, el caso es que había una instrucción en el programa donde se enviaba el mensaje toString() a un objeto de la clase Circulo y ni en la clase Circulo ni en la clase FiguraGeometrica aparecía un método con semejante denominación. —¡Ja! —suelta. —¿Ja? Si yo hubiese sido el compilador habría detectado el error. —Ya, por eso no eres compilador —afirma malicioso. A pesar del cariño que nos profesamos tengo que reconocer que es un puñetero—. Voy a simular que soy el compilador, ¿de acuerdo? —De acuerdo —consiento. —A una variable declarada de tipo Circulo le llega el mensaje toString(). ¿Voy bien? —Sí —respondo de mala gana. —Entonces, busco en la clase Circulo el método que resuelve esa responsabilidad. Como no hay ninguno que encaje con la cabecera toString(), me muevo al código de la 160

© Alfaomega - RC Libros

JAVA. LA NOVELA

clase FiguraGeometrica (la superclase) y tampoco encuentro el método. ¿Voy bien? —Sí —respondo de peor gana. —Entonces, sigo subiendo —advierte, al mismo tiempo en que caigo en mi descuido—, porque no hemos llegado a la raíz de la jerarquía de herencia. Como en la clase FiguraGeometrica no aparece la palabra reservada extends, significa que se hereda de Object. Y, ¡ahí está...! —El método toString() está implementado en Object —termino la frase. —Exacto —confirma. —¿Y para qué sirve? —pregunto, no tanto porque me inquiete sino para evitar tener que decirle: «el compilador y usted tienen la razón». —toString() sirve para describir de forma textual un objeto. —Ah, por eso se usaba como argumento de System.out.println81 , para imprimir por pantalla los atributos del círculo. —Audaz muchacho, veo que has aprendido un poquito sobre la entrada/salida por pantalla en Java. —Poco, poco —reconozco—. He tenido otros temas más jugosos a los que prestar atención...

81

System.out.println(“mensaje a imprimir por pantalla”);

161

NURIA MEDINA

© Alfaomega - RC Libros

Me mira con rencor. A ver si va a tener envidia... Esos vídeos eran muy excitantes (y no me refiero a los tutoriales, ya sabes). —Sigamos —retomo el hilo—. Admito que eso no daba error. Pero ese compilador estaba malogrado, doy fe. —¿Qué otra cosa hizo mal, según tú? —recalca lo de “según tú”. Ahora se va a enterar... —La clase abstracta FiguraGeometrica implementaba una interfaz llamada Figura 82 . Pues bien, en el programa principal había una variable declarada de tipo Figura a la que en un momento dado se le asignaba un objeto de la clase Circulo y en otro momento dado se le asignaba un objeto de la clase Cuadrado... —Una variable polimórfica —apunta el señor Paradigma. —¿Polimórfica? —La terminación “mórfica” se asocia en mi “cerebro” con la palabra morfología, disparando en mi retina la proyección de las voluptuosas imágenes visualizadas en los vídeos. Me relamo y el señor Paradigma me propina un posiblemente merecido cocotazo. —Polimórfica significa que puede tomar varias formas 83. Ahora es un círculo, ahora es un cuadrado. La regla de compatibilidad de tipos permite este polimorfismo, ya que 82 83

abstract class FiguraGeometrica implements Figura{…} Figura unaVar; unaVar = new Circulo(3,5,7); ... unaVar = new Cuadrado (1,1,2); ...

162

© Alfaomega - RC Libros

JAVA. LA NOVELA

en la variable declarada de tipo Figura cabe cualquier clase que implemente dicha interfaz, como es el caso de FiguraGeometrica y, por ende, de todas sus subclases. —Sí, claro, eso ya lo había dicho yo. No me desvíe de mi destino, por favor —le exijo con fundamento, pues de otro modo se me olvidará adónde quiero llegar—. Cuando a la variable se le enviaba el mensaje area(), el resultado variaba según el objeto que contenía en ese momento era un círculo o un cuadrado. —Eso es el polimorfismo de mensajes, la misma sintaxis de envío de mensajes puede ejecutar métodos diferentes según quién sea el objeto receptor 84 —vuelve a interrumpir—. Este polimorfismo es posible porque la ligadura en Java es dinámica. —¿Ligadura dinámica? Usted gana. Explíqueme eso y luego déjeme continuar con mi narración del fallo del compilador.

84

Figura unaVar; unaVar = new Circulo(3,5,7); unaVar.area(); //polimorfismo de mensajes unaVar = new Cuadrado (1,1,2); unaVar.area(); //polimorfismo de mensajes

163

NURIA MEDINA

© Alfaomega - RC Libros

Ilustración 13. El tipo declarado para una variable restringe qué mensajes se le pueden enviar; pero, si hay ligadura dinámica, el resultado del mensaje depende del objeto que en cada momento contiene la variable.

164

21. Ligadura dinámica El señor Paradigma me pide tiempo. «Me estás estresando», me recrimina de pronto. No puedo creerlo, ha pasado de circular como una moto, centrifugando “brazos” y “piernas” a diestra y siniestra, a un estado de sosiego más propio de una momia que de un “ser vivo”. Sus “músculos” se han vuelto lánguidos. Y, como si desde las entrañas de la Tierra tirasen de él, se deja caer pesadamente para sentarse y ejecutar a cámara lenta un artificioso ovillo con sus “rodillas”. La posición de Loto dice que se llama. « पासन», respondió de primeras cuando le pregunté. ¿Tendrá pachorra?, ¿como si yo supiera sánscrito? Nada, ni caso me hace. Voy a dejarlo tranquilo un rato. Silbo. Camino. Me cruzo de “brazos”. Me descruzo. Silbo. Camino. Me cruzo de “brazos”. Me descruzo. Silbo… — ¡¿Ha terminado de meditar ya?! —grito cuando me harto. Abre los “ojos”, medio lelo, y pregunta: —¿Dónde estoy? —Suena confuso pero bondadoso. Ahora me da pena haber sido tan brusco. —Maestro, me estaba explicando lo que es la ligadura dinámica —digo bajito como si no quisiera despertarlo. Aunque no está dormido, por los “pelos” (que no tiene).

165

NURIA MEDINA

© Alfaomega - RC Libros

—Ah, sí. —Respira con más brío y se estira. Luego arranca—: cuando se hace cualquier envío de mensaje 85, el mensaje se liga a un método que se ejecuta para resolver la petición. Esta es una de las primeras cosas que te expliqué. Esa ligadura podría ser en tiempo de compilación o en tiempo de ejecución. Cuando la ligadura es en tiempo de compilación se denomina ligadura estática y cuando se realiza en tiempo de ejecución se dice dinámica. En Java solo existe la ligadura dinámica. —Ya veo —musito—. Pero ¿por qué no se llaman ligadura en compilación y ligadura en ejecución, respectivamente? Habría sido más intuitivo. —Qué va... —disiente el “maestro buda” que se ha colocado “cabeza” abajo—. Es más intuitivo el término “ligadura dinámica” porque eso indica que la ligadura se realiza en función del tipo dinámico de la variable que contiene el objeto receptor del mensaje. Y la ligadura estática, como podrás anticipar, se realizaría en base al tipo estático de la variable. —Prosiga. ¿Tipo dinámico y estático? ¿Qué diferencia existe? Yo solo conozco el tipo declarado para la variable. —El tipo estático de una variable es el tipo declarado. Por ejemplo, si en la línea de código 1 se declara Figura unaVar; el tipo estático de la variable unaVar es Figura.

85

unaVar.mensaje(arg1, arg2,...,argn); /* el mensaje se debe ligar a un método llamado de la misma forma. Este proceso se conoce como ligadura de mensajes */

166

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Obvio, el tipo declarado. Con eso no hay problema, puede ser una clase, una clase abstracta y, como en este caso, una interfaz. —Vale, ahora presta atención 86 —requiere con parsimonia—: si en la línea de código 2 se mete un objeto de la clase Circulo dentro de la variable, en esa línea el tipo dinámico de unaVar es Circulo (aunque su tipo estático no cambia y sigue siendo Figura). —Creo que lo entiendo. El tipo dinámico de una variable es el tipo del objeto al que la variable apunta en cada momento. Y, cuando el tipo estático es una interfaz (como lo es Figura), el tipo dinámico puede ser cualquier clase que la implemente. —Exacto. Evolucionas adecuadamente —sonríe—. Por eso mismo es un tipo dinámico, ¿entiendes?, porque puede variar durante la ejecución. Imaginemos que en la línea de código 7 se introduce en unaVar un objeto de la clase Cuadrado. —En la línea 7, el tipo dinámico de dicha variable sería Cuadrado. —Eso mismo —asiente—. Entonces, si en la línea de código 3 se le envía el mensaje area() a unaVar, ¿con qué método se liga la petición? 86

1. Figura unaVar; 2. unaVar = new Circulo(3,5,7); 2 3. unaVar.area(); //devuelve el área según PI*radio ... 7. unaVar = new Cuadrado(1,1,2); 2 8. unaVar.area(); //devuelve el área según lado

167

NURIA MEDINA

© Alfaomega - RC Libros

—Con el método area() de la clase Circulo, porque ese es su tipo dinámico y en Java la ligadura es dinámica. —¿Y si en la línea de código 8 se hace la misma petición? —A partir de la línea 7, el tipo dinámico de unaVar es Cuadrado. Por eso, el método area() que se ejecutaría en la línea 8 es el definido en la clase Cuadrado. —¡Bravo! —exclama el señor Paradigma mientras mantiene la postura del pez—. La misma sintaxis, unaVar.area(), ha dado lugar a resultados diferentes porque la ligadura del mensaje area() con el método area() ha sido diferente. La primera vez (línea 3) el receptor era un círculo y se ha ligado con el método area() de la clase Circulo, y la segunda vez (línea 8) el receptor era un cuadrado y se ha ligado con el método area() de la clase Cuadrado. —Bien, asimilado lo de la ligadura dinámica y el polimorfismo de mensajes —sintetizo mi sapiencia mientras me coloco detrás de él para que pueda mirarme sin quebrarse el “cuello”—. Y ahora estoy más seguro, si cabe, de que el compilador notificó un fallo inexistente. Le explico: suponga que en la línea 4, cuando el tipo dinámico de unaVar es Circulo se le envía el mensaje radio()87. El método radio()

87

1.Figura unaVar; 2. unaVar = new Circulo(3,5,7); 2 3. unaVar.area(); /* devuelve el área según PI*radio (el compilador no “protesta” porque el método area() está declarado en Figura, y el intérprete trabaja en ejecución con el tipo dinámico que es Circulo) */ 4. unaVar.radio(); /* da error en tiempo de compilación porque el método radio() no está declarado en la interfaz Figura (el compilador trabaja con tipos estáticos) */

168

© Alfaomega - RC Libros

JAVA. LA NOVELA

estaba implementado en la clase Circulo, se lo aseguro, y el compilador protestó justo en esa línea. —Normal —resuelve y me deja chafado—. Aunque en Java la ligadura del mensaje con el método se realiza en tiempo de ejecución, el compilador no tiene más remedio que testear los errores con la información que hay disponible en tiempo de compilación. Así que el compilador trabaja con los tipos estáticos. —Sssssss —siseo como una serpiente—. El compilador solo entiende de tipos estáticos. Entonces… ¿no funcionaría pedirle al objeto círculo que está dentro de la variable unaVar que nos diga su radio? —Sí funciona (es su responsabilidad), pero hay que indicarle al compilador que, en ese momento, esa variable contiene un objeto de la clase Circulo. Eso se hace con un casting 88. El casting es una declaración que proporciona información de tipo al compilador. En nuestro caso quedaría algo así como ((Circulo)var).radio() y no daría ningún problema si es verdad, como dices, que el método radio() está implementado en la clase Circulo. —¡Ajá! —chiflo—. El mensaje area() enviado a unaVar no daba error de compilación porque el método area() estaba declarado en la interfaz Figura, pero en dicha interfaz no existe ningún método llamado radio() y por eso hay que hacer el casting. El compilador sabía lo que hacía. Vaya. He quedado como un tonto. 88

(Tipo)unaVariable //o (Tipo)unaVariable.mensaje() /* cuando el resultado del mensaje es un objeto */ //en ambos casos, el tipo debe ser una clase o interfaz

169

NURIA MEDINA

© Alfaomega - RC Libros

—No, muchacho, no eres ningún tonto; simplemente hay cosas que no se encuentran en los vídeos tutoriales. —¿Sí?, no sé yo qué decirle. En esos vídeos aparece de TODO —fanfarroneo y, como no podía ser de otro modo, me llevo un buen capirotazo—. Otra cosa, ¿qué pasaría si se engaña al compilador con un casting? —¿Qué cosas tienes?, ¿engañar al compilador? Mira que eres rebuscado —arruga la “nariz” acortando distancia con el “labio”—. Digamos que si hay un casting equivocado, el error se produciría en tiempo de ejecución. Si el objeto receptor no tiene la responsabilidad que se le pide, el programa falla. —Hablando de fallos, me falla la “cabeza”. Estoy abotargado, con tanta ligadura y polimorfismo. ¿Podemos descansar? —Haremos algo mucho mejor que eso —anuncia exultante—. He preparado un plan para que nos divirtamos un poco. —Un plan “lúdico-educativo” —supongo y suspiro. —Solo lúdico —afirma con exagerado brío. Habrá que verlo…

170

22. Reflexiones Supe que el plan del señor Paradigma iba a ser un desastre desde el mismo momento en que se empeñó en que ambos nos colocáramos unas camisetas con el eslogan: “We love Java”. Fondo negro y letras grises, no se podía lucir más friki. En fin, el plan no prometía y mi primera impresión no fue refutada. El entretenimiento principal consistió en ver una obra de teatro. Los actores, como no podía ser de otro modo, eran objetos del programa y la acción habría convencido de que se volviesen a su tumba a los zombis más despiertos. Criar malvas es, sin duda, una actividad mucho más amena que observar semejante envío de mensajes. Según el maestro, los profesores de afuera, los de carne y hueso, estaban preparando las fichas de sus asignaturas, y las peticiones de mete(tema) y saca(tema) se sucedieron durante un buen rato, poniendo patas arriba el ArrayList llamado temario en prácticamente todos los objetos de la clase Asignatura. Para paliar el hastío y a compás del movimiento, me inventé una canción que decía: “métela sácala, métela sácala, métela sácala..., mete la pierna, saca la pierna... mete la pierna, saca la pierna...” Aunque pueda parecer increíble me habría hecho famoso si Félix Contreras no me hubiera tomado la delantera... En fin, si tuviésemos palomitas o me hubieran enviado algún mensaje a mí, la cosa habría tenido algo de chispa. 171

NURIA MEDINA

© Alfaomega - RC Libros

Pero, a falta de maíz y protagonismo, la representación se me antojó sosa a más no poder. Después, el señor Paradigma sacó una baraja de cartas. Napakalaki se llamaba el juego de rol e iba sobre monstruos y tesoros. ¡S.O.S.! Usamos la versión original, con los mensajes en danés. Reconozco que era todavía peor que la obra de teatro cuando el maestro, visiblemente desesperado, me pregunta con tono confidencial: —¿“Hackeamos” el reloj del sistema? —Noooo —estallo—. Déjese de “frikismos”, su plan es soporífero. —Pensé que algo tranquilo estaría bien —se disculpa decepcionado. Me desarma su “cara” de pena y se me cae el alma a los “pies”. —Señor Paradigma, he sido un desagradecido. Algo tranquilo estaría bien, pero no lo que usted propone, precisamente. —¿Qué planteas? —consulta indómito. —Le cuento… Cuando termino mi exposición, el señor Paradigma niega con la “cabeza”. Mi plan no lo ve factible: sentarnos en el zócalo de la CPU y darnos un masaje relajante con los “pinchitos” electromecánicos. Llorar y recoger las lágrimas en una tecla para montarnos un jacuzzi. Colocarnos, después, pétalos de rosas y piel de uva en todo el “cuerpo” y bebernos una infusión de granadina mientras jugamos con las burbujas. 172

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Nada de eso es posible, aquí dentro —concluye cuando su “cabeza” deja de negar. Miro hacia abajo, la desilusión me tira del “cuello”. El señor Paradigma me tira del “cogote”. —Pero, no te preocupes muchacho. Vamos a hacer todo eso. Y lo vamos a hacer juntos. Ven aquí —me señala su “hombro” y se da unos golpecitos a modo de invitación para que me tienda sobre él. Una vez acomodados, me regala un prolongado masaje y con sus palabras me rasca la “espalda” y me humedece la “piel” y me coloca encima los pétalos de rosa, las uvas y otras mil porquerías. Dirigido por su elocuencia verbal, con la imaginación, ingiero infusiones múltiples, y también zumos, y de paso, alguna bebida espirituosa cae. Y luego, bien achispados, nos vamos de compras, y me pillo el objectphone de última generación. El tiempo se detiene mientras lo estreno y el maestro de tanto hablar se queda sin saliva, pero aun así sigue envolviéndome con sus palabras para que viva todo lo que quería vivir, hasta el final. —Juan, volvemos, ¿vale? Inhala con más energía y regresa al aquí y al ahora. Respiro y me estiro. —Abre los “ojos”. Le obedezco, abro los “ojos” y sonrío complacido. —¿Lo has pasado bien? —me pregunta, aunque ya sabe la respuesta.

173

NURIA MEDINA

© Alfaomega - RC Libros

No le respondo. Queda poco tiempo. ¿Por qué malgastarlo con obviedades? He podido escuchar los latidos de su “corazón”. La cuenta atrás. En cada nuevo bombeo, su “masa vital” cruje con fuerza. Puedo descifrar en su mirada que me queda muy poco. Nuestro vínculo va a expirar y él no puede disimular la tristeza. —Maestro, quiero saber: si tenemos en Java una colección genérica, es decir, sus objetos pueden ser cualquier cosa… cuando se saca un objeto de la colección, el compilador solo sabe que es un Object (tipo estático) y por lo tanto solo aceptaría que se le envíen al objeto mensajes que “liguen” con métodos declarados en la clase Object. —¿Y? —interpela, consciente de que mi curiosidad más tiene que ver con evaporar miedos, que con ganas de saber. —Pues que no es lógico; si sacamos de la colección un objeto de la clase Naranja debería admitir el mensaje exprimir() y si sacamos un objeto de la clase Lapiz debería poder escribir(). ¿Cómo podríamos saber en tiempo de compilación de qué clase es el objeto que va a salir de la colección durante la ejecución del programa? Necesitamos saberlo en compilación para poder hacer el casting y que el compilador permita los mensajes propios del tipo dinámico. —No siempre es posible saberlo en tiempo de compilación. Como tú mismo has puesto sobre la mesa, puede que no lo sepamos hasta el tiempo de ejecución. Quizá el objeto que se saca de la colección sea aleatorio o dependa de la interacción del usuario. Lo normal es que ahí no podamos hacer el casting. —¿Entonces? —empieza a picarme la curiosidad (de verdad). 174

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Siempre podemos preguntárselo. —¿Preguntar?, ¿qué?, ¿a quién?, ¿cómo? —Con la reflexión —responde únicamente cómo. —¿Reflexión? —¿Acaso no sabes lo que es reflexionar? —¿Cómo no iba a saberlo?, si soy un virtuoso de la reflexión —bromeo, y mi mofa me aflige porque la realidad es que cada vez estoy más torpe—. Reflexionar es analizar detenidamente nuestra forma de ser o de actuar, con objeto de poder conocernos y modificarnos para mejorar. —Pues eso, en Java es posible reflexionar sobre la estructura (cómo son) y el comportamiento (qué pueden hacer) de las clases. —Ya, muy interesante, pero ¿cómo encaja eso con mi pregunta? ¿Cómo puedo saber de qué clase es el objeto que hay en una determinada posición de una colección de objetos variados? —A cualquier objeto podemos enviarle el mensaje getClass(). Se trata de un método 89 implementado en Object y devuelve un objeto de la clase Class que describe la clase del objeto receptor 90. Además, es un método final, lo que significa que no se puede redefinir. Esto garantiza que 89

public final Class getClass(){...} /* método implementado en Object */ 90 Class c = var.getClass(); /* en el caso del objeto “Juan” (almacenado en la variable var) el objeto c describiría la clase EstudianteGradoInformatica */

175

NURIA MEDINA

© Alfaomega - RC Libros

siempre getClass() devuelve un objeto describiendo la clase del receptor. —Es decir, que si yo fuese el receptor de getClass(), devolvería un objeto de la clase EstudianteGradoInformatica. —No me has escuchado —reprueba—. Devolverías un objeto de la clase Class que describiría la clase EstudianteGradoInformatica. Tú y todos los objetos de tu clase devolveríais lo mismo; ya que existe un único objeto de la clase Class para cada clase. Solo uno, tantos como clases. —Entiendo... Es verdad, yo había dicho una chifladura. Pero, cada vez me cuesta más pensar… Agudiza la tristeza en su semblante, pero continúa con la explicación: —Una vez obtenido el objeto de la clase Class, se le pueden enviar mensajes para preguntarle cualquier cosa sobre la clase que describe. Para saber el nombre, que es lo que nos compete en este caso, usaríamos getName(). —¿Cómo lo usaríamos en el supuesto de la colección genérica? —No sé qué me pasa. No puedo razonar… Tengo el “cerebro” congestionado. —Se emplearía un condicional para preguntar cuál es la clase del objeto extraído de la colección en cada momento —aclara paternal y no me riñe como acostumbraba. Está claro que me queda un telediario y dos afeitados. Suspiro y él trata de tapar el melancólico murmullo retomando su

176

© Alfaomega - RC Libros

JAVA. LA NOVELA

disquisición—: según la clase del objeto (obtenida mediante reflexión), se le enviarían al mismo unas u otras peticiones 91. —Creo que lo entiendo —aventuro con el “ceño” fruncido como un acordeón debido al sobreesfuerzo—. ¿Qué otras cosas se le puede preguntar al objeto Class sobre la clase que representa? —Todo, ya te lo dije —reitera—. El paquete donde está incluida la clase (getPackage), su superclase (getSuperclass), las interfaces que implementa (getInterfaces), las variables declaradas (getField), los métodos (getMethods)… —Espere… una clase puede implementar muchas interfaces y declarar muchos atributos y métodos. ¿Qué pasa entonces? —consulto mientras me llevo las “manos” a la “frente” en un denuedo baldío por detener el dolor. —Se devuelve un array de objetos de la clase Method si hemos solicitado los métodos, un array de la clase Field si hemos solicitado los atributos y un array de la clase Class si

91

ArrayList cesto = new ArrayList();

... //meter objetos de distinto tipo en el cesto for (Object o: cesto){ if (o.getClass().getName().equals(“Naranja”)){ ((Naranja) o).exprimir(); } if (o.getClass().getName().equals(“Lapiz”)){ ((Lapiz) o).escribir(); } ... }

177

NURIA MEDINA

© Alfaomega - RC Libros

hemos solicitado las interfaces implementadas. Luego, podemos conocer los modificadores de un objeto Method o Field concreto mediante el mensaje getModifier que codifica con un valor entero todos sus modificadores. —Hace una pausa para mirar de reojo las forzadas expresiones que estoy ejercitando mientras intento seguir el hilo. Y, disimulando la punzada que le acaba de recorrer la “espina dorsal” prosigue con la mayor naturalidad que es capaz de fingir—: existe una clase llamada Modifier 92 que si le pasamos como argumento el valor entero que codifica los modificadores de una variable o un método, nos saca de dudas sobre si es abstracto (isAbstract), es final (isFinal), es de clase (isStatic), tiene visibilidad privada (isPrivate), pública (isPublic), etc. —No sé si lo entiendo… —murmuro con flojera en la voz, en el “cuerpo” y en el espíritu. —A un objeto Field podemos preguntarle también por su tipo estático, el declarado (getType); y en el caso de un objeto Method podremos saber el tipo de retorno (getReturnType) y el tipo de sus argumentos (getParameterTypes). —No sé si lo entiendo… —repito porque estoy bastante confundido. Es como que mi trabajo cognitivo estuviera sufriendo interferencias. El apagón final está al caer… 92

Class describeClaseDeVar = var.getClass(); Method[] metodos = describeClaseDeVar.getMethods(); int modificadores1 = metodos[1].getModifiers(); boolean esAbstracto = Modifier.isAbstract(modificadores1); /* devolvería true si el primer método de la clase es abstracto */

178

© Alfaomega - RC Libros

JAVA. LA NOVELA

—Ah, una cosa que he pasado por alto —encubre mi confusión y sigue hablando para que nuestra espera sea menos agónica—: si preguntamos por las interfaces que implementa una clase (getInterfaces), obtendremos un array de objetos Class porque cada uno de esos objetos, a su vez, describe una interfaz. Y podemos preguntar, usando la reflexión de Java, cualquier cosa sobre ellas enviando mensajes a los objetos Class asociados. ¿Lo entiendes? Lo miro desamparado. Mi “cerebro” es pura maraña. —Ja, me acabo de dar cuenta de que antes no he sido preciso del todo: existe un objeto de la clase Class para cada clase e interfaz. No había incluido las interfaces en la cuenta —ríe para romper mi silencio y su lacónica carcajada retumba—. ¿Lo entiendes? —insiste. —Lo único que entiendo es que una vez conseguido el objeto Class que describe una clase, se le puede preguntar cualquier cosa sobre su código —resumo con sinceridad y el maestro sonríe—. Para lograr el objeto Class usaremos el mensaje getClass(). —¡Estupendo! —aclama con exagerado fervor—. La forma más común de obtener el objeto Class que describe una clase es solicitándoselo a una instancia de la misma con getClass(); pero si no existe ninguna instancia o si ni siquiera conocemos la clase (quizá la vayamos a pedir por teclado) podemos usar el método forName 93. Es un método de clase, 93

Class describeClaseEstudianteGradoInformatica = Class.forName(“EstudianteGradoInformatica”); /* El método que incluye esta sentencia debe capturar o declarar una excepción por si la clase especificada no existe en tiempo de ejecución) */

179

NURIA MEDINA

© Alfaomega - RC Libros

lo cual significa que el receptor debe ser la propia clase Class, y hay que pasarle un String con el nombre de la clase cuyo objeto Class queremos obtener. —Pare, por favor —suplico—. No creo que nadie pueda recordar tantos métodos. —No hace falta, el API 94 de Java facilita toda esta información y más, solo hay que conocer que la clase principal para la reflexión en Java es Class y se encuentra en el paquete java.lang. Ahora que sabes buscar en la Web, consultar la API será pan comido —apunta sollozando. Ambos sabemos que no voy a volver a buscar en ningún rectángulo gigante. Ambos sabemos que voy a morir. No disimules. También lo sabes tú. —¿Con la reflexión podemos modificar las clases para que sean mejores, añadirle atributos o cambiar el código de algunos métodos? —Contengo en la pregunta el tormento que me retuerce las “entrañas”. —No, en Java la reflexión es por introspección (solo consultas). Para poder modificar las clases en tiempo de ejecución (reflexión por intersección) es necesario que el lenguaje de programación orientado a objetos sea puro, vamos, que las clases también sean objetos. Eso no ocurre en Java. Ocurre, por ejemplo, en Smalltalk. La vibración que provoca la “k” de Smalltalk nos toca la fibra sensible, es una letra inofensiva y liviana, pero no necesitábamos más que un soplo para rompernos. Lloramos 94

Application Programming Interface

180

© Alfaomega - RC Libros

JAVA. LA NOVELA

sobre la profunda brecha que ha partido por la mitad nuestra simulada entereza y nos abrazamos. No nos decimos nada porque las lágrimas que aún viven en nuestras “gargantas” no consienten que salgan más letras. El silencio persiste y la hora se acerca. «No quiero marcharme sin contemplar unas ruinas romanas» le pido con el pensamiento, y él no se amedranta ante mi excentricidad, sino que se golpea el “hombro” para que descanse mi “cabeza” y me regala un masaje mientras me describe con todo lujo de detalles el Coliseo de Roma en la época de su mayor esplendor. Me siento un emperador, un gladiador, un héroe… me siento tú.

181

23. aDios Estoy listo. He llorado hasta disecar mis “órganos internos”. Lo suficiente como para colmar embalses y desviar de su cauce a caudalosos ríos. Ahora me siento mucho más ligero, mi “cuerpo” era un 75% agua. Un objeto no puede vivir eternamente, ningún ser vivo puede hacerlo... Es el precio que hay que abonar a cambio del regalo existencial. Lo acepto. No queda otra. Al menos marcho conociéndolo todo sobre la orientación a objetos en Java. —¿Todo? No, muchacho, apenas sabes nada. —¿Nada? —pregunto decepcionado ante el comentario del señor Paradigma que, se hace evidente, seguía leyendo mi mente. —Retiro lo de nada; la nada es muy vacía. Pero hay muchas cosas que te faltan. Si quieres te las enumero: serialización 95 , manejo de ficheros 96 , persistencia de

95

Interfaz Serializable que hay que implementar para poder obtener el estado de un objeto como una secuencia de bytes 96 Clases File, FileReader, BufferedReader...

182

© Alfaomega - RC Libros

JAVA. LA NOVELA

objetos97 , bases de datos orientadas a objetos 98, swings99 , threads100, applets101, servlets102... —No me interesa —miento y lo detengo porque no queda tiempo y su discurso se enzarza en mi “nuez gris”—. Estoy seguro de que me ha explicado todo lo importante. —No te quito la razón, has comprendido el núcleo de la orientación a objetos; a partir de aquí las posibilidades son infinitas. El silencio atiza cada una de las posibilidades que nunca desarrollaré; y el eco resuena mudo en la caja metálica que encierra nuestros entes incorpóreos. Es posible que el rumor se propague fuera de la carcasa. No lo sé porque también he perdido la capacidad de escuchar los ruidos del más allá. Mis percepciones se cortaron de raíz, no podría precisar cuándo. —¿Con qué te quedas? —pregunta, escudriñando mi “rostro” para discernir si estaré en condiciones de responder algo sensato. Sabe que mi conciencia está llegando a la sala oscura. —Con los objetos, sin duda —reímos y sorbemos—. Los objetos somos la naturaleza del programa, la parte viva. Una

97

Integración con una base de datos: JPA, JDO, JPQL... BD que almacena la información como objetos, se puede integrar con el programa mediante el OBMDS 98

99

Interfaz gráfica de usuario basada en componentes Hebras para concurrencia 101 Aplicación Java que se ejecuta dentro de una página web 102 Programa Java que se ejecuta dentro de un servidor web 100

183

NURIA MEDINA

© Alfaomega - RC Libros

comunidad bien avenida en la que nos solicitamos ayuda, unos a otros, mediante el envío de mensajes. Siempre responsables, los objetos requeridos ejecutan los métodos implementados en sus clases. Sin duda, los objetos somos los que damos el callo para que el programa ejecute sus funcionalidades y logre sus objetivos. —¿Y las clases? ¿Qué función tienen en el programa? —pregunta, algo repuesto ante la coherencia de mi última parrafada. —Las clases cortan el bacalao. —¿Callos y bacalao? —sonríe—. ¿Tienes hambre, chaval? —Reímos y sorbemos. Hubo un breve stop, pero ahora, de nuevo, los latidos que marcan la cuenta atrás reaparecen y avanzan contenidos, incrustando sombrías pausas en nuestra última conversación. —Los objetos sois la unidad de ejecución y las clases son la unidad de programación —resume el señor Paradigma que, maestro hasta el final, no se resiste a dejar de emplear los términos correctos. —¿Qué fue antes la gallina o el huevo? —suelto de improviso. —No hay objetos sin clases, ni clases sin objetos. Es cierto —convierte en reflexión mi delirio y me cubre de besos. Pero me ha mentido como un bellaco: existen lenguajes de programación basados en prototipos donde no se contempla el concepto de clase, aunque no es el caso de Java; e, incluso en Java, pueden existir clases sin objetos (como debe ser por 184

© Alfaomega - RC Libros

JAVA. LA NOVELA

obligación cuando la clase es abstracta). Su batalla es que muera feliz, así que le perdono la imprecisión y soporto estoicamente sus besuqueos durante un rato. —No sea pegajoso —le aparto con cariño porque la manta de besos ya pesa—. Cuénteme por qué las clases son la unidad de programación. El señor Paradigma adopta pose de cuentacuentos y me narra una elaborada historia cuyo hilo conductor es que en la orientación a objetos en general (y en Java en particular) se programa escribiendo clases, y que es en los métodos de dichas clases donde se envían los mensajes a los objetos. El primer acto lo resuelve el método main 103 , que pone en marcha el programa. «Por eso» —insiste— «siempre debe existir un método main en una clase del programa». —Me ha gustado el cuento —dictamino cuando culmina, sin apenas fuerza—. Trata de un grupo de objetos colaborando para resolver un problema planteado en forma de clases. —¿Te agrada entonces ser un objeto? —Me encanta —reconozco desolado ante el final que me espera. —¿Más que ser un compilador? —formula de forma íntima.

103

public static void main(String[] args){...método por el que comienza la ejecución del programa...}

185

NURIA MEDINA

© Alfaomega - RC Libros

—Mucho más. El compilador trabaja solo y los objetos, en cambio, somos un equipo. Una “unidad de ejecución” para ser precisos —le guiño. Un destello ilumina una sonrisa en medio de la tiniebla. —¿Quién crea las clases? En su historia no mencionó quién las programa. —¿Por qué es tan importante para ti eso? ¿Sabes que será tu última pregunta? Tiemblo, pero persisto: —¿Quién crea las clases? Para entender completamente quién soy necesito saber quién es mi Dios. —¿Dios? —El Creador. El que ha dado vida a este programa. El alquimista que ha transformado ideas en objetos. El que me recogerá en su seno cuando el recolector de basura recicle mi espacio. —Parece sorprendido—. Pensamientos fuimos y en pensamientos nos convertiremos. Usted me lo enseñó. Lo contemplo con una mirada perdida de “ojos” negros. Esta será la última mirada que mantendremos tan fijamente; suena a incoherencia pero los sentimientos no entienden de órdenes ni de prosa. La mirada del adiós duele. Abrazo el dolor, es necesario para estampar recuerdos perennes y yo no quiero olvidarte. —Las clases son definidas por el programador —enuncia en un suspiro.

186

© Alfaomega - RC Libros

JAVA. LA NOVELA

—¿El programador está al otro lado, verdad? —pregunto al tiempo que el latido que detiene la cuenta atrás ruge en el “pecho” del señor Paradigma. Nunca más se escuchará mi voz. El estrépito con forma de rugido aguijonea el “órgano vital” del maestro y la vibración es palpable. Juan, el objeto, le acaricia la “piel” abultada del “pecho” y sigue el movimiento de cada pulsación. Despacio, apoya su “cabeza” sobre el “hombro” del “hombre” calvo. Mentalmente, le pide a su maestro que haga lo que tenga que hacer. Su confianza es plena. Si ha llegado su hora, está dispuesto a dejar su hueco libre. No tiene miedo del recolector de basura. El señor Paradigma le acaricia la “barbilla” y le besa en la “frente”. «No es eso lo que va a ocurrir, tranquilo», le susurra aunque sabe que se está saltando las normas. «Seguirás viviendo un tiempo», afirma y pulsa el botón de reset. Tras la “explosión”, el paradigma de orientación a objetos se aleja, aunque siempre estará ahí, esperando a que alguien especial quiera aprender de él. Camina despacio, meneándose como los cangrejos hacia atrás. No puede dejar de mirarlo. A su amigo, el objeto más excepcional que ha tenido la oportunidad de tutelar, al más inteligente. Ahora, un objeto al uso, uno más de la unidad de ejecución. Mientras lo observa, le llega una petición. El verdadero Juan ha sacado matrícula de honor en programación y la calificación debe ser anotada en su expediente. «Estás ejecutando el método maravillosamente», anima a su discípulo, aun cuando sabe que ya no puede escucharlo. 187

NURIA MEDINA

© Alfaomega - RC Libros

Lo echará de menos. Es cierto que pronto algún otro requerirá su ayuda, pero Juan ha sido un objeto único; hasta ahora y siempre. Hay amores que jamás se olvidan. «Mira que decirme que el programador es Dios», recuerda con añoranza cuando se obliga a darse la vuelta y continuar hacia delante. El futuro le espera. «El programador es el Dios de los objetos que conviven en el programa en ejecución...». «¡Qué ocurrencia!» «¡Cuánta razón...!»

Ilustración 14. El creador contemplando la creación.

188

© Alfaomega - RC Libros

JAVA. LA NOVELA

Plantillas para escribir clases e interfaces en Java En las plantillas de código, proporcionadas a continuación, se utiliza una notación BNF (Backus-Naur form) de acuerdo a la siguiente sintaxis: ::=

Definición de regla sintáctica

< > “”

Delimitadores de nombre de regla sintáctica

|

Delimitadores de carácter o secuencia de caracteres literal Separador de alternativas

()

Agrupador sin repetición

{}

Agrupador con repetición (0, 1 o más veces)

[]

Agrupador opcional (0 o 1 vez)

Plantilla para escribir una clase ::= <cuerpoClase >

<declaracionPaquetes>



Una clase está formada por una cabecera y un cuerpo (precedidos de una declaración de paquetes). 189

NURIA MEDINA

© Alfaomega - RC Libros

<declaracionPaquetes> {}

::=

[<paqueteClase>]

La declaración de paquetes también consta de dos partes. En la primera, se puede indicar el paquete en el que se integrará la clase que estamos creando; y en la segunda, se pueden importar otros paquetes cuyas clases van a utilizarse en los métodos de la clase actual. Observe que la declaración de paquetes puede quedar vacía. <paqueteClase> ::= “package” nombrePaquete “;” El nombre del paquete suele indicarse en minúscula y coincidirá con la carpeta donde se guarda la clase que estamos definiendo. El nombre del paquete podría ser una estructura de paquetes y subpaquetes del tipo docencia.grado, donde grado es un subpaquete de docencia. Estos niveles de paquetes y subpaquetes acabarán reflejándose en la estructura de carpetas y subcarpetas donde se almacena el fichero.java de la clase. ::= “import” nombreOtroPaquete “.” (“*” | nombreClaseAImportar) “;” Cuando se importa un paquete, se pueden incluir todas las clases del paquete (*) o una clase concreta dentro del mismo (nombreClaseAImportar). El nombre del paquete a importar (nombreOtroPaquete) puede indicar una estructura de paquetes y subpaquetes (por ejemplo java.util). 190

© Alfaomega - RC Libros

JAVA. LA NOVELA

::= [“public”] [“abstract”] “class” NombreClase [“extends” NombreSuperClase][“implements” NombreInterfazImplementada {“,” NombreOtraInterfazImplementada}] En la cabecera de la clase, lo primero que puede aparecer es la palabra reservada public. En caso de que aparezca significa que la clase es visible fuera de su paquete. Si no aparece, indica que la clase no se puede utilizar fuera de su paquete (no se puede importar). El término abstract debe aparecer obligatoriamente cuando la clase deja uno o varios métodos sin implementar. Estos métodos pueden estar declarados en el cuerpo de la clase o derivarse de la herencia e implementación de interfaces definida en su cabecera. De acuerdo a la convención de nombres 104 de Java, el identificador de la clase (NombreClase) que aparece tras la palabra reservada class debería ser un sustantivo escrito con el estilo UpperCamelCase. Esto significa que debe comenzar con mayúscula y cuando se requieren varias palabras, la primera letra de cada una de ellas también irá en mayúscula. La sentencia extends indica cuál es la clase padre (NombreSuperClase) de la clase que estamos definiendo. Si no se indica nada, se hereda por defecto de la clase Object. Después de la herencia, se puede indicar la interfaz o interfaces (separadas por comas) que la clase implementa. 104

Conjunto de reglas para la elección de la secuencia de caracteres que se utilizará en los identificadores que denotan variables, tipos, métodos y otras entidades en el código fuente y la documentación

191

NURIA MEDINA

<cuerpoClase> ::= {<declaracionMetodo>} “}”

© Alfaomega - RC Libros

“{“

{<declaracionVariable>}

Encerrado entre llaves, el cuerpo de la clase incluye las declaraciones de variables y métodos. Aunque no sería de mucha utilidad, el cuerpo de la clase podría dejarse vacío, es decir, sin declarar ningún atributo ni responsabilidad. Lo habitual es que se definan varias variables y varios métodos dentro del cuerpo de la clase. <declaracionVariable> ::= [“private” | “protected” | “public”] [“static”] [“final”] tipoVariable nombreVariable [“=” valor] “;” La declaración de una variable suele comenzar con el modificador de acceso que establece la visibilidad de la variable: privada, protegida o pública. Si no se indica nada, la visibilidad es package (paquete). Si se incluye la palabra static en la declaración de la variable, avisa de que es una variable de clase. En su defecto, es una variable de instancia (propia de cada objeto de la clase). Si se incluye el modificador final significa que una vez inicializada la variable, no se podrá cambiar su valor. Estos tres elementos (visibilidad, static y final) pueden ir en cualquier orden, aunque el aquí presentado es el más habitual. El tipo de la variable (tipoVariable) puede ser un tipo primitivo (int, char…), una clase o una interfaz.

192

© Alfaomega - RC Libros

JAVA. LA NOVELA

El nombre de la variable (nombreVariable) debería comenzar en minúscula, especialmente si es una variable de instancia. Si se usan varias palabras para formar el identificador de la variable, cada una de ellas debe comenzar en mayúscula (estilo lowerCamelCase). Finalmente, de forma opcional, se puede otorgar un valor inicial a la variable de acuerdo con el tipo declarado para la variable. *Si la variable ha sido declarada como final, la inicialización es obligatoria, ya que en realidad se trata de una constante. En este caso, el nombre de la constante, por convención, debería escribirse enteramente en mayúscula, separando las palabras con guiones bajos (_). <declaracionMetodo> ::= <declaracionMetodoAbstracto> | <declaracionMetodoNoAbstracto> La declaración de un método varía según sea un método abstracto o no. <declaracionMetodoNoAbstracto> ::= <cuerpoMetodo> <declaracionMetodoAbstracto> ::= “;” En el caso de los métodos abstractos, únicamente se proporciona la cabecera del método seguida de un punto y coma. En los métodos no abstractos, a la cabecera le sigue el cuerpo con la implementación de la responsabilidad asociada al método. ::= [“private” | “protected” | “public”] [“static”] [“final”] (tipoRetorno | “void”) nombreMetodo 193

NURIA MEDINA

© Alfaomega - RC Libros

“(“ [tipoArgumento nombreArgumento {“,” tipoArgumento nombreArgumento}] “)” La cabecera del método suele comenzar indicando la visibilidad del método: privado, protegido o público. Igual que en el caso de las variables, si no se indica nada, la visibilidad del método es package. Si se incluye la palabra static, el método es de clase. En su defecto, la responsabilidad de ejecutar el método es de sus instancias. Si se incluye la palabra final, se establece que el método no se podrá redefinir en las subclases de la clase actual. Estos tres elementos (visibilidad, static y final) pueden ir en cualquier orden, aunque el aquí presentado es el más habitual. La invocación del método puede proporcionar una respuesta tras su ejecución. En caso de que el método no devuelva nada, se indicará en su cabecera con la palabra reservada void. En caso de que sí devuelva, es necesario proporcionar el tipo del valor de retorno. Dicho tipo (tipoRetorno) puede ser un tipo primitivo, una clase o una interfaz. En este caso, también será obligada una sentencia return en el cuerpo del método. El nombre del método (nombreMetodo) debe ser significativo y como las variables utiliza el estilo lowerCamelCase. El método puede ir sin argumentos o necesitar uno o varios de estos para funcionar. Para cada argumento hay que 194

© Alfaomega - RC Libros

JAVA. LA NOVELA

indicar un tipo y un nombre. Los argumentos van entre paréntesis y separados por comas si hay más de uno. ::= [“private” | “protected” | “public”] “abstract” (tipoRetorno | “void”) nombreMetodo “(“ [tipoArgumento nombreArgumento {“,” tipoArgumento nombreArgumento}] “)” La cabecera de un método abstracto es igual que la cabecera de cualquier método salvo que, obligatoriamente, debe llevar la palabra reservada abstract. Si un método es abstracto no puede ser estático o final ya que el método no tendrá cuerpo y por lo tanto, necesariamente, se tendrá que redefinir en las subclases (directas o indirectas) de la clase actual. <cuerpoMetodo> ::= “{“ {sentencia} “}” El cuerpo del método delimita entre llaves un conjunto de sentencias que, aunque no es lo común, puede quedarse vacío. Cada sentencia representa una acción o secuencia de acciones, y en Java, todas las sentencias terminan con un punto y coma. Las sentencias pueden ser: literales, expresiones, sentencias de asignación, sentencias de selección, de repetición, devolución de un valor primitivo u objeto al finalizar la ejecución del método (return), etc. Plantilla para escribir una interfaz ::= <declaracionPaquetes> <cuerpoInterfaz>

195

NURIA MEDINA

© Alfaomega - RC Libros

Una interfaz, al igual que una clase, está formada por una cabecera y un cuerpo (precedidos de una declaración de paquetes). La declaración de paquetes para las interfaces funciona de modo similar que en las clases. ::= [“public”] “interface” NombreInterfaz [“extends” NombreSuperInterfaz {“,” NombreOtraSuperInterfaz }] En la cabecera de una interfaz, lo primero que puede aparecer es la palabra reservada “public” indicando que la interfaz es visible fuera de su paquete. El nombre de la interfaz, igual que ocurre con las clases, debe seguir el estilo UpperCamelCase. Las interfaces pueden heredar de ninguna, una o varias superinterfaces (separadas por comas si hay más de una) usando la palabra reservada extends. <cuerpoInterfaz> ::= {<declaracionMetodo>} “}”

“{“

{<declaracionConstante>}

Encerrado entre llaves, el cuerpo de la interfaz incluye las declaraciones de constantes y métodos. <declaracionConstante> ::= [“static”] tipoConstante NOMBRE_CONSTANTE “=” valor “;”

[“final”]

Por defecto (aunque no se ponga nada), las constantes de la interfaz son static final; ya que las interfaces no pueden instanciarse y las constantes no pueden modificar su valor.

196

© Alfaomega - RC Libros

JAVA. LA NOVELA

El tipo de la constante puede ser un tipo primitivo (int, char…), una clase o una interfaz. El nombre de la constante se suele poner en mayúscula, utilizando el guion bajo para separar las palabras cuando hay varias. En una interfaz solo se pueden definir constantes, con lo cual es obligatorio indicar un valor inicial. <declaracionMetodo> ::= “;” Los métodos no se implementan en la interfaz, únicamente se declaran. ::= [“public”] (tipoRetorno | “void”) nombreMetodo “(“ [tipoArgumento nombreArgumento {“,” tipoArgumento nombreArgumento}] “)” Por defecto (aunque no se ponga nada), en la interfaz los métodos son públicos. El tipo de retorno, nombre y argumentos funcionan igual que en los métodos de las clases. *Se podría utilizar el modificador abstract en los métodos de la interfaz, pero su uso está obsoleto ya que se sobreentiende que todos los métodos de la interfaz son abstractos (no tienen implementación).

197

NURIA MEDINA

© Alfaomega - RC Libros

*A partir de Java 8 se pueden añadir métodos default y métodos static en la definición de una interfaz Java para incluir en las interfaces métodos con implementación 105.

105

En opinión de la autora, esto tiene sus pros y contras, ya que amplía las posibilidades de reutilización de código pero desvirtúa ligeramente el concepto de interfaz como un contrato. Las clases abstractas ya permitían tener unos métodos implementados y otros sin implementar (aunque, evidentemente, no tenían herencia múltiple como es el caso de las interfaces). Esta novedad de Java 8 permite tener herencia múltiple de métodos a través de las interfaces

198

© Alfaomega - RC Libros

JAVA. LA NOVELA

Índice de contenidos

123, 124, 125, 126, 128, 132, 133, 136, 137, 138, 139, 140, 141, 142, 144, 145, 146, 147, 148, 149, 150, 151, 152, 156, 159, 160, 161, 162, 163, 167, 168, 169, 171, 174, 175, 176, 177, 178, 179, 180, 184, 185 clase abstracta, 139, 140, 141, 152, 167 clase hija, 115, 116 clase padre, 114, 115, 118, 122 clase parametrizada, 148 class, 55, 85, 89, 92, 108, 109, 132, 134, 135, 138, 139, 147, 150, 159, 162 Class, 175, 176, 177, 178, 179, 180 clone, 123, 124, 125, 126 código fuente, 25, 27, 37, 44, 51, 52, 55, 74, 80, 83, 94, 98, 100, 102, 110, 129 colección, 14, 69, 84, 104, 119, 149, 174, 176 compilación, 166, 168, 169, 174 compilador, 49, 52, 55, 158, 159, 160, 161, 162, 163, 164, 168, 169, 170, 174, 185, 186 constructor, 39, 40, 41, 42, 46, 104, 124, 135 consultor, 73, 75, 81, 82, 83, 124, 128

@ @Override, 116, 123, 126, 132

A abstract, 139, 141, 159, 162 API, 180 array, 177, 179 atributo, 13, 15, 41, 66, 68, 69, 73, 75, 78, 80, 81, 83, 84, 85, 86, 105, 107, 119, 120, 124, 126, 128, 134, 139, 144 atributos complejos, 68

B bytecode, 51, 52, 55

C cabecera, 27, 28, 33, 34, 88, 89, 92, 100, 105, 115, 116, 118, 119, 122, 123, 124, 125, 126, 138, 141, 147, 150, 160 canales de comunicación, 107, 110 casting, 169, 170, 174 clase, 25, 26, 29, 34, 35, 37, 38, 39, 40, 42, 43, 46, 54, 55, 67, 68, 73, 74, 75, 78, 80, 81, 82, 83, 86, 87, 88, 89, 90, 91, 92, 98, 100, 103, 104, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 119, 120, 122,

E encapsulación, 81, 87 encapsulamiento, 73, 74, 83, 124

199

NURIA MEDINA

© Alfaomega - RC Libros

estado, 14, 15, 16, 43, 47, 54, 66, 67, 69, 72, 73, 83, 85, 95, 111, 120, 131, 155, 156, 157, 165, 182 excepción, 105 excepciones, 105 Exception, 105 extends, 118, 119, 122, 123, 132, 134, 147, 150, 159, 161

122, 137, 145, 146, 152, 158, 161, 163, 166, 168, 169, 174, 179, 180, 182, 183, 184, 185 jerarquía de herencia, 123, 138

L ligadura dinámica, 165, 166, 168 ligadura estática, 166

F M

final, 20, 86, 90, 129, 138, 139, 151, 173, 175, 178, 184

main, 105, 185 manejo de excepciones, 105 mensaje, 20, 21, 23, 27, 28, 29, 34, 35, 40, 47, 54, 77, 86, 102, 103, 105, 106, 107, 108, 109, 111, 118, 126, 131, 132, 160, 161, 163, 166, 167, 168, 169, 171, 174, 175, 178, 179

G getClass(), 175, 176, 177, 178, 179

H heap, 56, 64, 65, 71 herencia, 111, 112, 113, 114, 115, 116, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 137, 138, 147, 152, 161

40, 41, 73, 74, 78, 81, 82, 84, 86, 87, 88, 90, 91, 93, 100, 102, 105, 109, 110, 111, 115, 116, 117, 119, 123, 124, 125, 127, 128, 130, 131, 132, 133, 138, 139, 141, 147, 151, 152, 160, 161, 166, 167, 168, 169, 175, 178, 179, 185, 187 modificador, 78, 83, 84, 86, 89, 90, 110, 116, 125, 138, 139, 141 modularidad, 90

I identidad, 43, 44, 65, 83 implements, 150, 162 import, 92, 100 interface, 147 interfaz, 20, 145, 146, 147, 148, 150, 151, 152, 156, 162, 163, 167, 168, 169, 179 intérprete, 38

N new, 40, 41, 58, 65, 66, 67, 103, 105, 114, 124, 126, 146, 162, 163, 167, 168, 177 null, 13, 102, 103 NullPointerException, 97, 102, 103, 104

J Java, I, III, 5, 6, 10, 11, 25, 27, 28, 31, 32, 33, 38, 49, 51, 52, 69, 73, 83, 88, 94, 98, 102, 104, 114, 118, 121,

200

© Alfaomega - RC Libros

JAVA. LA NOVELA

responsabilidad, 21, 29, 35, 82, 86, 103, 160, 169, 170 return, 27, 33, 81, 84, 124, 126, 132 reutilización, 111, 112, 114, 147, 148

O Object, 123, 125, 126, 137, 138, 150, 161, 174, 175, 177 objeto, 5, 6, 7, 9, 10, 11, 14, 15, 20, 21, 27, 29, 34, 40, 41, 42, 43, 44, 46, 47, 49, 50, 53, 57, 58, 59, 66, 67, 68, 69, 72, 75, 77, 78, 81, 84, 85, 86, 87, 93, 96, 98, 102, 103, 105, 107, 108, 109, 112, 123, 124, 126, 131, 132, 133, 137, 140, 145, 146, 148, 154, 156, 160, 161, 162, 163, 166, 167, 169, 170, 174, 175, 176, 177, 178, 179, 182, 185, 187, 188

S sobrecarga, 125 stack, 56, 58, 64, 65, 71, 84 static, 34, 35, 41, 86, 185 String, 13, 29, 80, 81, 83, 84, 85, 89, 109, 126, 135, 138, 180, 185 subclase, 115, 116, 122, 135, 140, 141, 142, 145, 160 super, 131, 132, 133, 135, 147 superclase, 116, 119, 122, 132, 135, 161, 177 System.out.println, 161

P package, 88, 89, 90, 92, 100, 117 paquete, 88, 89, 90, 91, 92, 117, 177 paradigma de programación, 6, 7, 9, 114, 155 polimorfismo de mensajes, 163, 168 private, 80, 81, 85, 86, 87, 88, 89, 120, 128, 134, 135, 139, 144 protected, 88, 93, 116, 117, 125, 126 pseudovariable, 108, 131 public, 82, 84, 87, 88, 89, 92, 105, 108, 109, 116, 117, 118, 119, 124, 125, 132, 134, 135, 138, 139, 141, 147, 150, 175, 185 puntero, 2, 3, 58, 59, 65, 66, 83, 84

T this, 108, 131, 132, 133, 134, 135 tipo dinámico, 166, 167, 168, 174 tipo estático, 166, 167, 174, 178 toString(), 109, 160, 161

V valores primitivos, 57, 107, 114 84, 85, 86, 87, 88, 93, 102, 103, 105, 108, 109, 117, 126, 127, 130, 134, 145, 156, 160, 162, 163, 166, 167, 169, 175, 178 variable de clase, 86, 87 Variable de instancia, 85 visibilidad, 78, 88, 90, 116, 178 void, 29, 33, 39, 84, 105, 108, 109, 119, 138, 147, 185

R recolector de basura, 49, 50, 52, 58, 186, 187 Redefinición, 115 reflexión, 175, 177, 179, 180, 184 regla de compatibilidad de tipos, 126, 145, 156, 162

201

Descar gado en: eybooks.co m

Related Documents


More Documents from "Reinaldo De Souza Guerra"

Descargado En
January 2021 1
February 2021 2
January 2021 0
Contabilidad Analitica
January 2021 1
January 2021 2