libro completo de java 2

Download Libro completo de java 2

If you can't read please download the document

Upload: aldo-zanabria

Post on 15-May-2015

9.065 views

Category:

Documents


54 download

TRANSCRIPT

  • 1. d.-&y;?%-,t..

2. Indice .Introduccion. ............................................................................................. 23Contenido del libro ......................................................................................... 24Requerimientos ............................................................................................. 25Otros recursos ................................................................................................ 26.1 Java bsico............................................................................................ 29Todo sobre Java ........................................................................................... 30 Orgenes del lenguaje Java ....................................................................... 32Todo sobre bytecodes ............................................................................... 32 La seguridad del lenguaje Java .................................................................33 Programas Java .......................................................................................34 Es Java 2 o Java 1.2? .............................................................................. 37Adquirir e instalar Java .................................................................................. 37 Qu ocurre con CLASSPATH? ................................................................ 38Cules son las novedades de Java 1.1? ......................................................... 39Qu est censurado en Java 1.1 ? ................................................................... 41Cules son las novedades de Java 2? ............................................................. 41Qu se censur en Java 2? ........................................................................... 44Escribir cdigo: creacin de archivos de cdigo ............................................. 44 3. Escribir cdigo: conocer las palabras reservadas de Java................................ 45Escribir cdigo: crear una aplicacin .............................................................. 48 public class app ...................................................................................... 49 public static void main[String[] args) ........................................................ 50 System.out.println("iHola desde Java!"); ................................................... 51Compilacin ................................................................................................... 51Compilacin: utilizando opciones en la lnea de comandos ............................ 52 Opciones de compilacin cruzada .............................................................. 55Compilacin: revisin de los mtodos censurados ..........................................55Ejecucin del cdigo ...................................................................................... 56Ejecucin de cdigo: utilizar las opciones de la lnea de comandos ...............59Conocimientos bsicos: comentar el cdigo ................................................... 61Conocimientos bsicos: importando paquetes y clases Java ........................... 64Conocimientos bsicos: buscar clases Java con CLASSPATH ...................... 66Crear applets ................................................................................................... 69Ejecutarapplets ...............................................................................................71Crear aplicaciones ventana.............................................................................. 72Ejecutar aplicaciones ventana ......................................................................... 73Diseo de programas Java ..............................................................................74 Rendimiento .............................................................................................. 75 Mantenimiento ........................................................................................... 75 Extensibilidad .......................................................................................... 76 Disponibilidad ........................................................................................... 76Distribucin del programa Java ...................................................................... 77.2 Variables. arrays y cadenas..................................................................79Variables ....................................................................................................79Tipos de datos .................................................................................................81Arrays ............................................................................................................. 82Cadenas........................................................................................................... 85De qu tipo de datos disponemos? ................................................................ 87Creacin de literales enteros ...........................................................................88Creacin de literales en coma flotante ...........................................................89 ..Creacion de literales booleanos.......................................................................91Creacin de literales carcter .......................................................................... 91Creacin de literales tipo cadena ....................................................................93Declaracin de variables de tipo entero ....................................................... 93 4. Declaracin de variables de tipo coma flotante ............................................... 94Declaracin de variables de tipo carcter ....................................................... 95Declaracin de variables de tipo booleano...................................................... 96Inicializacin de variables............................................................................... 98 . .Inicializaclondinmica ................................................................................... 99Conversin de tipos de datos ........................................................................ 100 Conversionesautomticas........................................................................100 Casting a nuevos tipos de datos ...............................................................101Declaracin de arrays unidimensionales ....................................................... 103Creacin de arrays unidimensionales............................................................104Inicializacin de arrays unidimensionales .....................................................105Declaracin de arrays multidimensionales.................................................... 105Creacin de arrays multidimensionales.........................................................106Inicializacin de arrays multidimensionales .................................................108Creacin de arrays multidimensionales......................................................... 109Longitud de un array .....................................................................................110La clase String ...........................................................................................110..Creacion de cadenas...................................................................................... 117Obtencin de la longitud de la cadena .........................................................119Concatenacin de cadenas ............................................................................ 120Obtencin de caracteres y substring ..............................................................121Bsqueda y reemplazamientos en cadenas .................................................... 122Cambio de maysculas a minsculas (o viceversa) en cadenas .................... 123Formateo de nmeros en cadenas ............................................................... 124La clase StringBufferr...................................................................................124.. de StringBuffers............................................................................. 125CreacionObtencin y establecimiento de longitudes y capacidades de StringBuffer .. 129Establecer caracteres en StringBuffers..........................................................130Aadir e insertar utilizando StringBuffers ....................................................130Borrar texto en StringBuffers........................................................................ 131Reemplazar texto en StringBuffers ............................................................... 132.3 Operadores. condicionales y bucles ...................................................135Operadores ................................................................................................135Condicionales ........................................................................................... 137Bucles ....................................................................................................... 139Precedencia de operadores ............................................................................ 140 5. Incremento y decremento: ++ y................................................................... 141NOT unario:.y ! ......................................................................................... 143Multiplicacin y divisin: * y / ..................................................................... 144Mdulo: % .................................................................................................... 145Suma y resta: + y ......................................................................................... 145Operadores de desplazamiento: >>> y . >=. java app Hola desde Java! No se trata de uno de los programas ms significativos, pero s es buenopara empezar. Veamos este programa lnea por lnea. 42. public class app Esta es la primera lnea de app-java: public class a99 {Esta lnea indica que estamos creando una clase de Java nueva llamadaapp. Despus de que esta clase la transformemos en bytecodes, la mquinavirtual de Java podr crear objetos de esta clase y ejecutarlos. Aprender todosobre las clases en el captulo 4; este cdigo es slo para empezar con laprogramacin Java. Observe la palabra clave public en el cdigo anterior. Esta palabra es unespecificador de acceso, sobre la que aprender ms en los captulos 4 y 5. Elespecificador de acceso public indica que esta clase est disponible en cual-quier parte del programa que la utilice.Observe adems que si construye una clase pblica, Java le obliga a dar unnombre al archivo. Es decir, slo puede tener una clase pblica en un archivocon extensin ".javaW. razn de esto es que el compilador de Java traduceLael archivo de extensin ".javan en un archivo bytecode con la extensin".class", lo que significa que appjava se convertir en app.class, y si JVMnecesita la clase app, sabr cmo mirar en el archivo app.class. Dado queJVM utiliza el nombre del archivo para determinar las clases pblicas quehay en l, slo se puede tener una en cada archivo. Por esa razn, el cdigopara la clase app debe estar en un archivo llamado app.java (observe que Javaes bastante particular en esto, y el uso de maysculas hay que tenerlo encuenta). La implementacin de la clase que estamos definiendo ahora, estar entrellaves: public class app Java siempre encierra bloques de cdigo entre llaves, es decir,{y }.Como ver en el captulo 4, el cdigo de un bloque tiene su propio alcance (suvisibilidad para el resto del programa). A partir de ahora, continuaremosconstruyendo nuestra aplicacin siguiendo con la siguiente lnea de cdigo. 43. public static void main[String[] args) Esta es la siguiente lnea de cdigo de nuestra aplicacin: public class app { public static void main(String[l arga) {Aqu estamos creando un mtodo de la clase app. Un mtodo en la progra-macin orientada a objetos es como una funcin o subrutina en la programa-cin estndar, un bloque de cdigo al que se le puede pasar el control y quepuede devolver un valor. Los mtodos permiten manejar fcilmente el cdigoen una unidad funcional sencilla; cuando llama a un mtodo, la mquinavirtual de Java ejecuta el cdigo de ese mtodo.Los mtodos sern tratados formalmente en el captulo 4, pero aqu la ideaes que estamos creando un mtodo llamado main, que es el mtodo que lamquina virtual de Java busca cuando inicia una aplicacin (las applets notienen mtodo main). Cuando encuentra el mtodo rnain, JVM le pasa con-trol, y nos situamos en la parte del cdigo que queremos ejecutar de estebloque de cdigo del mtodo.Antes de continuar hay varias cosas que observar. El mtodo main debedeclararse con el especificador de acceso public, lo que quiere decir quepuede ser llamado desde fuera de su clase. Tambin debe declararse comostatic, que significa, como veremos en el captulo 4, que main es un mtodode una clase, no un mtodo de un objeto. Cuando se termine de ejecutar, nodebe devolver ningn valor, por lo cual usamos la palabra void en este cdigo(en otras palabras, un valor de retorno de tipo void significa que actualmenteno devuelve valor). Finalmente, observe el argumento entre parntesis quesigue a la palabra main: String[] args. Aparece una lista de argumentos entreparntesis en la declaracin de un mtodo para indicar que los valores se lepasan al mtodo y que el cdigo del mtodo puede usarlo. En este caso,estamos indicando que a main se le pasa un array cuyos elementos soncadenas de caracteres, llamado args. Estos elementos son valores que sepasan desde la lnea de comandos cuando se inicia la aplicacin; por ejemplo,si escribe Ijava app Hola ah", entonces "Hola" y "ah" seran las dos cadenasdel array args. Todos los detalles se mostrarn en el captulo 4. Dado que nousaremos ningn argumento desde la lnea de comandos en esta aplicacin,no usaremos args en el cdigo del mtodo main. 44. Esta lnea de cdigo, entonces, inicia el mtodo main. Todo el trabajo deeste mtodo es visualizar el texto "Hola desde Java! ", lo que se realizar enla siguiente lnea de cdigo.System.out.println("iHola desde Java! "); El mtodo main tiene una lnea de cdigo: public class app I public static void main(String[] args)(System.out.println("iHola desde Java!");1 >Esta es la lnea de cdigo que hace todo el trabajo. En este caso, estamosusando el cdigo que los programadores de Sun ya han creado para visualizarel texto "Hola desde Java!". En particular la clase System del paquete java.lang.En Java, las libreras de clases se llaman paquetes y el paquete java.lang esten todo programa Java, lo que quiere decir que no hay que hacer nadaespecial para utilizarlo, a diferencia de otros paquetes Java. La clase Systemdel paquete java.lang incluye un campo (es decir, un miembro de datos de laclase) llamado out, y este campo, a su vez, tiene un mtodo llamado println,que hace que se visualice el texto.Para referirse al campo out de la clase System, usamos la terminologaSystern.out. Para utilizar el mtodo println del campo out, usamos la termi-nologa System.out.println. Para imprimir el texto "Hola desde Java!", se lopasamos a System.out.println cerrndolo entre comillas.Observe adems que esta lnea de cdigo termina con un punto y coma(;). Esto es algo que Java ha heredado de C y C++ (de hecho, Java haheredado muchas cosas de C y C++), y casi todas las sentencias de Java seterminan con punto y coma. Si no est acostumbrado a ello, lo conseguirrpidamente, ya que el compilador de Java rechaza la traduccin a bytecodeshasta que el punto y coma est en su sitio.Por lo tanto, hemos creado una nueva aplicacin y la hemos almacenadoen un archivo llamado app.java. Cul es el siguiente paso? Ejecutarlo. Eche-mos un vistazo al siguiente tema.CompilacinEl gran jefe, mascando un cigarro, permanece de pie detrs de ustedmientras guarda la nueva aplicacin Java en un archivo. "Hmm", dice el gran 45. jefe, nada impresionado. "Y ahora?" "Ahora", dice, "tenemos que compilar el programa y ya podremos ejecutarlo". "De acuerdo," dice el gran jefe. "Sorprndame".Para traducir un programa Java a un archivo bytecode que la mquina virtual de Java pueda utilizar, usar el compilador de Java, que se llama javac (por ejemplo, en las mquinas Windows, este programa se llamar javac.exe, que est en el directorio bin de Java). A continuacin se indica cmo usar javac en general:javac [opciones] [archivos fuente] [@archivos]Argumentos de javac: opciones: Opciones desde la lnea de comandos. archivos fuente: Uno o ms archivos que se van a compilar (como app-java). @archivos: Uno o ms archivos de la lista de archivos fuente.Para compilar app.java, usaremos este comando:C:javac app. javaEl compilador de Java, javac, toma el archivo app.java y (suponiendo que no haya errores) lo compila, traducindolo y creando un nuevo archivo Ilama- do app.class. Si hubiera errores, el compilador de Java nos avisar de que hay errores incluyendo qu Inea de cdigo est mal, como en este caso en el que hemos olvidado el mtodoprintln e intentamos usar uno llamado printline: C:javac app.java app.java:5: Method printline(java.1ang.String) notfound in classjava.io .Print Strearn.System.out.printline("iHo1a desde Java!"); 1 errorCuando app.java est compilado sin errores, el nuevo archivo, app.class, contiene todo 10 que la mquina virtual de Java necesitar para crear objetos de la clase app. Ya hemos creado app.class. Ahora, jcmo lo ejecutamos en JVM? Veamos el siguiente punto.Compilacin: utilizando opcones en la lnea decomandos "Hmm", dice el programador novato, "tengo un problema. Me gusta guar-dar todos mis archivos con extensin ".class" en el mismo directorio, pero 46. algunas veces se me olvida copiar las nuevas versiones de esos archivos enese directorio". "Hay una opcin del compilador que es perfecta para eso: laopcin -d. Usando esa opcin, puede situar los archivos creados por elcompilador en el directorio de destino que quiera". "Entonces, slo tengo queacordarme de utilizar esa opcin ...," dice el programador. Hay un buen nmero de opciones que se pueden usar con javac. Porejemplo, indicaremos cmo usar la opcin -d para situar el archivo app.class yen el directorio temp., que ya~existe que, en este caso, es un subdirectoriodel directorio actual: javac -d T e m p . app. java A continuacin se muestra la lista de opciones de javac. Observe que lasopciones que empiezan con -X (llamadas opciones no estndar) estn marca-das de esa forma por Sun ya que pueden cambiar en el futuro: -classpath ruta de acceso. Establece la ruta de acceso del usuario, sobrescribindola en la variable de entorno CLASSPATH. Si no se especifica CLASSPATH ni -classpath, la ruta de acceso es el directorio actual. Observe que si no se usa la opcin -sourcepath, la ruta de acceso se busca tanto para los archivos fuentes como para los archivos de clase. -d directorio. Fija el directorio de destino de los archivos de clase. Para los lectores que sepan qu son los paquetes Java, si una clase forma parte de un paquete, javac pone el archivo de clase en un subdirectorio que refleja el nombre del paquete, creando los directorios necesarios. Por ejemplo, si especifica -d c:clases y la clase se llama com.package1. Class1, el archivo de clases se llama c:clasescompackage lClassl .class. Si no se especifica la opcin -d, javac pone el archivo de clases en el mismo directorio que el archivo fuente. Observe que el directorio indicado por -d no se aade automticamente a su ruta de acceso de clases. -deprecation. Muestra una descripcin de cada uso o sobrescritura de un miembro o clase censurado. (Sin -deprecation, javac slo muestra los nombres de los archivos fuente que usan o sobrescriben miembros o clases censurados). -encoding. Fija el nombre codificado del archivo fuente. Si no se especifica -encoding, se usar el convertidor por defecto de la plataforma. -g. Genera todo la informacin de debugging, incluyendo variables locales. Por defecto, slo se genera el nmero de lnea e informacin del archivo fuente. 47. -g:none. Hace que el compilador no genere ningn tipo de informacinde debugging.-g:(lista de palabras reservadas). Slo genera algunos tipos de informa-cin de debugging, especificados por la lista de palabras reservadasseparadas por coma. Las palabras vlidas son source (informacin dedebugging del archivo fuente), lines (informacin de debugging delnmero de lnea) y vars (informacin de debugging de Ias variableslocales).-nowarn. Deshabilita todos los mensajes de aviso.-O. Optimiza el cdigo para la ejecucin en trminos de hacer msrpido el tiempo de ejecucin. Observe que utilizar la opcin -O puederalentizar la compilacin, producir archivos de clase ms grandes yhacer que el programa sea difcil de poner a punto. Observe que antes detener JDK 1.2, las opciones -g y -O no podan usarse juntas. Con JDK1.2, puede combinar -g y -O, pero puede obtener resultados inespera-dos, como prdida de variables o de cdigo.-sourcepath ruta de acceso de fuentes. Especifica la ruta de acceso de lasfuentes para las definiciones de clases o de interfaces. Al igual que conla ruta de acceso de clases, las- entradas se separan por punto y coma(;) y pueden ser directorios, archivos Java (con extensin ",jarW) oarchivos zip. Si usa paquetes, el nombre local de la ruta de accesodentro del directorio o del archivo debe reflejar el nombre del paquete,como ver ms tarde. Observe que las clases buscadas en la ruta deacceso de clase sern recompiladas automticamente si sus archivos decdigo fuente no se encuentran.-verbose. Crea la salida "verbose". Incluye informacin sobre cadaclase cargada y de cada archivo fuente compilado.-X. Visualiza informacin sobre las opciones no estndares.-Xdepend. Busca todas las clases que pueden ser utilizadas por losarchivos fuente ms recientes para recompilar. Esta opcin descubrirclases que necesitan serrecompiladas, pero puede ralentizar enorme-mente el proceso de compilacin.-Xstdout. Enva mensajes del compilador a System.out. Por defecto, losmensajes del compilador van a System.err, que ver ms tarde.-Xverbosepath. Describe las rutas de acceso y las extensiones estndarque fueron localizadas para buscar archivos fuente y de clases. 48. -Joption. Usa esta opcin para pasar una opcin al lanzador de Javallamado por javac. Por ejemplo, -J-Xms64m fija la memoria de inicio a64 MB. Aunque esta opcin no empieza con -X, no es una opcinestndar de javac. Es una convencin para pasar opciones a las aplica-ciones escritas en Java que se estn ejecutando en JVM. Opciones de compilacin cruzadaLas opciones de compilacin cruzada se consideran un tema avanzado de Java; javac soporta la compilacin cruzada, en la que las clases se compilan mediante un proceso autosuficiente (por defecto) y la implementacin de extensin de clases. Se debe utilizar -bootclasspath y -extdirs cuando se est hablando de compilacin cruzada. A continuacin se indican las opciones de compilacin cruzada:-target versin. Genera los archivos de clase que trabajar en JVM conla versin indicada. Por defecto se generan archivos de clase que soncompatibles con JVM 1.1 y 1.2. Las versiones soportadas por javac enJDK 1.2 son 1.1 (asegura que los archivos de clase generados serncompatibles con JVM 1.1 y 1.2; esto es por defecto) y 1.2 (generaarchivos de clase que se ejecutarn en JVM 1.2 pero no en JVM 1 .I).-bootclasspath ruta de acceso de arranque. Realiza la compilacin cru-zada contra el conjunto de clases de arranque indicadas. Al igual quecon la ruta de acceso de clases, estas entradas estn separadas por puntoy coma (;) y pueden ser directorios, archivos con extensinW.jar"oarchivos zip.-extdirs directorios. Realiza la compilacin cruzada contra los directo-rios indicados; los directorios estn separados por punto y coma (;).Cada archivo con extensin ".jarW los directorios indicados es locali- dezado automticamente por los archivos de clase.Compilacin: revisin de los mtodoscensurados"Bueno", dice el programador, " jcmo puedo cambiar todos los mtodos censurados para que sean correctos? Ahora que ya estoy en Java 2, no s lo que es obsoleto y lo que no". "Eso es fcil", responde. "El compilador de Java, javac, le dir si est usando un mtodo que ya ha sido abandonado. 49. Mejor an, puede usar la opcin -deprecation para asegurarse de tener todos los detalles".La opcin -deprecation es buena, y es la opcin estndar que utilizo para asegurarme de que estoy evitando los mtodos obsoletos. Supongamos que tiene un programa de 200 lneas, y que cuando lo intenta compilar, javac le devuelve este resultado:C :javac app . javaNote: app.java uses or overrides a deprecated API. Recompile with " - deprecation" for details.1 warning Esto no es de mucha ayuda. Sin embargo, utilizando la opcin -deprecation, puede conocer el problema exacto:C: >javac app.java -deprecationapp.java:109: Note: The method java.awt.Dimension s i z e 0 in classjava.awt.Component has been deprecated.x = ( s i z e 0 .width - fontmetrics.stringWidth(text) ) / 2 ;ANote: app.java uses or overrides a deprecated API. Please consultthe documentation for a better alternative.1 warningComo puede ver, el problema es que app.java utiliza el mtodo size en la lnea 109 y ese mtodo es obsoleto. Si se reemplaza por el mtodo de la nueva versin, getSize, se resuelve el problema.Ejecucin del cdigoEl gran jefe se est poniendo impaciente. Ha escrito usted una nueva aplicacin y la ha compilado sin errores a la primera (de lo que puede sentirse orgulloso), pero realmente no ha ocurrido nada que el gran jefe pueda ver. Es hora de ejecutar la nueva aplicacin.Las aplicaciones Java se ejecutan con el programa llamado java (en Windows, por ejemplo, es el archivo java.exe del directorio bin de Java). El programa java, llamado utilidad java, es lo que realmente ejecuta JVM. A continuacin puede ver cmo usar la utilidad java:java [opciones] clase [parmetro . . . 1java [opciones] -jar archivo.jar [parmetro . . .1Estos son los parmetros de las lneas anteriores: opciones. Opciones de la lnea de comandos, que se vern en otro apartado. 50. clase. Nombre de la clase a la que se llama. archivo.jar. Nombre del archivo de archivo Java (JAR) al que se llama. Se usa slo con -jar. Los archivos JAR se tratan en el captulo 23. Parmetro. Un parmetro de la lnea de comando que se pasa al mtodo main. Por ejemplo, para ejecutar la aplicacin llamada app, que est en el archi-vo app.class, podra ejecutar el siguiente comando en la lnea de comandos(observe que se omite la extensin".class" de app.class): java app El resultado aparecer inmediatamente: java app Hola desde Java! En la figura 1.4 puede ver cmo funciona en una ventana DOS bajoWindows. Eso es todo. Ya ha escrito, compilado y ejecutado su primera aplicacin.Felicidades!Figura 1.4. Ejecucin de una aplicacin en una ventana DOS. Observe que si su aplicacin no responde o si quiere pararla por algunarazn, puede pulsar Control-C. Si no funciona, intntelo con la tecla Esc. Adems, en este libro, ver cmo crear aplicaciones ventana, y cuandoejecute una de estas aplicaciones con la utilidad java, obtendr los resultadosque aparecen en la figura 1.5. Hay algo que hacer notar sobre la figura 1.5; la ventana consola (aqu unaventana DOS) est por debajo y espera que la aplicacin termine antes de 51. continuar (es decir, antes de que elprompt de DOS aparezca en este caso). Sino quiere que una ventana consola est asociada con su aplicacin ventana,puede utilizar la utilidad javaw, como se indica: j avaw appFigura 1.5. Ejecucin de una aplicacin ventana.A continuacin se indica cmo se utiliza javaw en general, igual que lautilidad java: javaw [opciones] clase [parmetro . . 1. javaw [opciones] -jar archivo.jar [parmetro . . . 1 Estos son los parmetros utilizados con javaw: opciones. Opciones de la lnea de comandos, que trataremos prxima- mente. clase. Nombre de la clase a la que se llama. Archivo.jar. Nombre del archivo de archivo Java (JAR) al que se llama. Se usa slo con -jar. Los archivos JAR se tratan en el captulo 23.Parmetro. Un parmetro de la lnea de comandos pasado al mtodomain.Cuando usted lanza una aplicacin ventana de Java como esta, la ventanaconsola no espera a que la aplicacin termine; si la est ejecutando en DOS,la aplicacin aparece y el prompt DOS reaparece en la ventana DOS. Esto daun sentido ms profesional a estas aplicaciones.De hecho, hay otro lanzador en Java 2, el lanzador oldjava, que Sunincluy para la compatibilidad hacia atrs. Este lanzador no soporta elframework de extensiones Java (ver el punto "Cules son las novedades de 52. Java 2?"). Proporciona compatibilidad hacia atrs cuando tiene una aplica-cin que utiliza el estilo de seguridad de Javal. 1, que es incompatible con lastcnicas de carga de clases de 1.2 (o quizs las clases que se estn cargandohan sido generadas o cambiadas de alguna forma que es incompatible con laestructura de clases de 1.2). En este libro estoy siguiendo Java 2, por lo queno se usar mucho el oldjava, pero si est migrando a Java 2 y necesita usar elmecanismo de carga de clases antiguo, es bueno saber que est ah. Tambinhay una utilidad oldjavaw. , As es como puede ejecutar una aplicacin, usando cualquier utilidad deJava: java, javaw u oldjava. Cuando lance una aplicacin java2, el compiladorJust In Time (JIT) compila los bytecodes y ejecuta la aplicacin. Mientras estemos enel tema de compilar y ejecutar el cdigo, hay otrodetalle que deberamos tratar: las opciones de la lnea de comando que sepueden usar con los comandos javac y java. Les echaremos un vistazo en losdos apartados siguientes.Ejecucin de cdigo: utilizar las opciones de lalnea de comandos"Bien," dice el programador, "tengo otro problema. He almacenado todosmis archivos con extensin ".class" en un directorio, pero no quiero estarcambiando a ese directorio para ejecutarlos". "Otro problema fcil de resol-ver," le dice. "Puede usar la opcin -classpath de la utilidad java o establecerla variable de entorno CLASSPATH para que el compilador de Java busquelas clases correctamente". 53. Esto es un ejemplo en el que se pone a funcionar el buclefor (observe queel bucle se empieza con el ndice a 1 y se termina cuando es mayor que 10, esdecir, el cuerpo del bucle se ejecuta exactamente 10 veces): public class app 1 public static void main(String[] args) { int loop-index; for (loop-index = 1; loop-index i 10, loop-index++) = { System.out.println("Esta es la iteracin nmero " + loop-index); 1 > 1 Este es el resultado: C:>java app Esta es la iteracin nmero 1 Esta es la iteracin nmero 2 Esta es la iteracin nmero 3 Esta es la iteracin nmero 4 Esta es la iteracin nmero 5 Esta es la iteracin nmero 6 Esta es la iteracin nmero 7 Esta es la iteracin nmero 8 Esta es la iteracin nmero 9 Esta es la iteracin nmero 10 Este es un ejemplo que se vio al principio del captulo; ste calcula elgrado medio de un estudiante despus de recorrer todos los grados e irlossumando (observe que se est declarando e inicializando el ndice a O en laexpresin de inicializacin): public class app { public static void main(String[l args) { double grades[l = {88, 99, 73, 5 6 , 87, 6 4 ) ; double sum, average; sum = 0; for (int loop-index = 0; loop-index < grades.length;loop-index++) C sum += gradesiloop-indexl; 1 average= sum / grades.length; System.out.println("Grado medio = " + average); 54. Este es el resultado del cdigo:C:>java appGrado medio = 7 7 . 8 3 3 3 3 3 3 3 3 3 3 3 3 3 Cuando se declara una variable del bucle (como loop-index en este ejem-plo), el alcance de esa variable est limitado al cuerpo del bucle for (elalcance de una variable es la parte del programa en la que se puede acceder aella, como veremos en el siguiente captulo). Observe que se pueden usar expresiones muy generales en un bucle for.En un bucle for, Java permite separar expresiones con una coma, como semuestra en el siguiente ejemplo en el que se utilizan dos ndices: public class app (public static void main(String[l args)for (int loop-index = 0, doubled = 0, loop-index java app El doble del ndice El doble del ndice El doble del ndice El doble del ndice El doble del ndice El doble del ndice El doble del ndice El doble del ndice El doble del ndice El doble del ndice El doble del ndice En un bucle for no es obligatorio rellenar todos los elementos; de hecho,se pueden utilizar sentencias null. Esto es un ejemplo en el que se sumantodos los elementos de un array en un bucle for que no tiene cdigo en sucuerpo: public class app {public static void main(String[] args) 55. {int arrayil = {l. 2, 3 , 4, 51, sum = 0;for (int loop-index = 0,loop-index < array.length;eum + = array[loop-index++]) ;System.out.println("La suma = " + sum);11Este es el resultado:c:>java aPPLa suma = 15Tambin se puede convertir un bucle while en un bucle for. A continua- cin se ha adaptado el ejemplo del factorial del punto anterior "Bucle while".public class app{public static void main(String[] args){int value = 6, factorial = 1, temp;temp = value;//copia temporal.for ( ;t- > O; ) {factorial *= temp-; 1System.out.println(value + " ! = " + factorial);11Bucles anidados "Estoy trabajando con arrays de dos dimensiones", dice el programador novato", y me gustara tener un bucle dentro de otro para poder recorrer las dos dimensiones". "Por supuesto que puede usar unos bucles dentro de otros", le contesta. Java permite anidar bucles, uno dentro de otro. Esto es un ejemplo en el que se ve cmo funciona (en este caso, se haya el valor medio de los elemen- tos de un array de dos dimensiones recorriendo todos los elementos con dos bucles for):public class app{ 56. public static void main(String[l args){ double array[l [ = {{l, 2 , 3 1 , l{ 3 , 2 , 1).{l, 2 , 3 ) ) ; int sum = O , total = 0; for(int outer-index = 0; outer-index c array.length; outer-index++) { for(int inner-index = 0; inner-index < array[outer-index1.length; inner-index++) {sum += array[outer-index] [inner-index];total++; System.out.println("Valor medio del a r r a y = " + (sum / total)) ;1}Este es el resultado:C:>java appValor medio del a r r a y = 2Sentencia breakEl programador novato tiene otro problema: "Estoy recorriendo un array multidimensional, y algunas veces, al insertarse en cinco bucles anidados, los resultados exceden el mximo valor permitido, por lo que quiero terminar todos los bucles. Cmo lo hago para que todos ellos terminen de forma natural?" "Usando la sentencia break", le responde.Algunos lenguajes incluyen la sentencia goto que se puede utilizar para saltarse alguna sentencia del cdigo, pero la mayor parte de los lenguajes consideran que goto no es estructurada (Java es de sos y no incluye la sentencia goto). Como Java no tiene una sentencia goto, soporta la sentencia break con este propsito.Se puede usar la sentencia break para terminar un bucle, como en el siguiente caso, en el que se termina un bucle si la suma es mayor que 12:public class app(public static void main(String[] args) { doublearrayll= 11, 2 , 3 , 4 , 5 , 6 , 7, 8, 9 , 10); int sum = 0: 57. for(int loop-index = 0; loop-indexc array.length; loop-index++) {sum += array [ loop-index] ;if (sum > 12) break;System.out.println("Recorriendo el bucle...");1 System.out.println("La suma excede el valor mximo."); 1 1 Este es el resultado: c:>java app Recorriendo el bucle. . . Recorriendo el bucle... ~ecorriendo el bucle . . . ~ecorriendo el bucle . . . La suma excede el valor mximo Qu ocurre si se quiere salir de varios bucles anidados? En ese caso, sepueden etiquetar los bucles e indicar de cul se quiere salir. Esto es unejemplo en el que se sale de un bucle doblemente anidado: public class app ( public static void main(String[l args)I double array[l [ l = {{l, 2, 31, ( 3 , 2 , 11, (1, 2 , 311; int sum = 0; outer: for(int outer-index = 0; outer-index < array.length; outer-index++) { inner: for(int inner-index = O; inner-index < array[outer-index] .length; inner-index++) (sum += array[outer-index][inner-indexl;if (sum > 3 ) break outer;1System.out.println("No voy a imprimir.");1System.out.println("E1 bucle ha terminado."); Este es el resultado: C:>java app ~l bucle ha terminado 58. Observe que si no se usa una etiqueta con la sentencia break, slo se saldr del bucle actual.Sentencia continue "Me gustan los bucles", dice el programador novato, "slo hay un proble- ma. Algunas veces, cuando estoy recorriendo un bucle, tengo un valor que no quiero usar y querra saltrmelo y pasar a la siguiente iteracin del bucle sin ejecutar nada. Puedo hacerlo?" "S, por supuesto", le responde. "Puede usar la sentencia continue". Para pasar a la siguiente iteracin de un bucle, se puede usar la sentencia continue. Esto es un ejemplo en el que se obtienen los inversos y se intenta evitar el inverso de O. Si el ndice del bucle actual es O, se pasa a la siguiente iteracin. Este es el cdigo:public class appIpublic static void main (String[ ] args) { foridouble loop-index = 5; loop-index > -5; loop-index-) ( if (loop-index == 0 ) continuo; System.out.println("E1 inverso de " + loop-index + - - " + (1 / loop-index)); 8s 1Este es el resultado del cdigo (observe que esta salida se ha saltado la lnea en la que el cdigo intenta calcular el inverso de O):C:>java appEl inverso de 5.0 = 0.2El inverso de 4.0 = 0.25El inverso de 3.0 = 0.3333333333333333El inverso de 2.0 = 0.5El inverso de 1.0 = 1.0El inverso de -1.0 = -1.0El inverso de -2.0 = -0.5El inverso de -3.0 = -0.3333333333333333El inverso de -4.0 = -0.25 59. m Programacinorientadaa objetos Este captulo es comn a cualquier programa de Java: programacin orien-tada a objetos (POO). La vimos en el captulo 1, ya que, sin ella, no se puedeescribir cdigo en Java. Ahora que ya conocemos la sintaxis bsica de Java,estamos preparados para trabajar, de manera formal, con la programacinorientada a objetos. La programacin orientada a objetos es, realmente, otra tcnica paraimplementar el famoso dicho d e la programacin: "divide y vencers". Laidea es encapsular datos y mtodos en objetos, de forma que cada objeto seasemiautnomo, encerrando mtodos y datos privados (es decir, internos) ysalvndolos del desorden general que les rodea. As, el objeto puede interactuarcon el resto del programa por medio de una interfaz bien definida por susmtodos pblicos (es decir, se les puede invocar desde fuera). La programacin orientada a objetos fue creada para gestionar programasms grandes y descomponerlos en unidades funcionales. Esto nos lleva alsiguiente paso, que consiste en dividir un programa en subrutinas, ya que losobjetos pueden contener mltiples subrutinas y datos. El resultado deencapsular partes de un programa en un objeto es que es concebido como unelemento sencillo y no hay que tratar todo lo que el objeto hace internamente. Como ya se vi en el captulo 1, suponga que su cocina est llena d etuberas, bombas, un compresor y todo tipo de interruptores para mantener la 60. temperatura ideal de la comida. Cada vez que esta temperatura sea demasiadoalta, habr que encender el compresor, abrir las vlvulas y empezar a moverlas bombas manualmente. Ahora bien, toda esa funcionalidad se puede cubrircon un objeto, un frigorfico, en el que todas esas operaciones se gestionaninternamente, realimentndose todas las partes de su interior de forma auto-mtica. Esta es la idea que hay detrs de la encapsulacin: parte de un sistema complejo que necesita mucha atencin y lo convierte en un objeto que gestio-na todo internamente con su propio trabajo y puede ser fcilmente, concebi-do, como un frigorfico. Si el primer principio de la programacin orientada aobjetos es "divide y vencers", el segundo es "fuera de la vista, fuera de lamente". 7En Java, la programacin orientada a objetos gira sobre algunos conceptosclave: clases, objetos, miembros de datos, mtodos y herencia. De formarpida, estos trminos significan: 1 Una clase es una plantilla desde la que se pueden crear objetos. La definicin de una clase incluye especificaciones formales para la clase y cualquier dato y mtodos incluidos en ella. Un objeto es una instancia de una clase, al igual que una variable es una7 instancia de un tipo de dato. Se puede pensar en una clase como el tipo de un objeto y se puede pensar en el objeto como una instancia de una clase. Los objetos encapsulan mtodos y variables de instancia. -7 Los miembros de datos son esas variables que forman parte de una clase y en ellas se almacenan los datos que usa el objeto. El objeto soporta variables de instancia, cuyos valores son especficos del objeto, y variables de clase, cuyos valores son compartidos entre los objetos de esa clase. 9 Un mtodo es una funcin construida en una clase u objeto. Se pueden tener mtodos de instancia y mtodos de clase. Con objetos, se usan los mtodos de instancia, pero se puede usar un mtodo de clase haciendo referencia, simplemente, a la clase por su nombre, sin requerir ningn objeto. 7 Herencia es el proceso que consiste en derivar una clase, llamada clase derivada, de otra, llamada clase base, y se pueden utilizar los mtodos de la clase base en la clase derivada. 7 Todos estos conceptos son importantes para la programacin orientada aobjetos y entraremos en cada uno de ellos con ms detalle. 61. ClasesEn la programacin orientada a objetos, las clases proporcionan una espe- cie de plantilla para los objetos. Es decir, si se piensa en una clase como un molde de galletas, los objetos que se crean a partir de ella, son las galletas. Se puede considerar que una clase es un tipo de objeto; se usa una clase para crear un objeto y luego se puede llamar a los mtodos del objeto desde este cdigo.Para crear un objeto, se invoca al constructor de una clase, que es un mtodo que se llama igual que la clase. Este constructor crea un nuevo objeto de la clase. En este libro, ya hemos creado clases; cada vez que se crea un programa Java, se necesita una clase. Por ejemplo, veamos el cdigo necesa- rio para crear una clase llamada app, que se almacena en un fichero llamado app.java (esta clase crea una aplicacin Java):public class app{public static void main(String[] args) I System.out.println~Hola desde Java! " ) ; 11Cuando se utiliza el compilador de Java, este fichero, app.java, se con- vierte en el fichero de bytecode app.class, que gestiona toda la especificacin de la clase app.Entonces, jcmo se crean objetos desde las clases? Veamos la siguiente seccin.En Java, a un objeto se le llama instancia de una clase. Para crear un objeto, se llama al constructor de una clase, que tiene el mismo nombre que 62. ella. He aqu un ejemplo en el que se crea un objeto de la clase String, pasando la cadena que se quiere incluir en ese objeto al constructor de la clase String:String S = new String(" Hola desde Java! " ) ;Se ver ms sobre la creacin de objetos con constructores a lo largo de este captulo. Qu se hace con un objeto cuando se dispone de otro? Se puede interactuar con l usando sus miembros de datos y mtodos; veamos las dos secciones siguientes.Miembros de datosLos miembros de datos de un objeto se llaman miembros de datos de instancia o variables de instancia. Los elementos de datos compartidos por todos los objetos de una clase se llaman miembros de datos de clase o variables de clase. En este captulo, se ver cmo se crean variables de instancia y variables de clase. Los miembros de datos pueden hacerse accesi- bles desde fuera de un objeto, o se puede hacer que sean internos al objeto para usar, de forma privada, los mtodos del interior del objeto.Esto es un ejemplo en el que se muestra cmo se deberan utilizar los miembros de datos de un objeto. Supongamos que se tiene una clase llamada Data-class, y se crea un objeto de esta clase llamado datal:Data-class datal = new Data-class(" Hola desde Java!");Si Data-class define un miembro de dato que es accesible pblicamente llamado data, se puede hacer referencia al miembro de dato de datal usando el operador punto (.), como sigue:datal-dataEsto significa que se pueden meter los datos en datal, de la siguiente forma:Data-class data1 = new Data-class(" Hola desde Java!");system.out.println(datal.data);De esta forma, se puede hacer referencia a los miembros de datos de un objeto que lo hace accesible pblicamente.Por otro lado, recordemos que el poder invocar esos datos ocultos es una de las motivaciones de la programacin orientada a objetos, y dar acceso a 10s datos internos de un objeto desde un cdigo externo al mismo no es buena 63. idea. En su lugar, muchas veces se da acceso a los datos de un objeto a uncdigo externo slo a travs de los mtodos del objeto (lo que significa que sepuede controlar la interfaz del objeto para el resto del programa, comproban-do los valores de los datos antes de que esos valores sean almacenados en losmiembros de datos del objeto).Mtodos Los mtodos son funciones de una clase. Generalmente los mtodos sedividen en aquellos que se usan internamente en la clase, llamados mtodosprivados (private), los que se usan fuera de la clase, llamados mtodos pbli-cos (public) y los que son usados por la clase y sus derivadas, llamadosmtodos protegidos (protected). Los mtodos privados son, generalmente, llamados en el interior del obje-to por otras partes del mismo. En el ejemplo del frigorfico que propusiimosal principio de este captulo, el termostato puede invocar un mtodo internollamado start-compressor cuando llegue el momento de enfriar. Una vez que se tiene un objeto que soporta mtodos, se pueden usar losmtodos de esos objetos. En el ejemplo siguiente, se usa el mtodo calculatepara trabajar con los dos valores de operandl y operand2 y almacenar elresultado del clculo en result:Calculator calcl = new Calculator();result = calcl.calculate(operandl, operanda); Java soporta dos tipos de mtodos: mtodos de clase y mtodos de instan-cia. Los mtodos de instancia, como en el ejemplo calculate, son invocadosen objetos (es decir, los objetos son instancias de una clase). Los mtodos declase, por otro lado, son invocados en una clase. Por ejemplo, la clasejava.lang.Math tiene un mtodo de clase llamado sqrt que calcula una razcuadrada, y se puede usar como sigue (no es necesario un objeto):public class appIpublic static void main(String[l args)(double value = 4, sqrt;sqrt = iath.sqrt(value);System.out.println("La raz cuadrada de " + value + " = "+ sqrt);11 64. Esto es lo que se puede ver cuando se ejecuta el cdigo: C:>java app La raz cuadrada de 4.0 = 2.0En este captulo, aprender cmo se crean mtodos de clase e instancia.Antes de entrar en el cdigo, hay un concepto ms dentro de la orientacin a objetos: la herencia.HerenciaLa herencia es uno de los aspectos de la programacin orientada a objetos que se ha definido formalmente. Utilizando la herencia, se puede derivar una nueva clase a partir de una antigua, y la nueva heredar todos los mtodos y miembros de datos de la antigua. La clase nueva se llama clase derivada y la clase original, clase base. La idea es aadir lo que se quiera a la nueva clase para darle ms funcionalidad que a la clase base.Por ejemplo, si se tiene una clase llamada vehculo, se podra derivar una nueva clase llamada coche y aadir un nuevo mtodo llamado claxon que visualiza "beep" cuando se le llama. De esta forma, se ha creado una nueva clase de la clase base y hemos ampliado esa clase con un mtodo adicional.La herencia es un tema importante en Java, ya que se puede usar la gran librera de clases disponible, derivando de ellas nuestras clases propias. Ve- remos cmo utilizar la herencia orientada a objetos en el captulo siguiente. Ahora que ya hemos visto los conceptos de POO, es hora de que vayamos a la seccin siguiente y revisarlos P O 0 en detalle. Todo este material es esencial para la programacin de Java, por lo que conviene profundizar en l hasta que se domine.Declaracin y creacin de objetosEl programador novato aparece, preparado para discutir la programacinorientada a objetos. "Ya s todo sobre los objetos", dice, "slo ..." "Slo qu?" le pregunta. "Slo que no s cmo crear un objeto en un programa". Antes de utilizar un objeto, es necesario declararlo. Se pueden declarar objetos de la misma forma que se declaran variables de tipo de datos senci- llos, pero se puede usar la clase como tipo de objeto. Adems, se puede usar el operador new para crear objetos en Java. Veamos un ejemplo que utiliza la clase String. 65. Para empezar, declararemos un nuevo objeto, s l , de la clase String: public class app I public static void main(String[] args) { String sl; Aunque al declarar una variable simple se crea esa variable, la declaracinde un objeto no la crea. Para crear el objeto se puede usar el operador new conel siguiente formato en el que se pasan parmetros al constructor de laclase: object = new clase([parmetrol [ , parmetro2 . . . 1 1 1 ; La clase String tiene varios constructores, como vimos en el captulo 2. Sepueden pasar cadenas entre comillas a uno de los constructores de la claseString; por lo que se puede crear el nuevo objeto, s l , como sigue: public class app I public static void mainString[l args) { String SI; sl = new String("iHo1a desde Java!"); Ahora, el nuevo objeto, s 1, existe y ya se puede utilizar. Por ejemplo, paraconvertir todos los caracteres de s l a minscula, se puede usar el mtodotoLowerCase de la clase String: Adems se pueden combinar la declaracin y creacin en un solo paso.Esto es un ejemplo en el que se declara un nuevo objeto String, s2, crendolocon el operador new, todo en una lnea: 66. public class app i public static void main(String[l args) I String sl; sl = new String(";Holadesde Java! " ) ; String s2 = new String(";Hoia desde Java!"); Las clases, con frecuencia, tienen varios constructores, cada uno de loscuales tiene diferentes especificaciones de datos (es decir, diferentes tipos ynmero de parmetros; el compilador sabe qu constructor es el que se quiereusar por el tipo y por el nmero de parmetros). En trminos de orientacin aobjetos, estos constructores estn sobrecargados (se ver la sobrecarga eneste captulo). Por ejemplo, el constructor de la clase String est sobrecargado para cogerarrays d e caracteres, as como cadenas de texto, por lo que se puede crear unobjeto nuevo, s3, usando un array de caracteres: public class app i public static void main(String[] args) { String s1; sl = new String("iHo1a desde Java! " ) ; String s2 = new String("iHo1a desde Java!");Char cl[] = {H,o n , -111 -h, t , ) ;String s3 = new String(c1); Algunas veces las clases tendrn mtodos que devuelven objetos, lo quequiere decir que usarn internamente el operador new (y nosotros no lotenemos). Esto es un ejemplo en el que se usa el mtodo valueOf de la claseString, para convertir un double en un objeto String: public class app { public static void main(String[] args) { String sl; sl = new String("iHo1a desde Java! " ) ; 67. String s2 = new String("Hola desde Java!"); char cl[] = {H, o,1. a, , a,h p , t r ) ; String s3 = new String (cl); double doublel = 1.23456789; String s4 = String valueOf(doub1el): Adems, se puede asignar un objeto a otro, como se puede ver aqu: public class app t public static void main(String[] args) { String SI; s1 = new String("iHo1a desde Java!"); String s2 = new String("iHo1a desde Java!"); char cl[] = {H, o, l, a, , a, h,) ; String s3 = new Stringcl); double doublel = 1.23456789; String s4 = String.valueOf(doublel); String 85; s5 = al; Internamente, lo que est ocurriendo realmente es que la referencia alobjeto de s l se copia en s5. En la prctica, esto significa que s l y s5 serefieren al mismo objeto. Esto es importante saberlo, porque si se cambian los datos de instancia des l , tambin se estn cambiando los de s5 y viceversa. Si dos variables hacenreferencia al mismo objeto, hay que tener cuidado; muchas referencias a unmismo objeto pueden producir errores que son muy difciles de detectar. Estogeneralmente ocurre porque se cree que se est tratando con diferentes obje-tos. Al final del cdigo anterior, se visualizan todas las cadenas creadas. Estoes lo que aparece al ejecutar el programa: 68. C:>java app Hola desde Java! Hola desde Java! Hola ah 1.23456789 ;Hola desde Java! As es como se declaran y se crean los objetos, de la misma forma que sedeclaran y crean variables sencillas, con el valor aadido de poder configurarobjetos pasando datos a un constructor de la clase. Ya es hora de empezar acrear nuestras propias clases y empezaremos con este proceso en el siguientepunto.Declarar y definir clases El programador novato (PN) est nervioso y dice, "LO he conseguido!He creado un objeto, y funciona!" "Bien", le dice, con aprobacin, "ahoracmo se creara una clase?" "Uh-oh", dice el PN "cmo se hace?" En Java, la creacin de una clase se realiza en dos pasos: la declaracin dela clase y su definicin. Con la declaracin se dice a Java lo que necesitasaber sobre la nueva clase. Esta es la forma general de la declaracin de unaclase: [access] class nombre de clase [extends ...] [implernents ...1 i//aqu va la definicin de la clase. 1La implementacin de la clase es lo que se llama definicin de clase, y sehace en el cuerpo de la declaracin, como se ve en el ejemplo anterior. Esta esla forma general de una definicin y declaracin de la clase: access class nombre de clase [extends . . . ] [implements . . . 1 { [accessl [staticl tipo variable-de-instancial; [access] [staticl tipo variable-de-instanciaN; [accessl [staticl tipo mtodo1 (lista-deqarmetros)( 69. [accessl [ s t a t i c l tipo mtodoN (lista-deparmetros) ( Aqu, la palabra clave static convierte variables en variables de clases omtodos en mtodos de clase (en contraposicin a las variables y mtodos deinstancia), como veremos ms tarde. El trmino access especifica la accesibi-lidad de la clase o de un miembro de clase al resto del programa y puede serpublic, private o protected. Adems, hay un acceso por defecto si no seespecifica ningn tipo; se ver ms sobre esto en las pginas siguientes. Seusan las palabras clave extends e implements con la herencia, como veremosen el siguiente captulo. Con un ejemplo, quedar claro. Para empezar, crearemos una clase muysencilla llamada printer que define un mtodo, print (ya vimos este ejemploen el captulo 1). Cuando se llama al mtodo print, se visualiza el mensaje"iH01a desde Java!" en la pantalla. As sera la clase: class printer ( public void print0 C System.out.println(~ola desde Java!); 1 > Ahora se puede usar el mtodo print en otras clases, como en este ejem-plo, en el que se est creando un nuevo objeto de la clase printer usando eloperador new y el mtodo print de ese objeto en una aplicacin llamada app: class printer ( public void print0 ( System.out.println("Hola desde Java! " ) ; 1 1 public class app ( public static void main(String[ 1 args) C printer printerl = new printer( ); 70. Ahora se pone este cdigo en un fichero, app.java, se compila y se ejecuta como sigue: C:>java app Hola desde Java! Tomemos un momento para estudiar este ejemplo; observe que se estndeclarando y definiendo dos clases, printer y app, en el mismo fichero. Enun fichero slo una clase puede ser declarada como pblica y en este caso, esapp. Al fichero se le da el nombre despus de esa clase, lo que quiere decirque el fichero que la contiene debe ser app.java. Sin embargo, se puedentener tantas clases privadas o protegidas como se quiera dentro del fichero (yJava crear diferentes ficheros con extensin ".class"cuando se compile). Tambin se puede dividir este ejemplo en dos ficheros, uno para cadaclase. Este es printer.java: class printer ( public void p r i n t 0 I System.out.println("iHola desde Java! " ) ; 1 1 Y este es el nuevo app.java (observe que se tiene que importar la claseprinter para poder utilizarla; para ms detalles sobre la importacin de clases,ver el captulo 1): import printert public class app ( public static void main(String[l args) ( printer printerl = new p r i n t e r 0 ;Crear variables de instancia "Hmm", dice el programador novato (PN), "quiero crear una clase paraalmacenar datos, y tengo todo menos un pequeo detalle" "S?" pregunta.le"Cmo almaceno datos en la clase?" pregunta el PN. 71. En la clase, se pueden almacenar datos de dos formas, como variables deinstancia o como variables de clase. Las variables de instancia son especfi-cas para los objetos; si se tienen dos objetos (es decir, dos instancias de unaclase), las variables de instancia de cada objeto son independientes de lasvariables de instancia del otro objeto. Por otro lado, las variables de clase deambos objetos se referirn a los mismo datos y por lo tanto tendrn el mismovalor. En primer lugar, echemos un vistazo a las variables de instancia. As es como se almacenan datos de instancia en una clase: access class nombre de clase [extends . . . ] [implements ... 1 ( [access] tipo variable-de-inctancial; [access] tipo variable-de-instanciaN; ) Este es un ejemplo en el que se crea una clase llamada Data que gestionauna variable de instancia de tipo String llamada data-string, que contiene eltexto " iHola desde Java!" : clasci Data c public String data-etring = wyHola desde Javalm; 1 Ahora, se puede crear un objeto, llamado data, de la clase Data en main yhacer referencia a la variable de instanciadata-stringcomo data-data-string.As es el cdigo: class Data ( public String data-string = "iHola desde Java!"; ) public class app ( public static void main(String[l args) { Data data = new Data(); String etring - data.data-etring;Como se puede observar, se puede acceder a las variables de instanciapblicas de un objeto con el operador punto. Sin embargo, recuerde que una 72. de las motivaciones de la programacin orientada a objetos es mantener la privacidad de los datos. Veremos esto con ms detalle en la siguiente seccin.Acceso a variables"Hey", dice el programador novato, "crea que los objetos encapsulaban los datos de forma privada, cmo ese jorobado Johnson ha podido acceder a los datos de mis objetos?" "Porque utiliz un especificador de acceso errneo para sus datos", le dice.Se puede usar un especificador de acceso, llamado access en el siguiente cdigo, para fijar la visibilidad de los miembros de datos de una clase a lo largo del resto del programa:access class nombre de clase [extends ... ] [implements ...1I[access] [static] tipo variable-de-instancial;[access] [static] tipo variable-de-instanciaN;1Los valores posibles de access sonpublic, private y protected. Cuando se declara un miembro de una clase como public, es accesible desde cualquier lugar del programa. Si se declara como private, slo es accesible desde la clase de la que es miembro. Si se declara como protected, est disponible para la clase actual, otras clases del mismo paquete (se pueden agrupar libreras de clases en paquetes Java; ya se han visto algunos paquetes Java como java.lang, y se ver cmo crear paquetes customizados ms tarde en el libro), y clases que son derivadas de esa clase. Si no se usa un especificador de acceso, el acceso por defecto es que el miembro de la clase es visible a la clase de la que es miembro, a las clases derivadas de la misma que estn en su mismo paquete y a otras clases del mismo paquete. Los detalles se pueden ver en la tabla 4.1. Por ejemplo, si se quisiera hacer, en el ejemplo de la seccin anterior, que la variable de instancia data-string fuera privada a la clase Data, se podra declarar private como sigue:class DataIprivate String data-string = -1Hola desde Javalm;>public class app 73. {public static void main(String11 args) { Data data = new Data(); String string = data.data-string;Ahora, si se intenta acceder a la variable de instancia data-string desde otra clase, como se hizo anteriormente en la clase app, el compilador de Java devolver:C : >javac app.java -deprecationapp.java:lZ: Variable data-string in class Data not accessiblefrom class app. String string = data.data-string;A1 errorTabla 4.1. Alcance del especificador de acceso ( x = dentro del alcance). 1 Misma clase xx x x 1Subclase del mismopaqueteNo subclase del mismo x x xpaquete 1 Subclase de otro paquete xINo subclase de otropaqueteCrear variables de clase"Oye", dice el programador novato, "tengo una nueva clase llamada counter, y necesito llevar un contador total en una variable llamada counter para todos los objetos de esa clase. Y ahora qu? Estoy hundido". "No se hunda", le dice. "Slo necesita usar una variable de clase".El valor de una variable de clase es compartido por todos los objetos de esa clase, lo que significa que ser el mismo para todos los objetos. Una variable se declara como esttica con la palabra clave static (que realmente 74. especifica la forma en que el valor es almacenado, como dato esttico, encontraposicin a otras variables, que se almacenan de forma dinmica enpilas): access class nombre de clase [extends ... ] [implements . . . 1 I [access] static tipo variable-de-instancial; [access] static tipo variable-de-instanciaN; 1 Esto es un ejemplo en el que se crea una clase llamada data con unavariable de datos de clase llamada intdata: class data ( public static int intdata = 0; 1 Ahora se pueden crear dos objetos de la clase data: a y b. Cuando se pongala variable intdata para a con el valor 1, la variable intdata para b sertambin puesta a 1, como se puede ver aqu: class data ( public static int intdata = 0; 1 public class app ( public static void main(String[] args) I data a, b; a = new d a t a 0 1 b = new data0; System.o~t.println(~E1valor de b-intdata =" + b.intdata); 1 1 Este es el resultado del cdigo: C:>java app El valor de b.intdata = 1Si se necesita ejecutar algn clculo para inicializar variables estticas, sepuede hacer en un bloque de cdigo esttico, que se etiqueta con la palabra 75. clave static; este cdigo se ejecuta slo una vez, cuando la clase se carga porprimera vez: class data {public static int intdata = 1 ;public static int doubledintdata;staticcdoubledintdata = 2 *intdata;1 1 public class app {public static void main(String[] args){data a;a = new data0 ;System.out.println(E1 valor de a.doubledintdata = "ia.doubledintdata);1 1 Este es el resultado del cdigo: C:>java app El valor de a.doubledintdata = 2Crear mtodos"De acuerdo", dice el programador novato, "ya tengo variables de instan-cia. Hay algo ms que aprender sobre clases?" "Bastante", le dice. " Tomeuna silla y hablemos sobre la creacin d e mtodos".Llevamos usando mtodos desde que visualizamos nuestro primer mensa-je con S~stem.out.println,por lo que ya est familiarizado con el concepto.Un mtodo es un bloque de cdigo al que se puede transferir el control y porlo tanto, ejecutar ese cdigo. As es cmo se crean mtodos en una clase: access class nombre de clase [extends . . .1 [implements . . .1{[access] [static] tipo mtodo1 (lista de parmetros){ 76. [accessl [staticl tipo mtodoN (lista de parmetros){Para declarar y definir un mtodo, se puede usar un especificador deacceso (ver el siguiente punto) y especificar el tipo de retorno del mtodo sise quiere que devuelva un valor. Ejemplos de ellos son int,float, tipo objecto void, si el mtodo no devuelve ningn valor. S e da el nombre del mtodo yse sita la lista de parmetros que se le quieren pasar despus de ese nombre.El cuerpo actual del mtodo, el cdigo que se ejecutar cuando se le llame,est encerrado en un bloque de cdigo que sigue a la declaracin del mtodo. Veamos un ejemplo. De hecho, ya ha visto uno antes en este captulo, laclaseprinter. En ese ejemplo, se aadi un mtodo pblico llamadoprint a laclaseprinter, se cre un objeto de la claseprinter y se llam al mtodoprint,como sigue: c l a s s printer public void p r i n t ( ) S y s t e m . o u t . p r i n t l n ( V o l a desde Java!");1 1 public class app ( public static void mainString[] args){ printer p r i n t e r l = new p r i n t e r ( ) ; printerl .print ( ;1 1 1 En este caso, el mtodo print no tiene parmetros y no devuelve ningnvalor, pero se siguen poniendo los parntesis despus del nombre del mtodo;es obligatorio cuando se est llamando a un mtodo en Java ya que es laforma en que el compilador Java sabe que print es un mtodo y no unmiembro de datos). Esta es la salida del cdigo: 77. C:>java app H o l a desde Java!Hay muchas cosas que conocer sobre la creacin de mtodos en Java, por lo tanto, vamos a verlas a lo largo de los siguientes puntos. Uno de los aspectos ms importantes de los mtodos es que se puede hacer que sean puramente internos a un objeto, con el concepto de encapsulacin de la programacin orientada a objetos, y por ah es por donde vamos a empezar.Establecer el acceso a los mtodos "Ese maldito Johnson", dice el programador novato (PN), "ha estado utilizando los mtodos internos de mis objetos, aunque yo claramente llam al mtodo internal-use-only. No hay nada ms riguroso que pueda utilizar para aislar a ese jorobado?" "S", le dice, "puede usar un especificador de acceso ms riguroso". "Fantstico! " dice PN. A los mtodos de una clase se les puede aadir un especificador de acceso, como sigue (access es el especificador de acceso):access c l a s s nombre de clase [extends . . . ] [implements... 1{ [ a c c e s s ] [ s t a t i c ] tipo mtodo1 (lista de parmetros) I [access] [ s t a t i c ] tipo mtodoN (lista de parmetros)Los valores posibles de access son public, private y protected. Cuando se declara un miembro de una clase como public, es accesible desde cualquier lugar del programa. Si se declara como private, slo es accesible desde la clase de la que es miembro. Si se declara como protected, est disponible para la clase actual, otras clases del mismo paquete y clases que son deriva- das de esa clase. Si no se usa un especificador de acceso, el acceso por defecto es que el miembro de la clase es visible a la clase de la que es 78. miembro, a las clases derivadas de la misma que estn en su mismo paquete y a otras clases del mismo paquete. Los detalles se pueden ver en la tabla 4.1.Esto es un ejemplo en el que se ha aadido un mtodo private a la clase printer desarrollada en las secciones anteriores. Este mtodo slo puede ser llamado desde otros mtodos de la clase printer, como sigue:class printer{public void print ( ){internal-use-only();}private void internal-use-only()ISystem.~ut.println(~;Holadesde Javalm);11public class app{public static void main(String[] args){printer printerl = new printero;Cuando se llama al mtodo print de la clase printer, se utiliza el mtodo internal-use-only, que no est accesible fuera del objeto, para hacer la visua- lizacin. Este es el resultado del cdigo:C:>java appHola desde Java! -Con frecuencia, es una buena idea hacer que los mtodos sean privados o protegidos, ya que se reduce o se controla la accesibilidad del mtodo al resto del cdigo.Pasar parmetros a los mtodosEl especialista en soporte a clientes de la empresa le llama y le dice, "Tenemos un problema". "Cul es el problema?" le pregunta. "Su clase printer visualiza un mensaje, pero los clientes se estn quejando porque quieren poder fijar el mensaje que se va a visualizar". "No hay problema", le contesta. "Cambiar el mtodo print para que acepte parmetros". 79. Cuando se declara un mtodo, se puede especificar una lista de parmetrosseparados por comas, que se pasa al mtodo ponindola entre parntesisdespus del nombre del mtodo: [accessl [ s t a t i c l tipo mtodo1 ([tipo nombre-degarmetrol [, tiponombre-deqarmetro2. . . 1 1 1 Los valores que se pasan al mtodo estarn accesibles en el cuerpo delmismo, usando los nombres que se les ha dado en la lista de parmetros. Esto es un ejemplo en el que al mtodo print se le pasa la cadena avisualizar. El mtodo se declara de forma que Java sepa que aceptar unparmetro, un objeto String llamado S: class printer ( public void print(String s){ Ahora, en el cuerpo del mtodo, se puede hacer referencia al objeto Stringque se ha pasado al mtodo print como S: class printer { public void print(String S ){System.out.println(s);) 1 public class app I public static void main(String[l args){(new printer()).print("Hola otra vez desde Java!");1 Este es el resultado del cdigo: C:>java app Hola otra vez desde Java! 80. Si hay que pasar ms de un parmetro, se pueden especificar en la lista, separados por comas:class calculatori n t addenn(int 091, i n t 0 9 2 ) int result = opl + op2;}1 Se puede llamar a los mtodos con literales, variables, arrays u objetos, como sigue:calc.addem1, intl, arrayl, objl) Debera observarse que cuando a un mtodo se le pasa una variable senci- lla o un literal, el valor de la variable o literal es lo que se le pasa; este proceso se llama paso por valor. Por otro lado, cuando se le pasa un objeto o array, realmente se est pasando una referencia a ese objeto o array (de hecho, cuando se almacena un array u objeto en una variable, lo que realmente se est almacenando es una referencia a los mismos). Por esa razn, el cdigo del mtodo llamado tiene acceso directo al array u objeto original, no a una copia, por lo tanto si ese cdigo cambia algn aspecto del array u objeto, como puede ser un elemento del array o un miembro de datos del objeto, el array u objeto originales cambian. Veremos ms sobre esto en este captulo.Argumentos de la lnea de comandos pasadosa rnainiEn las aplicaciones hay un array especial que se pasa como parmetro al mtodo main, un array de objetos String que gestiona los argumentos de la lnea de comandos que el usuario especific cuando inici Java. Por ejemplo, supongamos que se inicia una aplicacin de la siguiente forma:c:>java app Ya es la hora-7En este caso, el primer elemento del array que se pasa a main es "Ya", el segundo "es", el tercero "la" y el cuarto "hora". 81. Esto es un ejemplo en el que se muestra cmo funciona; esta aplicacin visualizar todos los argumentos pasados desde la lnea de comandos utili- zando un bucle sobre el array String que se le pasa como parmetro al mtodo main:public class appIpublic static void main(String[] args)ISystem.out.println("Argumentos de la lnea de comandos...");for(int loop-index = 0 ; loop-index < args.length;loop-index++) {System.out.println("Argumento " + loop-index t 8, -- S, + args [ loop-indexl ) ;111As es como funcionara la aplicacin:C:>java app Ya es la horaArgumentos de la lnea de comandos. . .Argumento O = YaArgumento 1 = esArgumento 2 = laArgumento 3 = horaDevolver valores desde los mtodosEl programador novato regresa y dice, "bien, Bay otro problema. El gran jefe quiere que cree una clase calculadora que realice operaciones matemti- cas. S cmo pasar parmetros a los mtodos de esa clase, pero ..." "S?"le dice. "No s devolver los resultados obtenidos despus de haber hecho la operacin". "Ah", le dice, "use la sentencia return".En un mtodo se utiliza la sentencia return para devolver un valor desde un mtodo y en la declaracin del mtodo se indica el tipo del valor de retorno.[accessl [staticl tipo mtodo1 ([tipo nombreqarmetrol [, tipo nombreqarmetro2 . . . 1 1 ) 82. El tipo del retorno puede ser cualquier tipo de los que Java reconoce, porejemplo, int, float, double, el nombre de una clase que se ha definido, int[]para devolver un array de enteros, oJloat[] para devolver un array defloat. Esto es un ejemplo en el que la clase calculator tiene un mtodo llamadoaddem que coge dos parmetros enteros, los suma y devuelve el resultado.As es como se declara addem: class calculator I i n t addem(int opl, int op2) { As se devuelve la suma de los valores pasados aaddem, usando la senten-cia return: class calculator ( int addem(int opl, int op2) { return opl + op2; 1 As funciona la clase calculator en un programa: class calculator { int addem(int opl, int op2) ( return opl + op2; 1 ) public class app public static void main(String[l args) ( calculator calc = new calculator(); System.o~t.println(~addem(2,2) = " + calc.addem(2, 2 ) ) ; 1 Este es el resultado de la aplicacin: C:>java app addem(2, 21 = 4 83. -Crear mtodos de clase"Vaya", dice el programador novato, "he creado mi nueva clase calculator con un mtodo estupendo llamado addem, pero por qu tengo que meterme en los creando un objeto de esa clase antes de poder usar el mtodo addem? No se puede llamar al mtodo directamente?" "Se puede", le dice, "si se hace que addem sea un mtodo de clase en vez de un mtodo de instancia".Para hacer que un mtodo sea un mtodo de clase, se debe utilizar la palabra clave static:class calculator(static int addem(int opl, int op2){return opl + op2;>1Ahora, se puede llamar al mtodo addem directamente usando el nombre de la clase, sin crear un objeto. Esto es un ejemplo:public class app(public static void main(String[l args)(system.o~t.println(~addem(2.2) =+ calculator.addem2,2));1Este es el resultado del cdigo:C:>java appaddem(2, 2) = 4 Adems se puede usar un mtodo de clase de la forma usual, como un mtodo de un objeto:class calculator(static int addem(int opl, int op2)(return opl + op2;31public class appIpublic static void rnain(String[] args)I 84. calculator calc = new calculator0;system.out.println("addem(2, 2) = m + clac.addem(2, 2));}Hay que hacer notar que el mtodo main en una aplicacin se declara esttico porque Java debe llamarlo antes de que exista un objeto.Si se declara un mtodo esttico (incluyendo el mtodo main de cualquier aplicacin), slo puede llamar a otros mtodos estticos y acceder a datos estticos. Adems, no puede usar las palabras claves this y super, que hacen referencia al objeto actual y a su padre, respectivamente, como veremos en este y en el siguiente captulo. En particular, observe que no puede hacer referencia a datos de instancia en un mtodo esttico.Crear mtodos de acceso a datos4"Ese maldito Johnson", dice el programador novato (PN), "est fisgoneando otra vez en el cdigo de mis objetos. Pero esta vez, no puedo declarar todo como private, porque el resto del cdigo necesita acceder al miembro de datos en cuestin. Qu puedo hacer?" "Puede fijar un mtodo de acceso a datos", le contesta", y restringir el acceso a sus miembros de datos de una forma bien definida". " iSe lo har a ese Johnson! " dice PN. 7Se puede restringir el acceso a los datos de sus objetos usando mtodos de acceso a datos que deben ser invocados para obtener los datos. Esto es un ejemplo en el que se tiene un miembro de datos String llamado data-string:class dataIprivate String data-string = "iHola desde Java!";Se puede dar acceso a este miembro de datos privado con dos mtodos: getData y setData. El mtodogetData devuelve el valor de la variable priva- da data-string, como sigue: 85. class data ( private String data-string ="Hola desde Java!"; public String getData0 i return data-string; 1 1 Sin embargo, el mtodo setData restringe el acceso a los datos internos;en particular, escribiremos este mtodo para que el cdigo desde el que seinvoca slo pueda cambiar los datos internos a una nueva cadena si la longi-tud de la misma es menor que 100. As sera: class data { private String data-string = "Hola desde Java!"; public String getData0 t return data-string; 1 public void setData(String S) i if (a.length0 * 100) { data-string = S; 1 1 1 Ahora se puede utilizar el mtodogetData para obtener la cadena interna yel mtodo setData para ponerle una nueva. Este es un ejemplo en el que semuestra cmo se usa getData: public class app ( public static void main (String [ 1 args) I System.out.println((newdataO).getDataO); 1 1 Este es el resultado del cdigo: C:>java app ;Hola desde Java! Es buena idea utilizar los mtodos de acceso a datos para garantizar elacceso a los datos internos de los objetos. Usando estos mtodos, se puede 86. controlar la interfaz con esos datos y por lo tanto bloquear operaciones que se consideren ilegales.Crear constructores"Hmm", dice el programador novato (PN), "s cmo usar constructores para inicializar los datos de un objeto, como los constructores de la clase String que utilizo para meter texto en una cadena, pero ..." "S?"le pregunta. Cmo puedo crear constructores para mis propias clases?" dice PN.Crear un constructor para una clase es fcil; basta con aadir un mtodo a una clase con el mismo nombre que la clase, sin ningn especificador de acceso ni tipo de retorno. Vamos a ver un ejemplo en el que se aade un constructor que no tiene parmetros a la claseprinter que hemos desarrollado en este captulo. A este constructor se le llama cuando se crea un objeto de la claseprinter y, en este caso, inicializa los datos internos data-string a "Hola desde Java!" (observe que todava se necesitan los parntesis despus del nombre del constructor cuando se declara, aunque no lleve parmetros):class data{private String data-string;data ( ) cdata-string = "iHola desde Java!"; 1public String getData0 { return data-string; 11public class app(public static void main(String[l args)ISystem.out.println((new data0 ).getDataO ) ;11Esto es lo que se ver al ejecutar el programa:C:>java appHola desde Java! 87. Este constructor es especialmente sencillo porque no utiliza ningn parmetro. En la siguiente seccin se explica el constructor con parmetros.pasar parmetros a constructores"De acuerdo", dice el programador novato, "Java est gracioso de nuevo. He hecho un constructor para mi nueva clase, pero realmente, el objeto no est inicializado con los datos que quiero". "Hmm", le contesta; "pas algn dato al constructor?" "Uh-oh", dice PN.Se pueden pasar datos a los constructores, al igual que se hace con otros mtodos. Este es un ejemplo en el que se usa la clase printer del punto anterior, pasando la cadena que se va a visualizar al constructor de la clase printer:class dataIprivate String data-string;data(String S){ data-string = S;1public String getData0(return data-string;11public class appIpublic static void main(Stringi1 args)(System.out.println((new data("iHo1a desde Java!") ).getDataO ) ;11Este es el resultado del cdigo:C:zjava appHola desde Java!El paso de parmetros a un constructor funciona de la misma forma que el paso de parmetros a cualquier mtodo.Un ejemplo completo de clase En este apartado se presentar un ejemplo utilizando los conceptos que se han discutido a lo largo del captulo. El siguiente ejemplo simula la progra- 88. macin de una pila. Veremos las pilas con ms detalle cuando discutamos lascolecciones de Java, pero la teora es sencilla; la programacin de una pilafunciona como una pila de platos. Cuando se pone un plato en la partesuperior de la pila, se est avanzando un elemento en la pila. Cuando se cogeun plato de la pila, se est quitando un elemento de la pila. Observe que losplatos van en orden inverso, si se ponen los platos 1, 2 y 3, cuando se quitende la pila, el plato 3 ser el que se quite primero, seguido de los platos 2 y 1.Para usar la clase stack, se crea un objeto de la clase, pasando un argumen-to al constructor que le indica el tamao de la pila que se quiere (es decir,cuntos enteros se quieren almacenar en ella). El constructor ubica la memo-ria para la pila en un array llamado stack-data, y establece un puntero a lapila, stackgtr, que apunta al artculo que actualmente est en la parte supe-rior de la pila (y es realmente el ndice que se utilizar con el array stack-data). Luego, se puede utilizar el mtodopush de la pila para avanzar un elemen-to en sta, que almacena un dato e incrementa el puntero de la pila hasta lasiguiente posicin del array, o se puede usar el mtodo pop para quitar unelemento; el mtodopop devuelve el artculo retirado y decrementa el punte-ro de la pila. Esta aplicacin se llama stacker.java; el cdigo aade 10 artculos a la pilay despus los retira: class stack { private int stack-data[]; private int s t a c k g t r ;/ / s t a c k q t r = -1 -> la pila est6vacastack(int size)Istack-data = new int[sizel;s t a c k q t r = -1;1public int pop ( )Iif(stackgtr == -1) / / Pila vaca - devuelve errorreturn O;else / / Si no, devuelve datosreturn stack-datalstackqtr-1;1public int push(int push-this){if ( s t a c k g t r >= 99) / / La pila est llena - devuelve errorreturn O ;else (/ / Si no, almacena datosstack-data[++stackqtr] = push-this;return 1; 89. public class stacker { public static void main(String args[l) ( int popped-value; stack stackl = new stack(100); System.out.println("Aiadiendo valores ahora..."); for(int loop-index = 0; loop-index i 10; loop-index++)( stackl.push(loop-index); System.out.println("~aloraadido-> " + loop-index); 1 System.out.println("Quitando valores ahora..."); for(int loop-index = 0; loop-index < 10; loop-index++)I popped-value = stackl.pop0; System.out.println("Valor quitado-> " + popped-value); 1 1 1 As funciona el programa: ~ :> j a v stacker a Aadiendo valores ahora.. Valor aadido-> O Valor aadido-> 1 Valor aadido-> 2 Valor aadido-> 3 Valor aadido-> 4 Valor aadido-) 5 Valor aadido-> 6 Valor aadido-> 7 Valor aadido-> 8 Valor aadido-> 9 Quitando valores ahora. . . Valor quitado-> 9 Valor quitado-> 8 Valor quitado-> 7 Valor quitado-> 6 Valor quitado-> 5 Valor quitado-> 4 Valor quitado-> 3 Valor quitado-> 2 Valor quitado-> 1 Valor quitado-> OComprender el alcance de las variables"Hmm", dice el programador novato, "he definido una nueva variable llamada the-answer en un mtodo llamado get-the-answer, y estaba tratando 90. de usar esa variable en un mtodo llamado get-a-clue, pero Java dice que lavariable no est definida". Parece que es cuestin del alcance de la variable,no se pueden usar variables declaradas en un mtodo, en otro mtodo", lecontestamos. "No se puede?", pregunta PN. El alcance de una variable consiste en las partes del programa en las queesa variable puede utilizarse, y como se puede ver desde el punto de vista delprogramador novato, el alcance es un concepto importante. Java define tres alcances principales: alcance a nivel de clase, a nivel demtodo y a nivel de bloque de cdigo. Si se define un miembro de dato en una clase, estar disponible en la clase,y posiblemente ms all, como se ha visto con los especificadores de accesoprivate, public y protected. El alcance de un mtodo se inicia cuando el flujo de la ejecucin entra enel mtodo y termina cuando dicho flujo lo abandona. Las variables declaradasen el mtodo slo son visibles en el propio mtodo. Los miembros de datosde la clase tambin son visibles en los mtodos de la clase, como los parmetrospasados a esos mtodos. Tambin se puede definir un alcance local para las variables utilizadas en"bloques de cdigo, ya que se pueden declarar variables en esos bloques. Lasvariables que se declaran en un bloque de cdigo slo sern visibles en l y enlos bloques de cdigo que estn contenidos en el primero.La forma ms fcil de tener esto en mente es saber que las variables no"estticas declaradas en un bloque de cdigo comprendido entre llaves, secrean y almacenan en una pila local cuando se entra en el bloque de cdigo yse destruyen cuando se abandona dicho bloque (por eso se llaman variablesdinmicas). Las variables estticas, por otro lado, se almacenan en la alocacinde datos propios del programa, no en cualquier pila, y por tanto no estn fueradel alcance. Estn cercanas a las variables globales (es decir, variables paratodo el programa) que Java permite.He aqu un ejemplo en el que se muestran varios niveles de alcance (clase,mtodo y bloque de cdigo): class Class ( int intl = 1; //visible para todo el cdigo de la clase public void methodiint int2) //visible para todo el cdigo de estemtodo.{int int3 = 3; //visible para todo el cdigo de este mtodo.i f(intl ! = int21 { int int4 = 4; //visible slo en este bloque de cdigo. 91. System.out.println("int1 = " + intl + " int2 =+ int2 + " int3 = " + int3 + " int4 = " + int4); 111public class app{public static void main(String[l args) I Class c = new Class ( ) ;Esto es lo que se ve cuando se ejecuta el cdigo:C:>java appintl = 1 int2 = 2 int3 = 3 int4 = 4Recursividad El programador novato entra murindose de risa y dice, "nunca pens que el zar de la Programacin Exacta me lo dijera: en C++, los mtodos se pueden llamar a s mismos". "Tambin en Java", le contesta. "iEh?" dice PN. Cada vez que se llama a un mtodo en Java, Java sita nuevo espacio en su pila interna para todas las variables del mtodo, lo que quiere decir que no hay razn para que no se pueda llamar al mismo mtodo otra vez, pues un nuevo conjunto de variables ser alocado en la pila automticamente. Lo que es ms, un mtodo puede llamarse a s mismo en Java; a esta tcnica se la llama recursividad. El ejemplo clsico de recursividad es calcular un factorial, por lo tanto, lo implementaremos aqu. Para calcular el factorial de un entero positivo n, que se escribe como "n! ",se calcula lo siguiente: Este proceso se presta a la recursividad fcilmente, porque cada estado de la recursividad puede calcular una operacin en la que multiplica el nmero que se ha pasado por el factorial del nmero menos 1. Cuando el nmero llega a 1 despus de las sucesivas llamadas, el mtodo vuelve, y el control regresa a travs de las sucesivas etapas, ejecutando una multiplicacin en 92. cada etapa hasta que todas las llamadas anidadas han vuelto y se obtiene el factorial.As es el cdigo:class calculator( public int factorial(int n) I if (n == 1) { return n; 1 else { return n * factorialn - 1); } 1public class appJt public static void rnain(String[] args) { calculator calc = new calculator(); Systern.out.println("6! = " + calc.factorial(6) ) ; 11Esto es lo que devolvera el programa:En la prctica, probablemente no se quiera usar la recursividad con mucha7 frecuencia, pero es bueno saber que est disponible.Coleccin garbage y gestin de memoria 7"Bien", dice el programador novato, "contesta, se aloca ms memoria con el operador new, pero cmo se libera cuando no es necesaria? Hay un operador old?" "Qu va!", "Java lo hace todo".7En algunos lenguajes, como C++, se usa el operador new para alocar memoria y luego se usa el operador delete para liberarla cuando no se la necesita ms. Sin embargo, Java no tiene un operador delete. Entonces, cmo se libera la memoria alocada cuando ya no es necesaria? ., 4En Java, hay que contar con un proceso ya construido llamado coleccion garbage. Este proceso es automtico, aunque no se pueda predecir cundo va a tener lugar. Java dispondr de la memoria alocada que no tenga ms refe- rencias. Para que funcione la coleccin garbage, se puede poner un artculo a 93. null (aunque hacer esto tampoco permite predecir cundo, si llega el caso, lacoleccin garbage empezar a funcionar al ejecutar el programa). Veamos un ejemplo en el que se est creando un nuevo objeto y luego sepone su variable a null. Dado que no hay ms referencias a ese objeto, elproceso de la coleccin garbage lo liberar ms pronto o ms tarde. Este es elcdigo: class Data { public int intdata = 0; Data () {intdata= 1; 1 1 public class app { public static void main(String[] args) t Data d = new Data();//algo de cdigo . . .d3 null;//ms cdigo . . . 1 1 Recordemos, por tant, que cuando algn elemento de datos, incluyendoobjetos y arrays, se ha situado con el operador new, se pueden poner susreferencias a null, y si Java necesita ms memoria, comenzar el proceso dela coleccin garbage. Sin embargo, se tiene que tener cuidado y evitar lasreferencias circulares. $0 dnde estgn lospunteros en Java, y la respuesta es que no tiene. Los diseadores de Java omitieron tos punteros por razones de seguridad, para asegurarse que los programadores no podan acceder a la memoria mas all de los limites legales. En lugar de punteros, Java usa referen-jue act;tn como punteros de forrna ocul ta. Cuando se cirea un nuevo, se obtiene una referenci;t a ese ose usa ferenciaJava: 94. Evitar las referencias circulares La coleccin garbage, liberacin de memoria de aquello que no tiene msreferencias en el programa, arranca automticamente. Sin embargo, se debe-ran evitar las referencias circulares en las que un objeto hace referencia aotro y el segundo al primero. Cuando se liberan todas las referencias a estos objetos en un programa,cada uno todava tiene una referencia interna al otro, lo que significa que lacoleccin garbage no puede actuar en el otro objeto. Peor todava es que,como no hay referencias externas al objeto, no se puede llegar a ese objetopara cambiar la situacin. Ambos objetos estarn en memoria, consumiendorecursos, hasta que el programa finalice.Este es un ejemplo en el que se muestra lo que hemos querido decir: en l,la clase a tiene una referencia interna a un objeto de la clase b, y la clase b,una referencia interna a un objeto de la clase a. Cuando el cdigo de mainpone la referencia, tiene uno de estos objetos anull, y estos objetos continua-rn ocupando memoria hasta que el programa finalice. Este es el cdigo: class a ( b bl; a 0( bl = new b 0 ;1 1 class b ( a al; b 0( al = new a();1 } public class app I public static void main(String[] args)( a obj = new a();-7 obj = null; //existen referencias circulares inaccesibles!1 >1 Slo hay una forma de evitar esto, y es liberar las referencias circularesantes de ir a la aventura. En la prctica, esto generalmente quiere decir que se 95. ponen las referencias de un objeto a otros objetos a null antes de poner la referencia del objeto, en s mismo, a null. Algunas veces, es posible hacer esto en el mtodofinalize (para ms detalles, ver el siguiente apartado).Mientras estamos viendo la gestin de memoria, hay que notar que se tiene algn control sobre la alocacin de memoria como un todo (ver la opcin de la lnea de comando -J en el captulol, que permite fijar la cantidad de memoria total alocada cuando el programa se ejecuta). En general, Java gestiona la memoria en los programas.Coleccin garbage y el mtodo fnalze"Hmm", dice el programador novato, "entonces Java tiene un recolector de basura que retira de la memoria los artculos que no estn referenciados ya. Hay algo ms que yo debera saber sobre este proceso?" "Una cosa", le responde. "Garbage llama a un mtodo especial, finalize, si existe, y se 1 puede usar este mtodo para limpieza de ltima hora .Cuando un objeto est dentro del proceso de garbage (ver el punto ante- rior), este recolector llama a un mtodo del objeto llamadofinalize, si existe. En este mtodo se puede ejecutar el cdigo de limpieza y, con frecuencia, es buena idea liberar cualquier referencia a otros objetos que tenga