Tutorial Java St



Comments



Description

Tutorial JavaContents Lección: Lenguaje básico .......................................................................................................... 8 Variables .................................................................................................................................. 8 Operadores.............................................................................................................................. 8 Expresiones, declaraciones y bloques ................................................................................ 8 Instrucciones de flujo de control........................................................................................... 8 Variables ...................................................................................................................................... 8 Nomenclatura ........................................................................................................................ 10 Tipos de datos primitivos......................................................................................................... 10 Valores por defecto .............................................................................................................. 12 Literales .............................................................................................................................. 13 Usando caracteres de subrayado en literales de valores numéricos........................... 15 Arreglos ...................................................................................................................................... 16 Declarar una Variable para hacer referencia a un Arreglo ............................................ 18 Crear, inicializar y acceder a una arreglo ......................................................................... 19 Copia de Arrays .................................................................................................................... 20 Manipulación de arreglos .................................................................................................... 21 Resumen de Variables ............................................................................................................ 22 Preguntas: Variables ................................................................................................................ 22 Operadores................................................................................................................................ 22 Asignación, aritmética y operadores unarios ....................................................................... 24 El operador de asignación Simple ..................................................................................... 24 Los operadores aritméticos................................................................................................. 24 Los operadores unarios ....................................................................................................... 25 Operadores de igualdad y relacionales ............................................................................ 27 Los operadores condicionales ............................................................................................ 28 El operador de comparación de tipo instanceof .............................................................. 29 Operadores Bitwise y Bit Shift ................................................................................................ 30 Resumen de operadores ......................................................................................................... 30 Operador de asignación simple.......................................................................................... 30 Operadores aritméticos ....................................................................................................... 30 Operadores unarios ............................................................................................................. 31 Igualdad y operadores relacionales ................................................................................... 31 Operadores condicionales .................................................................................................. 31 Operador de comparación de tipo ..................................................................................... 31 Operadores Bitwise bit a bit y Bit Shift (mover bits) ........................................................ 31 Preguntas y ejercicios: operadores ....................................................................................... 31 Preguntas............................................................................................................................... 31 Ejercicios................................................................................................................................ 32 Expresiones, instrucciones y bloques ................................................................................... 33 Expresiones ........................................................................................................................... 33 Instrucciones o sentencias .................................................................................................. 34 Bloques .................................................................................................................................. 34 Preguntas y ejercicios: expresiones, instrucciones y bloques .......................................... 35 Preguntas............................................................................................................................... 35 Ejercicios................................................................................................................................ 35 Instrucciones de control de flujo............................................................................................. 35 Las instrucciones if-then e if-then-else.................................................................................. 36 La instrucción if-then ...................................................................................................... 36 La instrucción if-then-else .......................................................................................... 37 La instrucción switch ............................................................................................................ 38 El uso de Strings en la instrucción switch ..................................................................... 41 Las instrucciones while y do-while ................................................................................. 43 La instrucción for .................................................................................................................... 44 Instrucciones de ramificación ................................................................................................. 46 La instrucción break ........................................................................................................... 46 La instrucción continue .................................................................................................... 48 La instrucción return......................................................................................................... 49 Resumen de las instrucciones de flujo de Control .............................................................. 50 Preguntas y ejercicios: Control de flujo ................................................................................. 50 Preguntas............................................................................................................................... 50 Ejercicios................................................................................................................................ 50 Lección: Clases y objetos ....................................................................................................... 52 Clases..................................................................................................................................... 52 Objetos ................................................................................................................................... 52 Más tipos ................................................................................................................................ 52 Clases anidadas ................................................................................................................... 52 Tipos de enumeración ......................................................................................................... 52 Clases......................................................................................................................................... 52 Declarar Clases ........................................................................................................................ 54 Declarar las Variables miembro ............................................................................................. 55 Modificadores de acceso..................................................................................................... 55 ............................................................................................... 76 La clase de Bicycle ..................................................................................................................................................................... 58 Pasar información a un método o a un Constructor ......................................... 67 Llamar los métodos de un objeto ............................ 60 Número arbitrario de argumentos ........................................................................................................................................ 64 Declarar una Variable para hacer referencia a un objeto .... 62 Pasando argumentos de tipo de datos de referencia .............................. 65 Uso de objetos ................................................................................................................................................................................................................................................................................................. 58 Proporcionar constructores para tus clases .. 78 Bloques de inicialización estática ........................................................................ 69 Más sobre clases .................................................. 79 ......................................................... 67 Referenciando a los campos de un objeto ........................................................................................................................................................... 56 Nombres de variables ....... 74 Variables de clase ......................................................................................................................................................................................................................... 72 Usando this con un Constructor .............................. 77 Inicializar campos ............................................................................................................ 75 Métodos de la clase ....................... 73 Entendiendo a los miembros de la clase ............................................................ 64 Crear instancias de una clase ................................................... 70 Devuelve un valor desde un método .......................................... 71 Usando la palabra clave this............................................................................................................................................................ 72 Controlar el acceso a los miembros de una clase.............................................. 70 Devolviendo una clase o una interfaz ........................................................................................................................................................... 57 Sobrecarga de métodos ....................... 63 Creación de objetos ............................................................................... 57 Nombrando un método .................................................... 60 Nombres de parámetros ........................................................................................... 61 Pasando argumentos de tipo de datos primitivo ................................................................................................................................................................................................................................................................................................................................................ 62 Objetos ..................... 72 Usando this con un campo ............................................................................................................................................ 59 Tipos de parámetros ........................................................................................................................................ 68 El recolector de basura ................................... 76 Constantes....Tipos ................................................. 56 Definir Métodos ............................................................................................................................................................................................................................. 78 Inicializar miembros de instancia ............................................................................... 65 Inicializar un objeto...................................................................................................................................................... ....................................................................................................................... 89 Las clases locales son similares a las clases internas ............... 101 Conceptos básicos de anotaciones ................................................................................................................................................................... 91 Ejemplos de clases de anónimos ..................... 91 Acceder a las Variables locales del ámbito envolvente y declarando y acceder a los miembros de la clase anónima.......................................................................................................................................................................... 101 ............................................................................................................................................................................................................................................................................................................ 95 Las respuestas a las preguntas y ejercicios: clases anidadas ...................................... 84 Ejemplo de la clase interna ................................................................................................................ 82 ¿Por qué utilizar clases anidadas? ......................Resumen de crear y utilizar clases y objetos ............................................................... 88 Clases de sombreado y locales ........................ 97 Lección: anotaciones ........................... 90 Declarar clases anónimas ...... 89 Clases de anónimas............................................................................................................................................................................................................ Local clases.. 96 Preguntas......................................................................................................................... 82 Clases anidadas .......................................................................... 83 Clases internas ................................................................................................................................................................................................................................................................................................................................................................................................................................................. 81 Preguntas........................................ 86 Acceso a miembros de una clase envolvente.......................................................................................................................................... 81 Preguntas y ejercicios: objetos........................................................................................ 81 Ejercicios........................................................ 80 Preguntas................................................... 79 Preguntas y ejercicios: clases ...... 84 Clases locales y anónimas.............................................................................. 80 Ejercicios........................................................................................................................................................ 90 Sintaxis de clases anónimas ................................................................................................................................................................................................................................................ 94 Preguntas................................................................................................... 96 Ejercicio....................................... 86 Modificadores ......... 97 Tipos enumerados ............................................................................ 92 Cuándo utilizar clases anidadas............................................................................................................................................................... 82 Clases anidadas estáticas ........................................................................................................................................ 86 Clases locales ............... clases de anónimas y expresiones Lambda .................................................... 86 Declarar clases locales ....................... 95 Ejercicios................. 83 Sombreado ...................................................................................................................................................... 112 Métodos por defecto ..................................................................................................................... 111 Evolución de las Interfaces ..............................................................El formato de una anotación ................................................................................................................................................................ 101 Donde pueden ser utilizadas las anotaciones ...................................... 122 Un ejemplo de herencia........................................... 121 Preguntas y ejercicios: Interfaces .............................................. 109 Implementar una interfaz............................................................................................................................................................................................................. 104 Tipos de anotación utilizados por el lenguaje Java........... 124 Miembros privados en una superclase ......................... 109 Una interfaz de muestra................................. la implementación y el tipo .......................................................................... 115 Métodos estáticos.................................................................................................. 110 Usando una interfaz como un tipo ..... 109 Implementa la interfaz Relatable............................................................................................................................. 105 Preguntas y ejercicios: anotaciones ......................................................................................... 107 Interfaces en Java ................................................................ 108 Definir una interfaz ..................................................................................... 106 Lección: Interfaces y herencia ................................................................................................................................. 124 Herencia múltiple de estado..... 104 Anotaciones que se aplican a otras anotaciones .................................................................................. 121 Ejercicios.................................................................... 106 Interfaces .............................................................................................................................................................................. 106 Herencia .......................... 106 Preguntas.................................................................... 102 Tipos de anotación predefinidos . 102 Declarar un tipo de anotación .................................................................................................................................................................................................................................................................................................................................................................................... 121 Preguntas................................................................. 121 Herencia ...................................................................................................................................................... 125 ................................................... 124 Casting de Objetos ............................................................................................. 112 Extender Interfaces que contienen métodos por defecto............. 117 Resumen de Interfaces ............................................................................................................................. 108 El cuerpo de la interfaz .......................... Relatable ................................................................................................................................. 116 Integración de métodos por defecto en bibliotecas existentes ..................................................................................................................................................................................... 122 La jerarquía de clases de la plataforma Java ............................................................ 107 Interfaces como APIs .......................................................................................................................................................................... 106 Interfaces .............. 123 Lo que se puede hacer en una subclase .................................................. ...................................................................................... 132 Usando la palabra clave super ................................................................................................. 127 Modificadores . 145 La clase DecimalFormat ............................................ 140 Preguntas y ejercicios: herencia ..................................................................................................................................................................................................................................... 144 Los métodos printf y formato ........ 132 Acceso a miembros de la superclase.................................................................................................................................................................................................................................................... 140 Lección: Números y cadenas ................................... 144 Un ejemplo.............................................................................................................................................................. 142 Formato de impresión numérica ....................................................... 130 Ocultar campos ........... 136 Escribir clases y métodos finales .............. 137 Las clases abstractas en comparación con las Interfaces......................................................................................................................................................... 146 ............. 126 Métodos de instancia ....................................................................................................................................................................................................................................... 126 Métodos de interfaz ................................................................................... 138 Un ejemplo de clase abstracta .................................. 136 El método toString() ......................................................................... 141 Strings .......................... 139 Cuando una clase abstracta implementa una interfaz ........................................ 135 El método finalize()......... 134 El método equals() ........................................................................ 126 Métodos estáticos.................... 132 Los constructores de la subclase ........................................................................................................... 137 Clases y métodos abstractos............................................................................................................................ 136 El método hashCode() ................................................................................................................ 129 Polimorfismo....................................................... 136 El método getClass() .......................................................................................................................................................................................................................................................................................................................................................................................... 140 Miembros de la clase ................................................ 134 El método clone() .....................................................................................Sobreescribir y ocultar métodos. 140 Preguntas...................................................................................................................... 141 Las clases de números ............................................. 129 Resumen ..................................................................................................................................................... 140 Resumen de la herencia .................................................................................................................................................................................................................................................................................................................................... 133 Objeto como una superclase .............................. 141 Números.................................................................................................................................................................................................................................................. 141 Números........................................................................................................ .................... 159 Otros métodos para manipular cadenas ...................................................................................... 147 Constantes y métodos básicos ..................................................................................... 160 La búsqueda de caracteres y subseries de caracteres en una cadena ........................................................................................................................ 159 Caracteres y subcadenas Índice ................................................................ 169 .......................................................................................................... 169 Autoboxing y Unboxing .............................. 155 Concatenación de cadenas ................................................................................................................................................................ 167 Resumen de caracteres y cadenas ..................................................... 152 Resumen de números ............................................................................................................................................................ 150 Números aleatorios .................................................................................................................... 148 Métodos de funciones logarítmicos y exponenciales ............................................................................................................ 161 Un ejemplo........................................................................................................................................... 162 Comparación de cadenas y porciones de cadenas ...................................................................... 152 Secuencias de escape...................... 157 Convertir números en cadenas .. 160 Sustitución de caracteres y subseries de caracteres en una cadena .............................................................................................................................. 157 Conversión de cadenas a números ..................Más allá de la aritmética básica .......................................................................................................... 166 Un ejemplo........ 165 Longitud y capacidad ................................................................................................................................................................................... 152 Caracteres ........................................................................................................................... 154 Creación de strings .......................... 149 Métodos de funciones trigonométricos ......... 157 Conversión entre números y cadenas ............................................................................................................................................................................................................................................... 163 La clase StringBuilder ................ 165 Operaciones de StringBuilder ....................... 154 Strings ............................................................ 158 Manipulación de caracteres de una cadena .......................................................................................................................................................................................................................... 154 Longitud de cadena ............................................ 156 Creación de cadenas de formato ..................................................................... los tipos de datos básicos (tipos primitivos. hay algunas distinciones técnicas de las que primero debes ser consciente. Cada discusión incluye ejemplos de código que se pueden compilar y ejecutar. matrices y cadenas de caracteres). los valores por defecto y literales. Esta sección analiza expresiones. Esta sección analiza esta relación. que computan los valores. declaraciones y bloques Los operadores pueden utilizarse en la construcción de expresiones. En el lenguaje de programación Java. ya que ambas parecen a menudo referirse a lo mismo. Sin embargo. bucles y ramificaciones de sentencias que permiten a sus programas ejecutar condicionalmente bloques particulares de código. Variables Como has aprendido en la lección anterior. Ya hemos presentado a los campos. Operadores Esta sección describe los operadores del lenguaje de programación Java. . y por último los operadores menos utilizados. ¿qué otros tipos de datos existen? ¿Los campos se tienen que inicializar cuando se declaran? ¿A los campos se les asigna un valor predeterminado si no se inicializan explícitamente? Exploraremos las respuestas a estas preguntas en esta lección. Instrucciones de flujo de control Esta sección describe las sentencias de los flujos de control soportados por el lenguaje de programación Java. más las variables y sus reglas de nomenclatura y convenciones. las instrucciones pueden agruparse en bloques. int gear = 1. pero probablemente tiene todavía un par de preguntas. un objeto almacena su estado en campos. se usan ambos términos "campo" y "variable". int cadence = 0. tales como:     ¿Cuáles son las reglas y convenciones para nombrar un campo? Además de int. Expresiones. Cubre la toma de decisiones. instrucciones y los bloques usando el código de ejemplo que ya has visto. el lenguaje de programación Java también utiliza el término "variable". Esto es una fuente común de confusión entre los nuevos desarrolladores. pero antes de hacerlo.Lección: Lenguaje básico Variables Ya has aprendido que objetos almacenan su estado en los campos. Primero presenta los operadores más comúnmente utilizados. int speed = 0. las expresiones son los componentes básicos de las instrucciones.  Parámetros Ya has visto ejemplos de parámetros tanto en el método main de la aplicación "Hello World!" y en la clase Bicycle. Si el contexto pide una distinción. la palabra clave final podría añadirse para indicar que el número de marchas nunca cambiará. en otras palabras). la variable args es el parámetro de este método. variables locales. sin importar cuántas veces la clase ha creado una instancia.  Variables de Instancia (campos no-estáticos) Técnicamente hablando. No hay ninguna clave especial designando una variable como local. el resto de este tutorial utiliza las siguientes directrices generales cuando se habla de campos y variables: Si estamos hablando de "campos en general" (excluyendo las variables locales y los parámetros). métodos y tipos anidados se denominan colectivamente miembros. No son accesibles desde el resto de la clase. usaremos términos específicos (campo estático. etc. Los tipos de campos. Recordemos que la firma para el método main es public static void main(String[] args). Un campo define el número de marchas para una clase particular de bicicleta que podría ser marcado como static ya que conceptualmente el mismo número de marchas se aplicará a todas las instancias.  Variables Locales Similar a cómo un objeto almacena su estado en los campos. El código static int numGears = 6. Lo importante a recordar es que los parámetros siempre son clasificados como "variables" no como "campos". Los campos no estáticos son también conocidos como las variables de instancia porque sus valores son únicos para cada instancia de una clase (para cada objeto. . Además.) según corresponda. int count = 0. los objetos almacenan sus Estados individuales en "campos no estáticos". podemos decir simplemente "campos". un método almacenará temporalmente el estado en las variables locales. crearía un campo estático. las variables locales sólo son visibles para los métodos en los que se declaran.El lenguaje de programación Java define los siguientes tipos de variables:  Variables de Clase (campos estáticos) Una variable de clase es cualquier campo declarado con el modificador static. Esto se aplica a otras construcciones de parámetros aceptados también (como constructores y los controladores de excepciones) que aprenderá más adelante en el tutorial. Aquí. los campos se declararan sin la palabra clave static. Ocasionalmente también puede ver el término "miembro" usado también. la determinación proviene totalmente de la situación en la que se declara la variable —está entre la apertura y cierre de llaves de un método. podemos decir simplemente "variables". es decir. Una vez dicho esto.). el currentSpeed de una bicicleta es independiente de la currentSpeed de otra. Por lo tanto. Esto indica al compilador que hay exactamente una copia de esta variable en existencia. La sintaxis para declarar una variable local es similar a declarar un campo (por ejemplo. Si la discusión se aplica a "todas las anteriores". Aunque es técnicamente legal para comenzar un nombre de la variable con '_'. El nombre de una variable puede ser cualquier identificador legal —una secuencia de longitud ilimitada de Unicode de letras y dígitos. nunca se utiliza en absoluto. También tenga en cuenta que el nombre que usted elige no debe ser una palabra clave o palabra reservada. Un convenio similar existe para el carácter de subrayado. c y g. como s. y el lenguaje de programación Java no es diferente. no "$" o "_". es siempre comenzar sus nombres de variables con una letra. La Convención. se desaconseja esta práctica.Nomenclatura Cada lenguaje de programación tiene su propio conjunto de reglas y convenciones para las clases de nombres que puedes usar. cada letra será mayúscula y se separa las palabras posteriores con el carácter de subrayado. comenzando con una letra. el carácter de subrayado nunca se utiliza en otros lugares. contiene datos numéricos y tiene un valor inicial de "1". son mucho más intuitivos que versiones abreviadas. Tipos de datos primitivos El lenguaje de programación Java es estáticamente-tipado. pero sus nombres de variable siempre deben evitar usarlo.  Los caracteres posteriores pueden ser Letras. el lenguaje de programación Java soporta otros siete tipos de datos primitivos. además de las operaciones que pueden realizarse con él. números. Si consta de más de una palabra. Los ocho tipos de datos primitivos soportados por el lenguaje Java de programación son: . El espacio en blanco no está permitido. Hacerlo asi hará su código fácil de leer y comprender. Las reglas y convenciones para nombrar sus variables pueden resumirse como sigue:  Los nombres de variables distinguen mayúsculas de minúsculas. La convención (y el sentido común) se aplican a esta regla también. el carácter de signo de dólar.  Si el nombre que usted elige consta de una única palabra. speed y gear. por ejemplo. utilice palabras completas en lugar de abreviaturas crípticas. Si la variable almacena un valor constante. Por Convención. signos de dólar. como ya lo has visto: int gear = 1. tales como static final int NUM_GEARS = 6. sin embargo. escriba esa palabra en letras minúsculas. Así dice el programa que un campo llamado "gear" existe. Los nombres gearRatio y currentGear son los principales ejemplos de esta Convención. lo que significa que:  todas las variables primero deben ser declaradas antes de que puedan ser utilizadas. Usted puede encontrar algunas situaciones donde se generan automáticamente nombres que contienen el signo de dólar. Además. la primera letra de cada palabra subsiguiente será mayúscula.  Un tipo primitivo está predefinido por el lenguaje y es nombrado por una palabra clave reservada. Además de int. En muchos casos también hará su código auto-documentado. por Convención. la Convención cambia ligeramente. el signo de dólar "$" o el carácter subrayado "_". los campos denominados cadence. El tipo de dato de una variable determina los valores que puede contener. Los valores primitivos no comparten el estado con otros valores primitivos. o caracteres resaltados. Al elegir un nombre para sus variables. Esto implica declarar el tipo de la variable y el nombre. donde importa el ahorro de memoria. o o Para valores decimales. puede utilizar el tipo de datos int para representar un entero sin signo de 32 bits. Métodos estáticos como compareUnsigned.math. o o  Tiene un valor mínimo de -32. Utilice este tipo de datos cuando se necesita un rango de valores más amplio que las ofrecidas por int. este tipo de datos es generalmente la opción predeterminada. Útil para guardar memoria en grandes arreglos. Numbers and Strings cubre BigDecimal y otras clases útiles proporcionados por la plataforma Java. Para eso. el tipo de datos int es de 32-bit es un entero con signo en complemento a dos. doble: el tipo de datos double es un punto flotante de precisión doble de 64 bits IEEE 754. o o Tiene un valor mínimo de -128 y un valor máximo de 127 (inclusivo). Consulte la sección el número de clases para obtener más información. int: por defecto. pero se especifica en la sección tipos de coma flotante. divideUnsigned etc. que tiene un valor mínimo de 0 y un valor máximo de 264-1. que tiene un valor mínimo de 0 y un valor máximo de 232-1. . o o o  Use un float (en vez de double) si necesita guardar memoria en grandes conjuntos de números de punto flotante. usted necesitará utilizar la clase java. La clase Long también contiene métodos como compareUnsigned.  short: el tipo de dato short es de 16-bit es un entero con signo en complemento a dos. Su rango de valores está fuera del alcance de esta discusión.768 y un valor máximo de 32. divideUnsigned etc. en situaciones donde realmente importa el ahorro de memoria. Este tipo de datos no debe utilizarse para valores precisos. Puede utilizar un short para guardar memoria en arreglos grandes.BigDecimal en su lugar. pero se especifica en la sección tipos de coma flotante. se han añadido a la clase Integer para apoyar las operaciones aritméticas de números enteros sin signo. formatos y valores de la especificación del lenguaje Java. como moneda. Utilice la clase Integer para utilizar el tipo de datos int como un entero sin signo. o o La firma de long tiene un valor mínimo de -263 y un valor máximo de 263-1. formatos y valores de la Java Language Specification. como moneda. Como con las recomendaciones de byte y short. En Java SE 8 y versiones posteriores.  float: el tipo de datos float es un punto flotante de precisión simple de 32 bits del estandar IEEE 754 (Instituto de Ingeniería Eléctrica y Electrónica para aritmética en coma flotante). para apoyar operaciones aritméticas de long sin signo. Su rango de valores está fuera del alcance de esta discusión. el hecho de que el rango de una variable es limitado puede servir como una forma de documentación.  long: el tipo de datos long es de 64-bit complemento a dos con cualquier otro. o o Tiene un valor mínimo de -231 y un valor máximo de 231-1. Pueden también ser utilizados en lugar de int donde sus límites ayudan a clarificar el código. En Java SE 8 y versiones posteriores.767 (inclusivo). puede utilizar el tipo de datos long para representar 64 bits sin signo. Este tipo de datos no debe utilizarse para valores precisos. byte: el tipo de dato byte de 8-bit es un entero con signo en complemento a dos (0 para positivo y 1 para negativo). Los objetos String son inmutables. Usted aprenderá más acerca de la clase String en Objetos de datos simples. Este tipo de datos representa un bit de información. por defecto será cero o null. probablemente tenderán a pensar en él como tal.. que significa que una vez creado.lang. char: el tipo de datos char es un solo carácter Unicode de 16 bits. Los campos que son declarados pero no inicializados establecerán una moratoria razonable por el compilador.0F double 0. La siguiente tabla resume los valores por defecto para los tipos de datos anteriores. Además de los ocho tipos de datos primitivos mencionados anteriormente. o o  Utilice este tipo de datos para indicadores simples que siguen condiciones del tipo verdadero o falso.535 inclusivo). se considera generalmente mal estilo de programación. La clase String no es técnicamente un tipo de datos primitivo. el lenguaje de programación Java también proporciona un apoyo especial para cadenas de caracteres mediante la clase java. String s = "this is a string". pero teniendo en cuenta el apoyo especial dado por el lenguaje. pero su "tamaño" no es algo que se define con precisión. Encerrando tu cadena de caracteres entre comillas dobles creará automáticamente un nuevo objeto String. o Tiene un valor mínimo de '\u0000' (o 0) y un valor máximo de '\uffff' (o 65. Tipo de datos Valor por defecto (de campos) Byte 0 short 0 int 0 long 0L float 0. dependiendo del tipo de datos. por ejemplo. booleano: el tipo de datos boolean tiene sólo dos valores posibles: true y false.0d Char '\u0000' String (o cualquier objeto) null Boolean false . sin embargo. no se pueden cambiar sus valores.  En términos generales. Confiar en estos valores por defecto. Valores por defecto  No siempre es necesario asignar un valor cuando se declara un campo.String . los literales están representados directamente en el código sin necesidad de cómputo. Hexadecimal: Base 16. Los literales enteros pueden ser expresados por estos sistemas de numeración:    Decimales: Base 10. No son objetos creados de una clase. short s = 10000.  El acceso a una variable local sin inicializar producirá un error en tiempo de compilación. Sin embargo.Las variables locales son ligeramente diferentes. short. Literales Usted puede haber notado que no se utiliza la palabra clave new al inicializar una variable de un tipo primitivo.   Los valores de los tipos integrales byte. byte b = 100. Los valores de tipo long que exceden el rango de int pueden crearse de literales de long. es posible asignar un literal a una variable de un tipo primitivo: boolean result = true. El prefijo 0x indica hexadecimal y 0b binario: . Se recomienda utilizar la letra mayúscula L porque la minúscula letra l es difícil distinguir el dígito 1. Una literal es la representación de código fuente de un valor fijo. Como se muestra a continuación. Si usted necesita usar otro sistema de numeración. int y long pueden crearse desde literales int. Si no puede inicializar la variable local donde se declara. es probable que el sistema de numeración único que nunca usará es el sistema decimal.    Los tipos primitivos son tipos de datos especiales incorporados en el lenguaje. cuyas cifras consta de los números 0 a 9. de lo contrario es de tipo int. Literales enteros  Un literal entero es de tipo long si termina con la letra L o l. El compilador nunca asigna un valor predeterminado a una variable local sin inicializar. cuyas cifras se compone de los números 0 y 1 (puede crear literales binarios en Java SE 7 y versiones posteriores) Para la programación de propósito general. el ejemplo siguiente muestra la sintaxis correcta. char capitalC = 'C'. asegúrese de asignarle un valor antes de intentar usarla. Este es el sistema de numeración que utiliza todos los días. cuyos dígitos consisten en los números 0 a 9 y las letras A F Binario: Base 2. int i = 100000. 234e2. \f (forma de alimentación). El lenguaje de programación Java también soporta algunas secuencias de escape especial para literales char y String:         \b (retroceso) \t (tab). in decimal int decVal = 26. Carácteres y literales String  Los literales de tipo char y String pueden contener cualquier carácter Unicode (UTF-16).  Utilice siempre 'comillas simples' para literales char y "comillas dobles" para literales de String. se pueden utilizar tales caracteres directamente en el código. esta es la opción predeterminada y por Convención se omite). Los tipos de punto flotante (float y double) también puede expresarse utilizando E o e (para la notación científica). . Por lo tanto. \n (avance de línea). no sólo en literales char o String. de lo contrario su tipo es double y opcionalmente puede terminar con la letra D o d. También hay una literal especial null que puede utilizarse como un valor para cualquier tipo de referencia. // The number 26.4f. Literales de coma flotante  Un literal de coma flotante es de tipo float si termina con la letra F o f.// The number 26. in binary int binVal = 0b11010. in hexadecimal int hexVal = 0x1a. Es poco lo que puede hacer con un valor null más allá de pruebas de su presencia. double d1 = 123. \" (comilla doble). \r (retorno de carro). F o f (literal float de 32 bits) y D o d (64 bits double literal. excepto las variables de tipos primitivos.  null puede asignarse a cualquier variable. o "S\u00ED Se\u00F1or" (Sí Señor en Español). float f1 = 123. por ejemplo).4. // The number 26. Si tu editor y sistema de archivos lo permiten. // mismo valor que d1. Si no. Las secuencias de escape Unicode pueden utilizarse en cualquier parte en el programa (como en los nombres de campo. \' (comilla simple) y \\ (barra invertida). pero en notación científica double d2 = 1. puede utilizar un "escape Unicode" como '\u0108' (mayuscula C con acento circunflejo). long maxLong = 0x7fff_ffff_ffff_ffffL. float pi = 3. se forma al tomar un nombre de tipo y anexar (. también hay un tipo especial de literal llamada  Una clase literal. Finalmente. Esto se refiere al objeto (de tipo Class) que representa el tipo de sí mismo. null es a menudo utilizado en programas como marcador para indicar que un objeto no está disponible. long socialSecurityNumber = 999_99_9999L. long hexBytes = 0xFF_EC_DE_5E.1415F. similar a cómo usarías un signo de puntuación como una coma o un espacio. long bytes = 0b11010010_01101001_10010100_10010010.  Esta caracteristica le permite separar grupos de dígitos en literales numéricos. que pueden mejorar la legibilidad del código. long hexWords = 0xCAFE_BABE. // Invalido: no se puede poner subrayado .class. El siguiente ejemplo muestra otras maneras en que puede utilizar el carácter de subrayado en literales de valores numéricos: long creditCardNumber = 1234_5678_9012_3456L. Usted puede colocar subrayados sólo entre los dígitos.class). como un separador. // Invalido: no se puede poner subrayado // adyacente a un punto decimal float pi2 = 3. cualquier número de caracteres de subrayado (_) puede aparecer en cualquier parte entre los dígitos en un literal numérico. Por ejemplo. usarás un carácter de subrayado para separar dígitos en grupos de tres.14_15F. Usando caracteres de subrayado en literales de valores numéricos En Java SE 7 y versiones posteriores._1415F. byte nybbles = 0b0010_0101. si su código contiene números con muchos dígitos. Por ejemplo. String. No puede colocar subrayado en los siguientes lugares:     Al principio o al final de un número Adyacente a un punto decimal en un literal de coma flotante Antes de un sufijo F o L En las posiciones donde se espera una cadena de dígitos Los siguientes ejemplos demuestran las colocaciones de subrayado válido y no válido (que destacan) en literales de valores numéricos: // Invalido: no se puede poner subrayado // adyacente a un punto decimal float pi1 = 3_.  Cada item de un arreglo se llama un elemento. El noveno elemento. Como se muestra en la ilustración anterior. // Invalido: no se puede poner subrayado // Al final de una literal int x2 = 52_. en el método main de la aplicación "Hello World!". por ejemplo. la numeración comienza con 0. Después de la creación. // Invalido: no se puede poner subrayado // al final del numero int x7 = 0x52_. // Invalido: no se puede poner subrayado // en el prefijo 0x int x4 = 0_x52.// antes de un sufijo L long socialSecurityNumber1 = 999_99_9999_L. su longitud es fija. Una arreglo de 10 elementos. La longitud de un arreglo se establece cuando se crea el arreglo. sería por lo tanto para acceder al índice 8. Usted ya ha visto un ejemplo de arreglo. Esta sección analiza detalladamente los arreglos. // OK (literal hexadecimal) int x6 = 0x5_2. // Invalido: no se puede poner subrayado // en el comienzo de un número int x5 = 0x_52. // OK (literal decimal) int x1 = 5_2. Arreglos    Un arreglo es un objeto contenedor que contiene un número fijo de valores de un solo tipo. y cada a elemento se accede por su Índice numérico. // OK (decimal literal) int x3 = 5_______2. . System. // inicializa primer elemento anArray[0] = 100. pone algunos valores del arreglo e imprime cada valor en salida estándar.El siguiente programa. class ArrayDemo { public static void main(String[] args) { // declara una arreglo de enteros int[] anArray.out.out. // y así sucesivamente anArray[2] = 300. crea un arreglo de enteros.println("Element at index + anArray[8]). anArray[5] = 600.out.println("Element at index + anArray[3]). anArray[4] = 500. System. anArray[3] = 400. anArray[7] = 800.println("Element at index + anArray[4]). anArray[6] = 700.println("Element at index + anArray[6]). System.out.out.out. System.println("Element at index + anArray[2]). System.out. } } La salida de este programa es: Element Element Element Element Element Element Element Element Element Element at at at at at at at at at at index index index index index index index index index index 0: 1: 2: 3: 4: 5: 6: 7: 8: 9: 100 200 300 400 500 600 700 800 900 1000 0: " 1: " 2: " 3: " 4: " 5: " 6: " 7: " 8: " 9: " . System. System. // inicializa segundo elemento anArray[1] = 200. System. // asigna memoria para 10 números enteros anArray = new int[10]. anArray[8] = 900.println("Element at index + anArray[1]).out. ArrayDemo. System.println("Element at index + anArray[9]).println("Element at index + anArray[0]).out.println("Element at index + anArray[5]). System. anArray[9] = 1000.println("Element at index + anArray[7]).out. Del mismo modo. String[] anArrayOfStrings. donde type es el tipo de datos de los elementos contenidos. boolean[] anArrayOfBooleans. Usted aprenderá acerca de las diferentes construcciones de bucles (for. simplemente indica al compilador que esta variable mantendrá un arreglo del tipo especificado.  los corchetes son símbolos especiales que indica que esta variable contiene un arreglo.  una declaración de arreglo tiene dos componentes: tipo de arreglo y el nombre del arreglo. puede declarar arreglos de otros tipos: byte[] anArrayOfBytes. Al igual que las declaraciones de variables de otros tipos. long[] anArrayOfLongs. Sin embargo. float[] anArrayOfFloats. Tipo de arreglo se escribe como type[]. Declarar una Variable para hacer referencia a un Arreglo El programa anterior declara un arreglo (llamada anArray) con la siguiente línea de código: // declara un arreglo de enteros int[] anArray. while. .  Los corchetes identifican el tipo de arreglo y deben aparecer con la designación del tipo. También puede colocar los paréntesis después del nombre de la matriz: // esta forma se desaconseja float anArrayOfFloats[].  la declaración en realidad no crea un arreglo. y do-while) en la sección de Control de flujo . El tamaño del arreglo no es parte de este tipo (razón por la cual los corchetes están vacíos). char[] anArrayOfChars.En una situación de programación del mundo real. el ejemplo ilustra claramente la sintaxis de la matriz. Sin embargo. El nombre de un arreglo puede ser cualquier cosa que quieras. double[] anArrayOfDoubles. short[] anArrayOfShorts. Al igual que con las variables de otros tipos. es probable que utilice una de las construcciones de bucle soportados para iterar a través de cada elemento de la matriz. siempre que sigas las reglas y convenciones como se discute en la sección de nomenclatura . la convención desalienta esta forma. en lugar de escribir cada línea individual como en el ejemplo anterior. debe accederse por el número correspondiente de los valores del índice. por lo tanto. Esto es a diferencia de los arreglos en C o Fortran.out. 800. Si falta esta instrucción.out. "Ms. como se muestra en el siguiente programa MultiDimArrayDemo : class MultiDimArrayDemo { public static void main(String[] args) { String[][] names = { {"Mr. }. // y así sucesivamente A cada elemento del array se accede por su índice numérico: System.println("Element 2 at index 1: " + anArray[1]). 400. La siguiente instrucción en el programa ArrayDemo asigna un array con suficiente memoria para 10 elementos de tipo entero y asigna el arreglo a la variable anArray. los arreglos. entonces el compilador imprime un error como el siguiente.  = { 300. 1000 Aquí la longitud del arreglo se determina por el número de valores proporcionados entre corchetes y separados por comas. Las siguientes líneas asignan valores a cada elemento de la matriz: anArray[0] = 100. También puede declarar un arreglo de arreglos (también conocido como un arreglo multidimensional) mediante el uso de dos o más conjuntos de corchetes. // crea un arreglo de enteros anArray = new int[10]. "}. "Mrs. 900. ". // inicializa el primer elemento anArray[1] = 200.Crear. // inicializa el segundo elemento anArray[2] = 300. System. 700. tales como // arreglo multidimensional String[][] names   Cada elemento. En el lenguaje de programación Java.java:4: Variable anArray may not have been initialized. y falla la compilación: ArrayDemo. Como alternativa. 200. Una consecuencia de esto es que las filas pueden variar en longitud.out. . System. ". puede utilizar la sintaxis de método abreviado para crear e inicializar un arreglo: int[] anArray 100.println("Element 1 at index 0: " + anArray[0]). 600. inicializar y acceder a una arreglo  Otra forma de crear un array es con el operador new. 500.println("Element 3 at index 2: " + anArray[2]). un arreglo multidimensional es un arreglo cuyos componentes son ellos mismos. Jones System. Se utiliza el método System. 'd' }. deletrea la palabra "descafeinado".length).out. 'e'. 'a'. int length) Los dos argumentos Object especifican el arreglo a copiar y el arreglo al que se copiara. 't'. la posición de partida en el arreglo de destino y el número de elementos del arreglo para copiar.out. "Jones"} }. 'i'. 'n'. 2. 0. copyTo.out. posición inicial del obj destino. posición inicial del obj origen. ArrayCopyDemo.{"Smith". Jones Finalmente. Smith System. int destPos. 'e'. 'a'. } } La salida de este programa es: Mr. El código siguiente imprime el tamaño de la matriz a la salida estándar: // para determinar el tamaño del arreglo System.println(names[0][2] + names[1][1]). usted puede utilizar la propiedad incorporada length para determinar el tamaño de cualquier arreglo. // Ms. 'f'. char[] copyTo = new char[7]. // obj destino. System.println(new String(copyTo)). declara un array de elementos char.arraycopy(copyFrom. 7). System.arraycopy para copiar un subsecuencia de componentes del arreglo en un segundo arreglo: class ArrayCopyDemo { public static void main(String[] args) { char[] copyFrom = { 'd'. Copia de Arrays La clase System tiene un método arraycopy que puede utilizar para eficientar  copiar datos desde un arreglo a otro: // obj origen. 'c'. // numero de elementos a copiar public static void arraycopy(Object src. 'f'.println(anArray. } } La salida de este programa es: caffein . 'e'. Los tres argumentos int especifican la posición de partida en el arreglo de origen. int srcPos. El siguiente programa. // Mr. Smith Ms.out.println(names[0][0] + names[1][0]). Object dest. el ejemplo ArrayCopyDemo utiliza el método arraycopy de la clase de System en lugar de recorrer manualmente los elementos del arreglo origen y colocar cada uno en el arreglo de destino.Arrays . 9).Arrays. 't'. porque el arreglo de destino es devuelto por el método: class ArrayCopyOfDemo { public static void main(String[] args) { char[] copyFrom = {'d'. Esto se lleva a cabo detrás de escena. 'f'. Llenar una matriz para colocar un valor específico en cada índice (el método fill). 'n'. Algunas otras operaciones útiles proporcionados por métodos de la clase java. el rango a copiar no incluye el elemento del arreglo en el índice 9 (que contiene el carácter a). Esto puede hacerse ya sea secuencialmente. 'e'. utilizando el método de sort. Java SE proporciona varios métodos para realizar las manipulaciones de los arreglos (tareas comunes. } } Como puede ver. char[] copyTo = java. 'e'.out. 'a'.util. o al mismo tiempo. . como se puede ver en el ejemplo ArrayCopyOfDemo . como copiar.println(new String(copyTo)). 'a'.copyOfRange(copyFrom. 'c'. mientras que el tercer parámetro es el índice final del rango que se copiará. clasificar y búsqueda de arreglos) en la clase java. Por ejemplo. Tenga en cuenta que el segundo parámetro del método copyOfRange es el índice inicial del rango a ser copiado.Arrays. Comparar dos arreglos para determinar si son iguales o no (el método equals). Java SE proporciona métodos para realizar algunas de las manipulaciones más comunes relacionadas con arreglos. Para su conveniencia. el ejemplo anterior puede modificarse para utilizar el método copyOfRange de la clase java. 2. la salida de este programa es el mismo (caffein). son:     Buscar en una matriz un valor específico para obtener el índice en el cual se coloca (el método binarySearch). 'd'}. La diferencia es que mediante el método copyOfRange no requiere crear el array de destino antes de llamar al método. 'i'.util.util. 'f'. exclusivamente. usando el parallelSort método introducido en Java SE 8.util. permitiendo a los desarrolladores usar una sola línea de código para llamar al método. Clasificar un arreglo en orden ascendente.Manipulación de arreglos  Los arreglos son un concepto potente y útil usado en programación. System. aunque requiere menos líneas de código. Por ejemplo. inclusivo. La clasificación paralela de grandes arreglos en sistemas multiprocesador es más rápido que la matriz secuencial de clasificación. 'e'. En este ejemplo.Arrays . Una variable local almacena el estado temporal. es más alta su procedencia. Un ___ es un objeto contenedor que contiene un número fijo de los valores de un solo tipo. puede ser útil para usted saber con anticipación qué operadores tienen la mas alta precedencia.  Los operadores son símbolos especiales que realizan operaciones concretas en uno. Los parámetros son variables que proporcionan información extra para un método. Aprender los operadores del lenguaje de programación Java es un buen lugar para empezar. probablemente quieras saber cómo hacer algo con ellas. int. parámetros y variables locales siempre se clasifican como "variables" (no "campos"). Un arreglo es un objeto contenedor que contiene un número fijo de los valores de un solo tipo. 3.  Cuanto más cerca de la parte superior de la tabla un operador aparece. La clase java. Las variables de instancia (campos no estáticos) son únicas para cada instancia de una clase. 7. 6. se declara dentro de un ___. Mientras exploramos los operadores del lenguaje de programación Java. Operadores Ahora que ha aprendido a declarar e inicializar variables. boolean y char. . hay exactamente una copia de una variable de clase. nunca se asigna un valor predeterminado. su longitud es fija. Preguntas: Variables 1. Las variables de clase (campos estáticos) son campos declarados con el modificador static. sin importar cuántas veces se ha creado una instancia de la clase. para las variables locales. La longitud de un arreglo se establece cuando se crea el arreglo. apoyados por el lenguaje de programación Java? Cadenas de caracteres están representadas por la clase ___. dos o tres operandos y luego devuelven un resultado. Las variables locales almacenan temporalmente el estado dentro de un método. float. El término "variable de clase" es otro nombre para ___.String representa cadenas de caracteres. Después de la creación. double. Al nombrar sus campos o variables. ¿Cuáles son los ocho tipos de datos primitivos. 2. 5. hay reglas y convenciones que se deben (o debe) seguir. 4.lang.Resumen de Variables             El lenguaje de programación Java utiliza "variables" y "campos" como parte de su terminología. Los operadores en la tabla siguiente se enumeran según el orden de precedencia. short. Una variable declarada dentro de la apertura y cierre de paréntesis de la firma de un método se llama un ___. El término "variable de instancia" es otro nombre para ___. long. Los ocho tipos de datos primitivos son: byte. Un literal es la representación de código fuente de un valor fijo. El compilador asigna un valor razonable por defecto para los campos de los tipos anteriores.   Los operadores binarios se evalúan de izquierda a derecha. Los operadores de asignación se evalúan de derecha a izquierda. el operador de asignación "=" es mucho más común que el operador de desplazamiento a la derecha sin signo ">>>". Cada discusión va acompañada de código de ejemplo que se puede compilar y ejecutar. debe regir una regla de cuál se evalúa primero. . Estudiar la salida en consola le ayudará a reforzar lo aprendido. Cuando los operadores de igual prioridad aparecen en la misma expresión. Precedencias de los operadores Operadores Precedencia Postfix expr++ expr-- Unario ++expr --expr +expr -expr ~ ! Multiplicativo * / % Aditivo + - Shift (desplazar) << >> >>> Relacionales < > <= >= instanceof Igualdad == != bitwise AND & bitwise exclusive OR ^ bitwise inclusive OR | AND lógico && OR lógica || ternario ? : asignación = += -= *= /= %= &= ^= |= <<= >>= >>>= En la programación de propósito general.  Los operadores en la misma línea tienen la misma precedencia. la siguiente discusión se centra primero en los operadores que es más probable que utilice en forma regular y termina enfocándose en aquellas que son menos comunes. Con esto en mente. por ejemplo.Los operadores con mayor prioridad se evalúan antes que los operadores con precedencia relativamente menor. ciertos operadores tienden a aparecer con más frecuencia que otros. él cual divide un operandor por otro y devuelve el resto como su resultado.out. El único símbolo que puede parecer nuevo para ti es "%".1. result = result . como se discute en Crear objetos. Hay una buena posibilidad de que les reconocerás por sus homólogos en matemática básica. Viste a este operador en la clase de bicicleta. result = result / 2. result = result * 2. . int original_result = result. multiplicación y división. int gear = 1.println(original_result + " . int speed = 0.out. aritmética y operadores unarios El operador de asignación Simple Uno de los operadores más comunes que te vas a encontrar es el operador de asignación simple "=".println("1 + 2 = " + result). sustracción.println(original_result + " * 2 = " + result). original_result = result. Este operador puede usarse en objetos para asignar referencias a objetos. Operador Descripción + Operador aditivo (también utilizada para la concatenación de cadenas) - Operador de resta * Operador de multiplicación / Operador división % Operador del resto El siguiente programa. // el resultado es ahora 3 System. class ArithmeticDemo { public static void main (String[] args) { int result = 1 + 2.println(original_result + " / 2 = " + result). ArithmeticDemo. original_result = result. // el resultado es ahora 2 System.out.Asignación. // el resultado es ahora 4 System. asigna el valor a su derecha con el operador de la izquierda: int cadence = 0.out. prueba los operadores aritméticos. original_result = result.1 = " + result). Los operadores aritméticos El lenguaje de programación Java proporciona operadores que realizan la adición. // el resultado es ahora 2 System. realizan diversas operaciones como un valor de incremento/decremento en uno.result = result + 8. indica el valor positivo (sin embargo. incrementa un valor de 1 -- Operador de decremento. la variable thirdString contiene " This is a concatenated string. El + operador puede utilizarse también para concatenar (unir) dos cadenas juntas. } } Al final de este programa. System. Los operadores unarios Los operadores unarios requieren sólo uno de los operadores. invierte el valor de tipo booleano .1 = 2 2 * 2 = 4 4 / 2 = 2 2 + 8 = 10 10 % 7 = 3 También puedes combinar los operadores aritméticos con el operador de asignación simple para crear asignaciones compuestas. que queda impreso a la salida estándar.println(original_result + " + 8 = " + result). ambos incrementan el valor de x por 1.out. // el resultado es ahora 3 System. } } Este programa imprime lo siguiente: 1 + 2 = 3 3 .". String secondString = " a concatenated string. Operador Descripción + operador aditivo unario .". original_result = result. y x=x+1. result = result % 7. operador unario. los números son positivos sin esto) - Menos. disminuye un valor de 1 ! Operador complemento lógico. String thirdString = firstString+secondString. // el resultado es ahora 10 System.out. o invertir el valor de tipo booleano. Por ejemplo.println(original_result + " % 7 = " + result).println(thirdString). negar una expresión. x+=1.out. niega una expresión ++ Operador de incremento. como se muestra en el siguiente programa ConcatDemo : class ConcatDemo { public static void main(String[] args){ String firstString = "This is". result--. // el resultado es ahora 0 System.out. no importa qué versión elegir. result = -result.out. El siguiente programa. ++i.out.println(result).out.println(++i).println(result). // el resultado es ahora 1 System. La única diferencia es que la versión prefija   (++result) evalúa sobre el valor incrementado. result++. UnaryDemo. // imprime 6 System.println(i). PrePostDemo. boolean success = false. // imprime 4 System. Pero si utiliza este operador en una parte de una expresión más grande.out. ambos terminarán en que result se incrementa en uno. // false System.println(!success). // el resultado es ahora 1 System.println(result). (result++) se evalúa sobre el valor original.El siguiente programa. En el código result++.println(success). i++.out.out. // true System. ilustra el operador de incremento unario prefijo/postfijo: class PrePostDemo { public static void main(String[] args){ int i = 3.out.out. } } Los operadores de incremento/decremento pueden aplicarse antes del (prefijo) o después del (posfijo) operador. // imprime 6 .println(i). elegir indistintamente puede hacer una diferencia significativa. y ++result. prueba los operadores unarios: class UnaryDemo { public static void main(String[] args) { int result = +1. Si sólo está realizando un simple incremento/decremento.println(result). // imprime 5 System. // el resultado es ahora -1 System. int value2 = 2. // imprime 7 System. menor. == != > >= < <= igual no es mayor mayor menor menor a igual a que o igual que que o igual que El siguiente programa.out.println("value1 != value2").out. cuando se prueba si dos valores primitivos son iguales.out. ComparisonDemo.out.out.println(i).println("value1 < value2"). prueba los operadores de comparación: class ComparisonDemo { public static void main(String[] args){ int value1 = 1. Tenga en mente que  debe utilizar "==".println("value1 > value2"). if(value1 == value2) System. if(value1 != value2) System.System. o no es igual a otro operador.out.out. if(value1 < value2) System. } } Salida: value1 != value2 value1 < value2 value1 <= value2 . no "=".println("value1 == value2"). if(value1 > value2) System.println(i++). if(value1 <= value2) System. } } Operadores de igualdad y relacionales Los operadores de igualdad y relacionales  determinan si uno de los operadores es mayor. igual. La mayoría de estos operadores probablemente se verá familiar también.println("value1 <= value2"). println("value1 is 1 AND value2 is 2"). De lo contrario.out.out.println(result). && Condicional-AND || Condicional-OR El siguiente programa. este operador debe leerse como: "Si someCondition es true. prueba estos operadores: class ConditionalDemo1 { public static void main(String[] args){ int value1 = 1. result = someCondition ? value1 : value2. asigne el valor de value2 a result. int value2 = 2. int result. En el siguiente ejemplo. class ConditionalDemo2 { public static void main(String[] args){ int value1 = 1. este programa imprime "1" en la pantalla.println("value1 is 1 OR value2 is 1"). asigne el valor de value1 a result. if((value1 == 1) && (value2 == 2)) System.Los operadores condicionales Los operadores && y || realizan operaciones Y-condicional e O-condicional en dos expresiones boolean. System. que puede ser considerado como abreviatura para una instrucción if-then-else." El siguiente programa prueba el operador ?: en la ConditionalDemo2. } } Otro operador condicional es ?:. if((value1 == 1) || (value2 == 1)) System. int value2 = 2. } } Porque someCondition es true. .out. ConditionalDemo1. que significa que se evalúa el segundo operador sólo si es necesario. boolean someCondition = true. Este operador es también conocido como el operador ternario porque utiliza tres operandos. Estos operadores muestran un comportamiento "cortocircuito".  Use este operador ?: en lugar de una instrucción if-then-else si hace el código más legible; Por ejemplo, cuando las expresiones son compactas y sin efectos secundarios (tales como las asignaciones). El operador de comparación de tipo instanceof   El operador instanceof compara un objeto con un tipo especificado. Se utiliza para comprobar si un objeto es una instancia de una clase, una instancia de una subclase o una instancia de una clase que implementa una interfaz determinada. El siguiente programa, InstanceofDemo, define una clase padre (llamado Parent), una interfaz sencilla (llamado MyInterface) y una clase de hija (llamado Child) que hereda de los padres e implementa la interfaz. class InstanceofDemo { public static void main(String[] args) { Parent obj1 = new Parent(); Parent obj2 = new Child(); System.out.println("obj1 instanceof Parent: " + (obj1 instanceof Parent)); System.out.println("obj1 instanceof Child: " + (obj1 instanceof Child)); System.out.println("obj1 instanceof MyInterface: " + (obj1 instanceof MyInterface)); System.out.println("obj2 instanceof Parent: " + (obj2 instanceof Parent)); System.out.println("obj2 instanceof Child: " + (obj2 instanceof Child)); System.out.println("obj2 instanceof MyInterface: " + (obj2 instanceof MyInterface)); } } class Parent {} class Child extends Parent implements MyInterface {} interface MyInterface {} Salida: obj1 obj1 obj1 obj2 obj2 obj2 instanceof instanceof instanceof instanceof instanceof instanceof Parent: true Child: false MyInterface: false Parent: true Child: true MyInterface: true Cuando usa el operador instanceof , tenga en cuenta que null no es una instancia de nada. Operadores Bitwise y Bit Shift El lenguaje de programación Java también proporciona operadores que realizan operaciones bit a bit y de desplazamiento de bit en tipos integros. Los operadores discutidos en esta sección se utilizan poco. Por lo tanto, su cobertura es breve; la intención es simplemente hacerle consciente de que existen estos operadores. El operador unario de complemento Bitwise "~" invierte un patrón de bits; se puede aplicar a cualquiera de los tipos integros, haciendo todos los "0" a "1" y todos los "1" a "0". Por ejemplo, un byte contiene 8 bits; aplicar este operador a un valor cuyo patrón es "00000000" cambiaría su patrón a "11111111". El operador de desplazamiento a la izquierda con signo "<<" dezplaza el patrón de bit a la izquierda y el operador de desplazamiento a la derecha con signo ">>" dezplaza el patrón de bit a la derecha. El patrón de bits esta dado por el operando de la izquierda y el número de posiciones a desplazar por el operando de la derecha. El operador de desplazamiento a la derecha sin signo ">>>" cambia un cero en la posición más a la izquierda, mientras que la posición más a la izquierda después de ">>" depende de la extensión del signo. El operador Bitwise & realiza una operación bitwise AND. El operador Bitwise ^ realiza una operación bitwise OR exclusiva. El operador Bitwise | realiza una operación bitwise OR inclusiva. El siguiente programa, BitDemo, utiliza el operador bitwise AND para imprimir el número "2" en salida estándar. class BitDemo { public static void main(String[] args) { int bitmask = 0x000F; int val = 0x2222; // prints "2" System.out.println(val & bitmask); } } Resumen de operadores La siguiente referencia rápida resume los operadores soportados por el lenguaje de programación Java. Operador de asignación simple = Operador de asignación simple Operadores aritméticos + Operador aditivo (tambien usado para la concatenación de String) operador de resta * operador de multiplicación / % operador de Division operador de resto Operadores unarios + operador aditivo unario:indica el valor positivo (sin embargo, los números son positivos sin esto) Menos; operador unario, niega una expresion Operador de incremento; incrementa un valor de 1 Operador de decremento; disminuye un valor de 1 Operador complemento lógico; invierte el valor de tipo booleano ++ -! Igualdad y operadores relacionales == != > >= < <= Equal to Not equal to Greater than Greater than or equal to Less than Less than or equal to Operadores condicionales && || ?: Conditional-AND Conditional-OR Ternary (forma abreviada de de la sentencia if-then-else) Operador de comparación de tipo instanceof Compara un objecto con un tipo especificado Operadores Bitwise bit a bit y Bit Shift (mover bits) ~ << >> >>> & ^ | Unary bitwise complement Signed left shift Signed right shift Unsigned right shift Bitwise AND Bitwise exclusive OR Bitwise inclusive OR Preguntas y ejercicios: operadores Preguntas 1. Considere el siguiente fragmento de código. arrayOfInts[j] > arrayOfInts[j+1] ¿Que operadores contiene el código? 2. 5. 4. Ejercicios 1. a. Cambiar el siguiente programa para utilizar asignaciones compuestas: class ArithmeticDemo { public static void main (String[] args){ int result = 1 + 2.println(result). // } } args){ "4" "5" "6" "6" "7" . result = result * 2.out. i++. // result is now 2 System.out.println(i).println(i++).println(result). = o ==? Explica el siguiente ejemplo de código: result = someCondition ? value1 : value2.out. int n = i++%5. utiliza la versión prefija (++i))? ¿Para invertir el valor de un boolean. System. // ++i. que operador usarías? ¿Qué operador se utiliza para comparar dos valores. Considere el siguiente fragmento de código. int i = 10.out.println(result).out. explique por qué el valor "6" se imprime dos veces seguidas: class PrePostDemo { public static void main(String[] int i = 3. // result is now 3 System.println(i). // result is now 10 result = result % 7. } } En el siguiente programa.out.println(result). // result is now 3 System.out. // result is now 2 System. result = result / 2. // System.out.out. ¿Cuáles son los valores de i y n después de que se ejecuta el código? ¿Cuáles son los valores finales de i y n si en lugar de utilizar el operador postfijo de incremento (i++).1.out. result = result .println(++i). b.println(i). 3. // System. result = result + 8. // result is now 4 System. System. // System.println(result). puede escribir lo siguiente: (x + y) / 100 // no ambiguo. Los operadores que tienen una mayor prioridad consiguen ser evaluados primero. Ya hemos visto ejemplos de expresiones. es tiempo de aprender acerca de las expresiones.out. siempre y cuando el tipo de datos requerido por una parte de la expresión coincide con el tipo de datos del otro.Expresiones. una expresión puede devolver otros tipos de valores. ilustrados en negrita abajo: int cadence = 0. el orden en el cual se evalúa la expresión es importante porque el resultado de la multiplicación es independiente del orden. el orden es determinado por la precedencia asignada a los operadores en el uso dentro de la expresión. La expresión cadence = 0 devuelve un int porque el operador de asignación devuelve un valor del mismo tipo de datos que el de su operador de la izquierda. los siguientes dos comandos son equivalentes: . Por ejemplo. El lenguaje de programación Java permite construir expresiones compuestas de varias expresiones más pequeñas. tales como boolean o String. la siguiente expresión da resultados diferentes. Por ejemplo. recomendado Si usted no indica explícitamente el orden para las operaciones a realizar. Expresiones Una expresión es una construcción compuesta por variables. dependiendo de si se realiza la adición o la operación de división primero: x + y / 100 // ambiguo Puede especificar exactamente cómo una expresión serán evaluadas utilizando paréntesis: (y). las expresiones son los componentes básicos de las instrucciones. anArray[0] = 100. no importa en qué orden se aplican las multiplicaciones. Por ejemplo. System. Por lo tanto. en este caso. para hacer la anterior expresión inequívoca. se evalúa como un valor único.println("Element 1 at index 0: " + anArray[0]). las instrucciones pueden agruparse en bloques. instrucciones y bloques Ahora que comprende las variables y los operadores. int result = 1 + 2. Aquí hay un ejemplo de una expresión compuesta: 1 * 2 * 3 En este caso particular. // result is now 3 if (value1 == value2) System.println("value1 == value2"). que computan los valores. el operador división tiene una mayor prioridad que el operador de suma. que fueron construidas según la sintaxis del lenguaje. Sin embargo. el resultado es siempre el mismo.out.  Los operadores se utilizan en la construcción de expresiones. esto no es cierto de todas las expresiones. instrucciones y bloques. Como se puede ver en las otras expresiones. cadence es un int. operadores y las invocaciones de método. El tipo de datos del valor devuelto por una expresión depende de los elementos utilizados en la expresión. ). Ya has visto muchos ejemplos de instrucciones de declaración: // instrucción de declaración double aValue = 8933. las instrucciones o sentencias de control de flujo regulan el orden en que se ejecutan las instrucciones. Estos son algunos ejemplos de instrucciones de expresión. // instrucción de creación de objeto Bicycle myBike = new Bicycle().out. Esta práctica hace más fácil leer y mantener el código. Una declaración declara una variable. El ejemplo siguiente.234.x + y / 100 x + (y / 100) // no ambiguo. 2. Bloques  Un bloque es un grupo de cero o más instrucciones entre corchetes y puede ser utilizado en cualquier lugar que se permite una sola sentencia. Además de las instrucciones de expresión. // instrucción de asignación aValue = 8933.  Una instrucción forma una unidad completa de ejecución. Instrucciones o sentencias Las instrucciones son más o menos equivalentes a las oraciones en lenguas naturales.println("Hello World!"). // instrucción de incremento aValue++. Los siguientes tipos de expresiones se pueden realizar en una instrucción por la expresión de un punto y coma (terminación. Finalmente. // instrucción de invocación de método System. declaración de instrucciones e instrucciones de control de flujo.     Expresiones de asignación Cualquier uso de ++ o -Invocaciones de método Expresiones de creación de objeto Tales instrucciones son llamadas instrucciones o sentencias de expresión. recomendado Al escribir expresiones compuestas. BlockDemo. debe ser explícito e indicar entre paréntesis que los operadores deben ser evaluados primero. ilustra el uso de bloques: class BlockDemo { public static void main(String[] args) { .234. existen otros dos tipos de instrucciones: 1. Ejercicios Identifique los siguientes tipos de instrucciones de expresión:     aValue = 8933. que computan los valores. System. Las expresiones son los componentes básicos de ___. en las instrucciones del control de flujo. Bicycle myBike = new Bicycle()."). } // finaliza el bloque 2 } } Preguntas y ejercicios: expresiones. Un bloque es un grupo de cero o más instrucciones entre ___ y puede ser utilizado en cualquier lugar que se permite una sola sentencia. 3.println("Condition is false. 1 * 2 * 3 6.boolean condition = true. 5. if (condition) { // comienza el bloque 1 System. Las instrucciones son más o menos equivalentes a las oraciones en lenguas naturales. Esta sección describe las instrucciones para la toma de decisiones:    if-then if-then-else switch .out. 7.out.234. una instrucción termina con un ___. Los operadores pueden utilizarse en la construcción de ___. Instrucciones de control de flujo Las instrucciones dentro de los archivos fuente generalmente se ejecutan de arriba hacia abajo. en el orden en que aparecen.println("Condition is true. aValue++. El siguiente fragmento de código es un ejemplo de una expresión ___. la ruptura del flujo de ejecución mediante el empleo de toma de decisiones. pero en lugar de acabar con un punto. 2. Sin embargo. } // finaliza el bloque 1 else { // comienza el bloque 2 System. instrucciones y bloques Preguntas 1. 4. bucles y ramificaciones. Las instrucciones pueden agruparse en ___. permite a su programa condicionar la ejecución de determinados bloques de código.out.").println("Hello World!"). Omitirlos puede hacer el código más frágil. siempre que la cláusula "then" contenga solamente una instrucción: void applyBrakes() { // lo mismo que el anterior. Una posible implementación del método applyBrakes podría ser como sigue: void applyBrakes() { // la cláusula "if": la bicicleta debe estar en movimiento if (isMoving){ // la cláusula "then": disminuir la velocidad actual currentSpeed--.  Le dice a su programa que ejecute una determinada sección de código sólo si una determinada prueba se evalúa como true. } Decidir cuándo omitir las llaves es una cuestión de gusto personal.Instrucciones de bucle:    for while do-while Instrucciones de ramificación:    break continue return Las instrucciones if-then e if-then-else La instrucción if-then La instrucción if-then es la más básica de todas las instrucciones de control de flujo. la apertura y cierre de llaves son opcionales. . el control salta hasta el final de la instrucción if-then. } } Si esta prueba se evalúa como false (es decir. sólo obtendrá resultados equivocados. pero sin llaves if (isMoving) currentSpeed--. Si una segunda instrucción más tarde se añade a la cláusula "then". Por ejemplo. la clase Bicycle podría permitir a los frenos disminuir la velocidad de la bicicleta solamente si la bicicleta ya está en marcha. un error común sería olvidar añadir las llaves recién requeridas. que la bicicleta no está en movimiento). Además. El compilador no puede detectar este tipo de error. } else { grade = 'F'.println("Grade = { { { " + grade).err. } System. IfElseDemo. void applyBrakes() { if (isMoving) { currentSpeed--. . } else if (testscore >= 60) grade = 'D'. } else if (testscore >= 70) grade = 'C'. char grade. } } El siguiente programa.println("The bicycle has already stopped!").) y no se evalúan las condiciones restantes.La instrucción if-then-else  La instrucción if-then-else proporciona un camino secundario a la ejecución cuando una cláusula "if" se evalúa como false. se ejecutan las instrucciones apropiadas (grade = 'C'. class IfElseDemo { public static void main(String[] args) { int testscore = 76.out. } else { System. una B por una puntuación de 80% o superior y así sucesivamente. asigna una calificación basada en el valor de una prueba: una A para una calificación de 90% o superior. } else if (testscore >= 80) grade = 'B'. En este caso. Sin embargo. la acción es simplemente imprimir un mensaje de error indicando que ya se ha detenido la bicicleta. } } La salida del programa es: Grade = C Usted puede haber notado que el valor de testscore puede satisfacer más de una expresión en la declaración compuesta: 76 >= 70 y 76 >= 60. Puedes usar una instrucción if-then-else en el método applyBrakes para tomar medidas si se aplican los frenos cuando la bicicleta no está en movimiento. una vez que se satisface una condición. if (testscore >= 90) { grade = 'A'. El código muestra el nombre del mes. = "March". la clase String y algunas clases especiales que contienen ciertos tipos primitivos: Character. También funciona con tipos enumerados (discutido en Tipos Enum). La sentencia break lo lleva a la siguiente sentencia ejecutable fuera del bloque en el que se ubica. = "September". Short e Integer (discutido en números y cadenas). case 4: monthString break. case 8: monthString break. switch (month) { case 1: monthString break. basándose en el valor del month. Byte. short. case 7: monthString break. = "February". mediante la instrucción switch. declara un int llamado month cuyo valor representa un mes. = "May". SwitchDemo. = "January". = "June". case 5: monthString break. . case 9: monthString break. case 2: monthString break. = "July". char y tipos de datos primitivos int. case 6: monthString break.La instrucción switch A diferencia de las instrucciones if-then e if-then-else. = "August". = "October". Un switch trabaja con byte. case 3: monthString break. = "April". El ejemplo de código siguiente. case 10: monthString break.   La instrucción switch puede tener un número de posibles rutas de ejecución. String monthString. public class SwitchDemo { public static void main(String[] args) { int month = 8. break. if (month == 1) { System. El programa SwitchDemoFallThrough muestra las instrucciones en un bloque switch que fracasan. independientemente de la expresión de etiquetas posteriores case. August se imprime a la salida estándar.out. } . hasta que se encuentre una instrucción break. // y asi… Decidir si utilizar la instrucción if-then-else o una instrucción switch se basa en la legibilidad y la expresión que está probando la instrucción. El Flujo de control continúa con la primera instrucción que sigue en el bloque switch. case 12: monthString = "December".out. las instrucciones dentro del bloque switch fracasan: todas las instrucciones después de la correspondiente etiqueta del case son ejecutadas en secuencia.. Una declaración switch prueba expresiones basadas solamente en un único número entero.println(monthString). Las instrucciones de break son necesarias porque sin ellas.   Una instrucción if-then-else puede probar expresiones basadas en rangos de valores o condiciones.println("January"). Otro punto de interés es la instrucción break. Una instrucción en el bloque del switch puede etiquetarse con una o más etiquetas de case o default. } System.out. break.  Cada instrucción break termina la instrucción switch en la que se encuentra. break. } } En este caso. valor enumerado u objeto String. El programa muestra el mes correspondiente al número entero month y los meses que siguen en el año: public class SwitchDemoFallThrough { public static void main(String[] args) { . luego ejecuta todas las instrucciones que le siguen a la correspondiente etiqueta case. También se puede mostrar el nombre del mes con declaraciones if-then-else : int month = 8. default: monthString = "Invalid month".  La instrucción switch evalúa la expresión. } else if (month == 2) { System.case 11: monthString = "November".println("February")..  El cuerpo de una instrucción switch es conocido como bloque del switch. int month = 8. el break final no es necesario porque el flujo cae fuera de la declaración switch.util.add("December").add("July"). case 2: futureMonths.  La sección default se encarga de todos los valores que no son explícitamente manejados por una de las secciones del case. break.util.isEmpty()) { System.add("August"). case 3: futureMonths. case 10: futureMonths. default: break.out. el siguiente ejemplo de código muestra cómo una declaración puede tener varias etiquetas de case.add("January"). switch (month) { case 1: futureMonths. SwitchDemo2.add("June").ArrayList<String> futureMonths = new java. } else { for (String monthName : futureMonths) { System. case 7: futureMonths.add("May").ArrayList<String>(). } } } } Esta es la salida del código: August September October November December Técnicamente.java. . case 8: futureMonths. int numDays = 0. El ejemplo de código calcula el número de días en un mes determinado: class SwitchDemo2 { public static void main(String[] args) { int month = 2. int year = 2000.add("April"). } if (futureMonths. Es recomendable utilizar un break para que modificar el código sea más fácil y menos propenso a errores. case 11: futureMonths. case 6: futureMonths.add("March").println(monthName). case 9: futureMonths.println("Invalid month number"). case 12: futureMonths. case 5: futureMonths.add("February").add("September").out. case 4: futureMonths.add("October").add("November"). break. break. puede utilizar un objeto String en la expresión de la instrucción switch.out. StringSwitchDemo. else numDays = 28. } System. case 4: case 6: case 9: case 11: numDays = 30. } } Esta es la salida del código: Number of Days = 29 El uso de Strings en la instrucción switch En Java SE 7 y versiones posteriores. default: System. } // toLowerCase convierte en minuscula switch (month.println("Invalid month. . El ejemplo de código siguiente."). if (month == null) { return monthNumber. case 2: if (((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0)) numDays = 29.out. break. muestra el número del mes basándose en el valor de la String denominada month: public class StringSwitchDemo { public static int getMonthNumber(String month) { int monthNumber = 0.toLowerCase()) { case "january": monthNumber = 1.println("Number of Days = " + numDays).switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: numDays = 31. break. case "december": monthNumber = break.out. case "november": monthNumber = break. case "june": monthNumber = break. case "july": monthNumber = break. 7. if (returnedMonthNumber == 0) { System. 9.println("Invalid month"). La String en la expresión switch se compara con las expresiones asociadas con la etiqueta de cada case como si se utilizara el método String. A fin de que el ejemplo . case "march": monthNumber = break. default: monthNumber = break. int returnedMonthNumber = StringSwitchDemo. 8. } return monthNumber. 0. 5. } } } La salida de este código es 8. case "may": monthNumber = break. case "august": monthNumber = break. } else { System. case "september": monthNumber = break. case "october": monthNumber = break. 12.out. 4.getMonthNumber(month). case "february": monthNumber = break. case "april": monthNumber = break. 11. 6. 3. } public static void main(String[] args) { String month = "August".break.println(returnedMonthNumber).equals. 2. 10. StringSwitchDemo acepte cualquier mes independientemente del caso. que debe devolver un valor boolean. } } } Puede implementar un bucle infinito mediante la instrucción while como sigue: while (true){ // aqui va tu codigo } El lenguaje de programación Java también proporciona una instrucción do-while. Las instrucciones while y do-while  La instrucción ciclica while continuamente ejecuta un bloque de instrucciones mientras una condición particular es true. que puede expresarse de la siguiente manera: do { instrucción(es) // las instrucciones se ejecutan al menos una vez } while (expresión). la instrucción while ejecuta la instrucción(es) en el bloque de while. Su sintaxis puede expresarse como: while (expresión) { instrucción(es) }    La instrucción while evalúa la expresión. Si la expresión se evalúa como true.out. while (count < 11) { System. Asegúrese de que la expresión en cualquier instrucción switch no es null para impedir que una NullPointerException sea lanzada. count++. month se convierte en minúscula (con el método toLowerCase) y todas las cadenas asociadas con el case son etiquetas en minúsculas. Se logra mediante la instrucción while imprimir los valores del 1 al 10 como en el siguiente programa WhileDemo: class WhileDemo { public static void main(String[] args){ int count = 1. . Nota: este ejemplo comprueba si la expresión en la instrucción switch es null. La instrucción while continúa probando la expresión y ejecutando su bloque hasta que la expresión se evalúa como false.println("Count is: " + count).   El siguiente programa. i++){ System. incremento) { instrucción(es) } Cuando use esta versión de la instrucción for. La diferencia entre do-while y while es que do-while evalúa su expresión en la parte inferior del bucle en lugar de la parte superior. se ejecuta una vez. } } } La salida de este programa es: Count is: 1 . tenga en cuenta que:  La expresión inicialización. } while (count < 11). La forma general de la instrucción for puede expresarse de la siguiente manera: for (inicialización. terminación.out. Los programadores a menudo se refieren a él como el "for loop" debido a la forma en la cual el bucle se repite hasta que se satisface una condición particular. Como se muestra en el siguiente programa DoWhileDemo: class DoWhileDemo { public static void main(String[] args){ int count = 1.out. count++. inicializa el bucle. Por lo tanto. La expresión de incremento se invoca después de cada iteración a través del bucle.println("Count is: " + count). las instrucciones dentro del bloque do siempre se ejecutan al menos una vez. Cuando la expresión terminación se evalúa como false. i < 11. ForDemo. utiliza la forma general de la instrucción for para imprimir los números del 1 al 10 a la salida estándar: class ForDemo { public static void main(String[] args){ for(int i = 1. es perfectamente aceptable para esta expresión incrementar o disminuir un valor. do { System. cuando comienza el bucle. } } La instrucción for  La instrucción cíclica for proporciona una forma compacta para iterar sobre un rango de valores.println("Count is: " + i). finaliza el bucle. 9. Las tres expresiones del bucle for son opcionales. El siguiente programa. Si la variable que controla una instrucción for no es necesaria fuera del bucle.6. j y k se utilizan para el control de los bucles for.6. se puede crear un bucle infinito de la siguiente manera: // loop infinito for ( . así que puede ser utilizado en las expresiones de terminación y de incremento.8.2.10}.  Los nombres i.3.4.Count Count Count Count Count Count Count Count Count is: is: is: is: is: is: is: is: is: 2 3 4 5 6 7 8 9 10 Observe cómo el código declara una variable dentro de la expresión de inicialización.7. considere la siguiente matriz. for (int item : numbers) { System.9.8.3. EnhancedForDemo. ) { // your code goes here } La instrucción for también tiene otra forma diseñada por iteración a través de colecciones y arreglos de esta forma se refiere a veces como  Instrucción for mejorado y puede ser utilizada para hacer los bucles más compactos y fáciles de leer.println("Count is: " + item).5.out. for (parametro : nombrearreglo) { instrucción(es) } Para demostrarlo.5. El alcance de esta variable se extiende desde su declaración hasta el final del bloque regido por la instrucción for. .4. declarándolos dentro de la expresión de inicialización limita su vida útil y reduce errores. es mejor declarar la variable en la expresión de inicialización. que contiene los números del 1 al 10: int[] numbers = {1.10}. utiliza el bucle for mejorado a través de la matriz: class EnhancedForDemo { public static void main(String[] args){ int[] numbers = {1.2. } } } .7. como se muestra en el siguiente programa BreakDemo: class BreakDemo { public static void main(String[] args) { int[] arrayOfInts = { 32. while. También puede utilizar una etiqueta break para terminar un bucle for. la variable item retiene el valor actual de la matriz de números. 127 }. 589.println("Found " + searchfor + " at index " + i). La salida de este programa es la misma que antes: Count Count Count Count Count Count Count Count Count Count  is: is: is: is: is: is: is: is: is: is: 1 2 3 4 5 6 7 8 9 10 Se recomienda utilizar este forma de instrucción for en vez de la forma general siempre que sea posible. Instrucciones de ramificación La instrucción break  La instrucción break tiene dos formas: con etiqueta y sin etiqueta. i < arrayOfInts. } } if (foundIt) { System. int i. 622. o do-while.out.println(searchfor + " not in the array"). 8. boolean foundIt = false.En este ejemplo. 87. for (i = 0. } } } . 2000. 3. int searchfor = 12. i++) { if (arrayOfInts[i] == searchfor) { foundIt = true. } else { System. break. 1076. 12. Viste la forma sin etiqueta en la discusión anterior de la instrucción switch.length.out. int j = 0. } else { System. 589 }. int searchfor = 12. while. La salida de este programa es: Found 12 at index 4  Una instrucción break sin etiqueta termina las instrucciones switch. i < arrayOfInts. Luego el flujo de control se transfiere después del bucle for. 3. pero utiliza bucles for anidados para buscar un valor en una matriz bidimensional. " + j). finaliza el bucle for cuando se encuentra ese valor. break search. La instrucción break.out. } } } if (foundIt) { System. 127.  Cuando el valor se encuentra. un break con etiqueta finaliza el bucle for externo (etiquetado como " search "): class BreakWithLabelDemo { public static void main(String[] args) { int[][] arrayOfInts = { { 32. Found 12 at 1. for. 2000. { 12. } } } Ésta es la salida del programa. o dowhile mas internas. 87. 955 } }. 0 . Un break con etiqueta termina una instrucción externa. 1076.println("Found " + searchfor + " at " + i + ". es similar al programa anterior. j++) { if (arrayOfInts[i][j] == searchfor) { foundIt = true.Este programa busca el número 12 en una matriz. boolean foundIt = false.length. BreakWithLabelDemo.println(searchfor + " not in the array"). j < arrayOfInts[i].out.length. { 622. que se muestra en negrita. 8 }.  El siguiente programa. 77. search: for (i = 0. i++) { for (j = 0. int i. Si es una "p". Una instrucción con etiqueta continue salta la iteración actual de un bucle externo marcado con la etiqueta dada. // procesa p's numPs++. while. Se necesitan dos bucles anidados: . for (int i = 0. La forma sin etiqueta salta al final del cuerpo del bucle más interno y evalúa la expresión boolean que controla el bucle. diciendo que ha encontrado 35 p en lugar de 9. int numPs = 0. contando las ocurrencias de la letra "p". i++) { // interesado solo en p's if (searchMe. Para ver este efecto con más claridad. El Flujo se transfiere a la instrucción que sigue inmediatamente a la instrucción con etiqueta (finalizada). el programa incrementa el contador de letra. La instrucción continue  La instrucción continue salta la iteración actual de un bucle for.out. El siguiente programa de ejemplo. El siguiente programa. intente quitar la declaración continue y vuelva a compilar. Si el carácter actual no es una p. int max = searchMe. o dowhile.La instrucción break termina la instrucción etiquetada."). ContinueDemo. } System. No transfiere el flujo de control a la etiqueta. i < max.charAt(i) != 'p') continue. pasa a través de una String. } } Aquí está la salida de este programa: Found 9 p's in the string. class ContinueDemo { public static void main(String[] args) { String searchMe = "peter piper picked a " + "peck of pickled peppers".println("Found " + numPs + " p's in the string. ContinueWithLabelDemo.length(). la declaración continue omite el resto del bucle y procede al siguiente carácter. utiliza bucles anidados para buscar una subcadena dentro de otra cadena. la cuenta será incorrecta. Cuando se ejecuta el programa otra vez. int j = i. Cuando un método es declarado void. class ContinueWithLabelDemo { public static void main(String[] args) { String searchMe = "Look for a substring in me".charAt(k++)) { continue test. test: for (int i = 0. while (n-. La instrucción return sale por el método actual. este utiliza la forma de return que no devuelve un valor. int max = searchMe. boolean foundIt = false. simplemente ponga el valor (o una expresión que calcula el valor) después de la palabra clave return.!= 0) { if (searchMe. return ++count. } System. Para devolver un valor.charAt(j++) != substring.length(). int k = 0.length().length() substring. y el flujo de control regresa a donde se invocó el método. usa la forma etiquetada de continue para saltar una iteración en el bucle externo. La instrucción return tiene dos formas:   una que devuelve un valor otra que no devuelve. .out. } } Aquí está la salida de este programa. String substring = "sub". i <= max. break test. El siguiente programa. ContinueWithLabelDemo. El tipo de datos del valor devuelto debe coincidir con el tipo devuelto por el método declarado.  uno para iterar sobre la subcadena uno para iterar sobre la cadena en donde vamos a buscar. } } foundIt = true. i++) { int n = substring.println(foundIt ? "Found it" : "Didn't find it"). Found it La instrucción return La última de las instrucciones de ramificación es la instrucción return. Considere el siguiente fragmento de código. La lección de clases y objetos cubrirá todo lo que necesitas saber sobre métodos de escritura. 5. La instrucción for proporciona una forma compacta para iterar sobre un rango de valores.println("third string"). else System. a. A diferencia de if-then y if-then-else la instrucción switch se permite para cualquier número de rutas de ejecución posible. pero evalúa su expresión en la ___ del bucle. las declaraciones dentro del bloque do siempre se ejecutan al menos una vez. 2.println("second string").out. una de las cuales fue diseñada para crear bucles a través de las colecciones y los arreglos. La diferencia entre do-while y while es que do-while evalúa su expresión en la parte inferior del bucle en lugar de la parte superior. 4. 3. La instrucción if-then-else proporciona un camino secundario a la ejecución cuando una cláusula "si" se evalúa como false. La instrucción de ___ permite cualquier número de rutas de ejecución posible. Tiene dos formas. La instrucción de ___ es similar a la instrucción while.return. ¿Cómo se escribe un bucle infinito mediante la instrucción for? ¿Cómo se escribe un bucle infinito mediante la instrucción while? Ejercicios 1. System. Le dice al programa que ejecute una determinada sección de código sólo si una prueba en particular se evalúa como true. La más básica instrucción de los flujos de control soportado por el lenguaje de programación Java es la instrucción de ___. Por lo tanto.println("first string"). ¿Qué salida crees que el código producirá si aNumber es 3? . if (aNumber >= 0) if (aNumber == 0) System.out. Preguntas y ejercicios: Control de flujo Preguntas 1. La instrucción while y do-while continuamente ejecutan un bloque de sentencias mientras una condición particular es true. Resumen de las instrucciones de flujo de Control La instrucción if-then es la más básica de todas las instrucciones de flujo de control.out. en otras palabras. Practicas. ¿cuál es el flujo de control para el fragmento de código? Usando sólo espacios y saltos de línea. Escribe un programa de prueba que contenga el fragmento de código anterior.b. { y }. c. hacer aNumber 3. reformatear el fragmento de código para que el flujo de control sea fácil de entender. ¿Cuál es la salida del programa? ¿Es lo que has predicho? Explicar por qué la salida es lo que es. d. . Utilice llaves. para clarificar el código. Esta lección cubre también clases anidadas dentro de otras clases y enumeraciones. miembros de instancia y control de acceso. Las secciones posteriores de esta lección retroceden y explican las declaraciones de clase paso a paso. Por el momento. clases especializadas que le permiten definir y utilizar conjuntos de constantes. Tipos de enumeración Esta sección cubre las enumeraciones. con bicicletas de carreras. Clases La introducción a los conceptos de orientación a objetos en la lección titulada Conceptos de programación orientada a objetos utiliza una clase de bicicleta como ejemplo. Usted aprenderá a crear una instancia de un objeto y. para darle una visión general de una declaración de clase. En esta lección. clase vs. métodos y constructores. incluyendo declarar miembros. Clases Esta sección le muestra la anatomía de una clase y cómo declarar campos. Aquí está el código del ejemplo para una posible implementación de una clase de Bicycle. También hay una discusión sobre cuándo utilizar este enfoque. Clases anidadas Clases anidadas estáticas anónimas internas. no se preocupe por los detalles. public class Bicycle { // la clase Bicycle tiene // tres campos . bicicletas de montaña y bicicletas tándem como subclases. puede aprender a escribir sus propias clases. métodos y constructores. clases locales están cubiertas. encontrará información sobre cómo definir sus propias clases. Más tipos Esta sección cubre más aspectos de las clases que dependen del uso de referencias a objetos y sobre el operador dot que has aprendido en la sección anterior: devolver valores desde los métodos. Objetos Esta sección cubre la creación y uso de objetos. variables. Aprenderá a utilizar las clases para crear objetos y cómo utilizar los objetos que crea. cómo se utiliza el operador dot para acceder a las variables de instancia y métodos del objeto.Lección: Clases y objetos Con el conocimiento que ahora tiene de los fundamentos del lenguaje de programación Java. la palabra clave this. una vez instanciado. clases. seatHeight = startHeight. .public int cadence. startSpeed. } } MountainBike hereda todos los campos y métodos de Bicycle y agrega el campo seatHeight y un método para configurarlo (las bicicletas de montaña tienen asientos que se pueden mover hacia arriba y hacia abajo según la demanda de terreno). } // la subclase MountainBike tiene // un método public void setHeight(int newValue) { seatHeight = newValue. } public void applyBrake(int decrement) { speed -= decrement. } public void setGear(int newValue) { gear = newValue. int startGear) { gear = startGear. cadence = startCadence. // la clase Bicycle tiene // un constructor public Bicycle(int startCadence. // la subclase MountainBike tiene // un constructor public MountainBike(int startHeight. int startCadence. int startGear) { super(startCadence. int startSpeed. } // la clase Bicycle tiene // cuatro métodos public void setCadence(int newValue) { cadence = newValue. int startSpeed. public int gear. } public void speedUp(int increment) { speed += increment. } } Una declaración de clase para una clase de MountainBike que es una subclase de la Bicycle podría verse así: public class MountainBike extends Bicycle { // la subclase MountainBike tiene // un campo public int seatHeight. public int speed. speed = startSpeed. startGear). Modificadores como public. El nombre de clase. También puede agregar modificadores como público o privado al principio — así que puedes ver que la primera línea de una declaración de clase puede ser bastante complicada. y métodos para implementar el comportamiento de la clase y de sus objetos. si implementa cualquier interface y así sucesivamente. Contiene sólo aquellos componentes de una declaración de clase que se requieren. En general. Los modificadores público y privada. las declaraciones de los campos que proporcionan el estado de la clase y de sus objetos. La declaración de clase anterior es mínima. como el   nombre de su superclase. 2. Por el momento no necesitas preocuparte por estas complicaciones adicionales. con la letra inicial mayuscula por la Convención. class MyClass extends MySuperClass implements YourInterface { // declaraciones de métodos. Por ejemplo. La lección de las interfaces y la herencia le explicarán cómo y por qué utilizaría las palabras clave extends e implements en una declaración de clase. las declaraciones de clase pueden incluir estos componentes: 1. // campos y constructores } significa que MyClass es una subclase de MySuperClass y que implementa la interfaz YourInterface .Declarar Clases Has visto clases definidas de la siguiente manera: class MyClass { // declaraciones de métodos. private y otros que encontrará más adelante. que determinan qué otras clases pueden acceder MyClass. // campos y constructores } Esto es una declaración de clase. se discuten más adelante en esta lección. . en el inicio de la declaración de clase. El cuerpo de la clase (el área entre las llaves) contiene todo el código que se proporciona para el ciclo de vida de los objetos creados de la clase:    constructores para inicializar nuevos objetos. Puede proporcionar más información acerca de la clase. El cuerpo de la clase. public int gear. Las declaraciones de campos se componen de tres componentes. Los campos de Bicycle se denominan cadence. modificador private — el campo es accesible solamente dentro de su propia clase. 5. Una clase puede implementar más de una interfaz. 3. precedido por la palabra clave implements. si es el caso. Modificadores de acceso El primer modificador (extremo izquierdo) utilizado le permite controlar qué otras clases tienen acceso a un campo miembro. Sin embargo. 2. gear y speed y son todos datos de tipo integer (int). El nombre de las clases padres (superclase). Las variables en un método o bloque de código. Declarar las Variables miembro Existen varios tipos de variables:    Las variables miembro en una clase — se denominan campos. Otros modificadores de acceso se discutirán más adelante. en orden: 1. accesibles por cualquier objeto que pueda acceder a la clase. Cero o más modificadores. va precedido por la palabra clave extends. public int speed. En el espíritu de encapsulación. sí todavía necesitamos acceso a estos valores:  puede acceder indirectamente mediante la adición de métodos públicos que obtengan los valores de los campos para nosotros: . Una lista separada por comas de interfaces implementadas por la clase.3. se denominan variables locales. si los hubiere. { }. es común hacer los campos privados. Esto significa que sólo se puede acceder directamente desde la clase Bicycle. Una clase (subclase) puede solamente extender de un padre. El nombre del campo. como public o private. Por el momento. Las variables en las declaraciones de métodos — se denominan parámetros. considere sólo public y private.  La palabra clave public identifica estos campos como miembros públicos. El tipo del campo. La clase Bicycle utiliza las siguientes líneas de código para definir sus campos: public int cadence. 4.   modificador public — el campo es accesible desde todas las clases. rodeado de llaves. int startSpeed. arreglos u objetos. } public void speedUp(int increment) { speed += increment.   Puede utilizar los tipos primitivos como int. private int gear. private int speed. etc. } public int getCadence() { return cadence. } } Tipos Todas las variables deben tener un tipo. speed = startSpeed. } public void setCadence(int newValue) { cadence = newValue. tales como cadenas. ya sean campos. boolean. public Bicycle(int startCadence. Variables — Nomenclatura. excepto que . Nombres de variables Todas las variables. variables locales o parámetros. tenga en cuenta de que las mismas reglas de nomenclatura y convenciones se utilizan en los nombres de métodos y clases. } public int getSpeed() { return speed. int startGear) { gear = startGear. cadence = startCadence. } public void applyBrake(int decrement) { speed -= decrement.public class Bicycle { private int cadence. float. } public void setGear(int newValue) { gear = newValue. siguen las mismas reglas de nomenclatura y convenciones que se cubrieron en la lección de lenguaje básico. } public int getGear() { return gear. En esta lección. puede utilizar los tipos de referencia. 4. El cuerpo del método. Definición: Dos de los componentes de una declaración de método comprenden la firma del método— el nombre del método y los tipos de parámetro. 6. nombre. (). El tipo de retorno: el tipo de dato del valor devuelto por el método. Las excepciones son discutidas en una lección posterior. La lista de parámetros entre paréntesis — una lista delimitada por comas de parámetros de entrada. en orden: 1. La firma del método declarado anteriormente es: calculateAnswer(double. Estos son algunos ejemplos: run . un par de paréntesis () y un cuerpo entre llaves. encerrado entre paréntesis. int numberOfEngines. Modificadores — como public. int. Por Convención. private y otros que aprenderás más adelante. que se discutirá más adelante. las declaraciones de métodos tienen seis componentes. los nombres de métodos deben ser un verbo en minúscula o un nombre de varias palabras que comiencen con un verbo en minúsculas. sustantivos. van aquí. Si no hay parámetros. 5. y la primera (o única) palabra en un nombre de método debe ser un verbo. seguido de adjetivos. o void si el método no devuelve un valor. la primera letra de cada segunda y siguientes palabras debe escribirse con mayúscula. etc. Más generalmente. double grossTons) { // hacer el cálculo aquí } Los únicos elementos necesarios de una declaración de método son     el tipo de retorno del método. double length. 3. precedidos por sus tipos de datos. debe utilizar paréntesis vacíos. El nombre del método — las reglas para nombres de campo se aplican a los nombres de los métodos también. las convenciones de código restringen los nombres de métodos. {}. En los nombres de varias palabras. Los modificadores. Una lista de excepciones. double) Nombrando un método Aunque un nombre de método puede ser cualquier identificador legal. pero la convención es un poco diferente. Definir Métodos Aquí está un ejemplo típico de una declaración de método: public double calculateAnswer(double wingSpan. tipos de retorno y los parámetros serán discutidos más adelante en esta lección. encerrado entre llaves — el código del método. double.  debe escribirse con mayúscula la primera letra de un nombre de clase. incluyendo la declaración de variables locales. 2. Proporcionar constructores para tus clases .. public void draw(String . Esto significa que los métodos dentro de una clase pueden tener el mismo nombre si tienen listas de parámetros diferentes (hay algunos requisitos a esto que serán discutidos en la lección titulada "Interfaces y herencia").. No se puede declarar más de un método con el mismo nombre y el mismo número y tipo de argumentos. usted puede utilizar el mismo nombre para todos los métodos de dibujo pero pase una lista de argumentos diferentes para cada método.. incluso si tienen un tipo de retorno diferente. ya que pueden hacer el código mucho menos legible. .. Supongamos que tiene una clase que puede utilizar la caligrafía para dibujar distintos tipos de datos (cadenas. El compilador no considera el tipo de retorno al diferenciar los métodos. por lo que no puede declarar dos métodos con la misma firma. la clase de dibujo de datos podría declarar cuatro métodos denominados draw. drawFloaty así sucesivamente. En el código de muestra. } } s) { { f) { double f) { Los métodos sobrecargados se diferencian por la cantidad y el tipo de los argumentos que se pasan al método. Sin embargo. public class DataArtist { . enteros y así sucesivamente) y que contiene un método para la elaboración de cada tipo de datos. } public void draw(double . Sobrecarga de métodos El lenguaje de programación Java soporta Métodos de Sobrecarga y Java puede distinguir entre los métodos con diferentes firmas de métodos. un método tiene un nombre único en su clase.runFast getBackground getFinalData compareTo setX isEmpty Típicamente... ya que el compilador no puede distinguirlos.. Es incómodo usar un nombre nuevo para cada método — por ejemplo. En el lenguaje de programación Java.. cada uno de ellos tiene una lista de parámetros diferentes. } public void draw(int i) . drawInteger. un método podría tener el mismo nombre que otros métodos debido a la sobrecarga de método.. } public void draw(int i. draw(String s) y draw(int i) son métodos distintos y únicos porque requieren diferentes tipos de argumentos.. Por lo tanto. drawString. Nota: Los Métodos sobrecargados deben ser usados con moderación. Las declaraciones de los constructores parecen declaraciones de métodos — excepto que utilizan el nombre de la clase y no tienen tipo de retorno. no puede crear directamente objetos MyClass. invoca el constructor sin-argumentos para crear un nuevo objeto Bicycle llamado yourBike. entonces tiene una superclase implícita del Object. Por ejemplo. 8) crea el espacio en la memoria para el objeto e inicializa sus campos. pero debe tener cuidado al hacerlo. 8). 0. Esto se discutirá más adelante. Pasar información a un método o a un Constructor . se llama a un constructor por el operador new: Bicycle myBike = new Bicycle(30. incluyendo a un constructor sin argumentos: public Bicycle() { gear = 1. para cualquier clase sin constructores. la plataforma Java distingue los constructores sobre la base de la cantidad de argumentos en la lista y sus tipos. } Para crear un nuevo objeto Bicycle llamado myBike. } Bicycle yourBike = new Bicycle(). speed = startSpeed. Este constructor predeterminado llamará al constructor sin-argumentos de la superclase. int startSpeed. el compilador se quejará si la superclase no tiene un constructor sin-argumentos por lo que debe comprobar que lo tiene. No puedes escribir dos constructores que tienen el mismo número y tipo de argumentos para la misma clase.Una clase contiene constructores que se invocan para crear objetos desde la clase modelo o plantilla. Nota: Si otra clase no puede llamar al constructor de MyClass. new Bicycle(30. Si tu clase no tiene una superclase explícita. 0. Bicycle tiene un constructor: public Bicycle(int startCadence. speed = 0. en la lección de las interfaces y la herencia. provoca un error en tiempo de compilación. Si lo hace. Ambos constructores se pueden haber declarado en Bicycle porque tienen listas de argumentos diferentes. porque la plataforma no sería capaz de distinguirlos. int startGear) { gear = startGear. cadence = 10. cadence = startCadence. Usted puede utilizar modificadores de acceso en la declaración de un constructor para controlar qué otras clases pueden llamar al constructor. No tiene que proporcionar ningun constructor para la clase. El compilador proporciona automáticamente un constructor por default sinargumentos. Como con los métodos. que tiene un constructor sin-argumentos Usted puede utilizar un constructor de la superclase. podría tener otros. La clase MountainBike al principio de esta lección así lo hizo. Aunque Bicycle solamente tiene un constructor. En esta situación. como doubles. tales como objetos y arreglos. sigues el tipo del último parámetro con puntos suspensivos (tres puntos. Es un atajo para crear una matriz manualmente (del método anterior podría haber utilizado varargs en lugar de una matriz). Por ejemplo. la tasa de interés. y el nombre del parámetro.0. Los parámetros se utilizan en el cuerpo del método y en tiempo de ejecución tomarán los valores de los argumentos que se pasaron dentro. floats.((futureValue * partial1) / denominator). Tipos de parámetros Puede utilizar cualquier tipo de dato para un parámetro de un método o un constructor.pow((1 + interest). Para usar varargs. double partial1 = Math. Nota: Los parámetros se refieren a la lista de variables en una declaración de método. Usas varargs cuando no sabes cuantos de un tipo determinado de argumento se pasarán al método. double answer = (-loanAmt / denominator) . utilice una expresión lambda o un método de Referencia. Entonces puede llamarse al método con cualquier cantidad de ese parámetro. double rate.La declaración de un método o un constructor declara el número y el tipo de los argumentos para el método o constructor. Los tres primeros son números de punto flotante de precisión doble. incluyendo ninguno.). En este ejemplo. y la cuarta es un entero. double futureValue. el método crea un objeto nuevo Polygon y lo Inicializa desde un arreglo de objetos Point (asuma que Point es una clase que representa una coordenada x. y luego un espacio. los argumentos utilizados deben coincidir con los parámetros de la declaración de tipo y orden. la tasa de interés. Esto incluye tipos de datos primitivos.numPeriods).. } Este método tiene cuatro parámetros: el monto del préstamo. la duración del préstamo (el número de períodos) y el valor futuro del préstamo: public double computePayment( double loanAmt. Los argumentos son los valores reales que se pasan cuando se invoca el método. e integers. como viste en el método computePayment y tipos de datos de referencia. double denominator = (1 . el valor futuro y el número de períodos. Cuando se invoca un método.. . Aquí hay un ejemplo de un método que acepta un arreglo como argumento.partial1) / interest. int numPeriods) { double interest = rate / 100. return answer. el siguiente es un método que calcula los pagos mensuales para un préstamo hipotecario. .. Número arbitrario de argumentos Puede utilizar un constructor denominado varargs para pasar un número arbitrario de valores a un método. y): public Polygon polygonFrom(Point[] corners) { // el cuerpo del método va aqui } Nota: Si quieres pasar un método dentro de un método. basado en la cantidad de préstamo. int y) { .. considere la siguiente clase Circle y su método setOrigin : public class Circle { private int x.y) * (corners[1]. Un parámetro puede tener el mismo nombre que uno de los campos de la clase.printf("%s: %d. idnum. phone. Puede llamar al método con una matriz o con una serie de argumentos. name. %s%n". name.length. radius.corners[0]. %s%n". double squareOfSide1. Por ejemplo.x) * (corners[1]. no al campo.public Polygon polygonFrom(Point. debe . El método setOrigin tiene dos parámetros. } } La clase Circle tiene tres campos: x.y).corners[0]. o como esta System.y . Object. cada uno de ellos tiene el mismo nombre como uno de los campos. Para acceder al campo.out. Comúnmente se verá varargs con los métodos de impresión. Este nombre se utiliza en el cuerpo del método para referirse al argumento que se pasa dentro.x) + (corners[1]. lengthOfSide1. corners es tratado como una matriz. por ejemplo. proporcionas un nombre para ese parámetro.. lengthOfSide1 = Math.printf("%s: %d. args) le permite imprimir un número arbitrario de objetos. Puede ser llamado así: System. se dice del parámetro que sombrea al campo. o con todavía un número diferente de argumentos. %s. y no puede ser el nombre de una variable local dentro del método o constructor. y y radius. idnum..corners[0].x . address. dentro del método. email).out.y . Si este es el caso. // más codigo del cuerpo del método que sigue creando y // retornando un polygon que conecta los Points } Puedes ver que. address). squareOfSide1 = (corners[1]. public void setOrigin(int x. El nombre de un parámetro debe ser único en su ámbito de aplicación.corners[0]. este método printf : public PrintStream printf(String format.. corners) { int numberOfSides = corners. El código en el cuerpo del método tratará el parámetro como un arreglo en cualquiera de los casos.x . Así que usar los nombres simples x o y dentro del cuerpo del método hace referencia al parámetro. Sombrear los campos puede dificultar leer su código y convencionalmente se utiliza solo dentro de los constructores y métodos que fijan un campo particular. %s. Cada parámetro del método sombrea el campo que comparte su nombre. No puede ser el mismo que el nombre de otro parámetro para el mismo método o constructor.. Nombres de parámetros Cuando se declara un parámetro a un método o un constructor..sqrt(squareOfSide1). y. tales como objetos. int deltaY) { // código para mover el origen del círculo para x+deltaX. la referencia pasada dentro todavía hace referencia al mismo objeto que antes. 0). Por ejemplo. la salida es: Despues de invocar el passMethod. int deltaX. Aquí está un ejemplo: public class PassPrimitiveByValue { public static void main(String[] args) { int x = 3.println("Despues de invocar el passMethod.getX() + deltaX). también se pasan a los métodos por valor. // invoca el passMethod() con // x como argumento passMethod(x). } } Cuando se ejecuta este programa. } Deja que el método se invoque con estos argumentos: moveCircle(myCircle. Esto será discutido más adelante en esta lección en la sección titulada "Usando la palabra clave this”.setY(circle.utilizar un nombre cualificado. considere un método en una clase arbitraria que mueve objetos Circle: public void moveCircle(Circle circle. como un int o double. se pasan a los métodos por valor. y+deltaY circle. Cuando el método devuelve. Esto significa que cuando el método devuelve. } // cambia el parametro en passMethod() public static void passMethod(int p) { p = 10. x = 3 Pasando argumentos de tipo de datos de referencia Los parámetros de tipo de datos de referencia.out. Sin embargo. 56) . 23. Esto significa que cualquier cambio en los valores de los parámetros existe sólo en el ámbito del método. // imprime x para ver si este // valor ha cambiado System. si tienen el nivel de acceso adecuado.setX(circle. Pasando argumentos de tipo de datos primitivo Los argumentos primitivos. x = " + x). // código para asignar una nueva referencia al círculo circle = new Circle(0. circle. los parámetros se han ido y cualquier cambio en ellos se pierde. los valores de los campos del objeto se pueden cambiar en el método.getY() + deltaY). System. respectivamente.x).println("X Position of rectTwo: " + rectTwo. // muestra la posición de rectTwo System. cuando el método devuelve. Usted necesitará los tres archivos fuente completos para compilar este programa. un programa puede realizar diversas tareas.println("X Position of rectTwo: " + rectTwo. Una vez que un objeto ha completado el trabajo para el cual fue creado. pero. ejecutar una animación. circle inicialmente se refiere a myCircle. // mueve a rectTwo y muestra su nueva posición rectTwo.out.width). Rectangle rectTwo = new Rectangle(50.println("Width of rectOne: " + rectOne. 94).y). altura y área de rectOne System. A través de estas interacciones del objeto.getArea()).out.height). 100. Point originOne = new Point(23. // fija la posición de rectTwo rectTwo.out. debido a que la referencia fue pasada por su valor y no se puede cambiar. como implementar un GUI. 72).move(40.origin = originOne. 100). Aquí está un pequeño programa. 200).out. que crea tres objetos: un objeto Point y dos objetos Rectangle. System.origin.println("Y Position of rectTwo: " + rectTwo.println("Y Position of rectTwo: " + rectTwo. o enviar y recibir información sobre una red. myCircle) por 23 y 56. manipula y muestra información acerca de diversos objetos. sus recursos son reciclados para su uso por otros objetos. public class CreateObjectDemo { public static void main(String[] args) { // Declarar y crear un objeto punto y dos objetos rectángulo. // muestra la anchura. Aquí está la salida: Width of rectOne: 100 .out. interactúan mediante la invocación de métodos. sin embargo. El método cambia las coordenadas x y y del objeto de esas referencias circle (es decir. System.println("Area of rectOne: " + rectOne. Esta reasignación no tiene ninguna permanencia.Dentro del método. llamado CreateObjectDemo.origin. Objetos Un típico programa Java crea muchos objetos. Estos cambios se mantendrán cuando el método devuelve.x). System.out. System. myCircle todavía hace referencia al mismo objeto Circle como antes de que se llamará al método.y).out.origin. que como ya sabes. Rectangle rectOne = new Rectangle(originOne. Entonces circle es asignado a una referencia a un objeto nuevo Circle con x = y = 0.println("Height of rectOne: " + rectOne.origin. } } Este programa crea. el objeto apuntado por circle ha cambiado. Dentro del método. De ellos. 2. Inicialización: el nuevo operador es seguido por una llamada a un constructor. aprenderá cómo escribir código que crea y utiliza los objetos en sus propios programas. 100. 3. Debe asignar un objeto a originOne antes de usarlo en su código. La primera línea crea un objeto de la clase Point. una clase proporciona el plan de acción para los objetos. esta instrucción también reserva la cantidad adecuada de memoria para la variable. tienes que utilizar el operador new. También puede declarar una variable de referencia en su propia línea. Declarar una Variable para hacer referencia a un objeto Previamente. crea un objeto de una clase. aprendió que para declarar una variable. Cada una de estas instrucciones consta de tres partes (explicadas en detalle más abajo): 1. se puede ilustrar como sigue (nombre de la variable. y la segunda y tercera línea crean cada una un objeto de la clase Rectangle. Esto notifica al compilador que usará nombre para referirse a datos cuyo tipo es de un tipo de valor. Rectangle rectOne = new Rectangle(originOne. que inicializa el objeto nuevo. También aprenderás cómo el sistema limpia después un objeto cuando su vida ha terminado.Height of rectOne: 200 Area of rectOne: 20000 X Position of rectTwo: Y Position of rectTwo: X Position of rectTwo: Y Position of rectTwo: 23 94 40 72 Las siguientes tres secciones utilizan el ejemplo anterior para describir el ciclo de vida de un objeto dentro de un programa. Si se declara originOne así. escribe el tipo y el nombre: type name. Simplemente declarar una variable de referencia no crea un objeto. su valor será indeterminado hasta que un objeto es creado y asignado a él. 100). obtendrá un error del compilador. Cada una de las siguientes instrucciones extraídas del programa CreateObjectDemo crea un objeto y lo asigna a una variable: Point originOne = new Point(23. Con una variable primitiva. 94). originOne. además de una referencia apuntando a la nada): . Creación de objetos Como ya sabes. tal como se describe en la sección siguiente. Por ejemplo: Point originOne. que actualmente hace referencia a ningún objeto. 200). Instrucción: el código en negrita son todas las declaraciones de variables que asocian un nombre de variable a un tipo de objeto. Por eso. De lo contrario. Instanciación o creación de instancias: la palabra clave new es un operador de Java que crea el objeto. Una variable en este estado. Rectangle rectTwo = new Rectangle(50. La referencia devuelta por el operador new no tiene que ser asignado a una variable. int b) { x = a. Puedes reconocer un constructor porque su instrucción utiliza el mismo nombre que la clase y no tiene ningún tipo de retorno. //constructor public Point(int a. El nombre del constructor proporciona el nombre de la clase a instanciar. Esta referencia es asignada a una variable del tipo adecuado. Cuando crea un objeto. El operador new devuelve una referencia al objeto creado.Crear instancias de una clase El operador new crea una instancia de una clase por la asignación de memoria para un nuevo objeto y devuelve una referencia de esa memoria. La siguiente instrucción proporciona 23 y 94 como valores para esos argumentos: Point originOne = new Point(23. 94). public int y = 0.height. El operador new también invoca el constructor del objeto. Por ejemplo: int height = new Rectangle(). } } Esta clase contiene un único constructor. int b). 94). El operador new requiere un solo argumento postfijo: una llamada a un constructor. declarado por el código (int a. Nota: La frase "crear instancias de una clase" significa lo mismo que "creando un objeto". como: Point originOne = new Point(23. y = b. El resultado de la ejecución de esta instrucción puede ser ilustrado en la figura siguiente: . creará una "instancia" de una clase. Esta declaración se discutirá en la próxima sección. También puede utilizarse directamente en una expresión. El constructor de la clase Point toma dos argumentos enteros. por lo tanto es el "ejemplar" de una clase. Inicializar un objeto Aquí está el código para la clase Point: public class Point { public int x = 0. deben tener diferentes firmas. que contiene cuatro constructores: public class Rectangle { public int width = 0. public int height = 0. width = w. height = h. int h) { origin = p. } // un método para computar el área de un rectangulo public int getArea() { return width * height. usando ambos tipos primitivos y de referencia. // cuatro constructores public Rectangle() { origin = new Point(0. 0). El compilador de Java distingue los constructores basados en el número y el tipo de los argumentos.Aquí está el código de la clase Rectangle. Cuando el compilador de Java se encuentra con el siguiente código.y = y. Si una clase tiene varios constructores. int h) { origin = new Point(0. origin.x = x. int y) { origin. } public Rectangle(Point p. width = w. height = h. 0). } } Cada constructor permite ofrecer valores iniciales para el origen del rectángulo. } public Rectangle(Point p) { origin = p. public Point origin. } public Rectangle(int w. } // un método para mover el rectangulo public void move(int x. anchura y altura. int w. sabe llamar al constructor de la clase Rectangle que es el que requiere un argumento point seguido de dos argumentos enteros: . Si revisas el código en el constructor. Todas las clases tienen al menos un constructor. . el constructor establece el ancho (width). el compilador rechazará el programa. llamado constructor por default. que proporcionan los valores iniciales para la anchura y altura. así que se llama un constructor sin argumentos: Rectangle rect = new Rectangle().Rectangle rectOne = new Rectangle(originOne. Además. la altura (height) de 200 y 100. 100. Puede necesitar usar el valor de uno de sus campos. Uso de objetos Una vez que haya creado un objeto. Si una clase no declara explícitamente alguno. Referenciando a los campos de un objeto A los campos del objeto se accede por su nombre. cambiar uno de sus campos o llamar a uno de sus métodos para realizar una acción. El constructor de rectángulo utilizado en la instrucción siguiente no toma ningún argumento. Este constructor por default llama al constructor sinargumentos de la clase padre. 200). Debe utilizar un nombre que no sea ambiguo. 100). Ahora hay dos referencias al mismo objeto Point— un objeto puede tener múltiples referencias a ella. como se muestra en la siguiente figura: La siguiente línea de código llama al constructor de Rectangle que requiere dos argumentos enteros. Si los padres no tienen ningún constructor (Object tiene uno). Esto llama al constructor de Rectangle que inicializa origin a originOne. o el constructor de Object si la clase no tiene ningún otro padre. el compilador de Java proporciona automáticamente un constructor sin-argumentos. probablemente quieras usarlo para algo. verá que crea un nuevo objeto point cuyo x y valores y se inicializan con 0: Rectangle rectTwo = new Rectangle(50. height). " + height).). o se puede utilizar cualquier expresión que devuelve una referencia al objeto. System. utilice paréntesis vacíos. El programa utiliza dos de estos nombres para mostrar la width y la height de rectOne: System. podemos agregar una instrucción dentro de la clase Rectangle que imprime la width (ancho) y la height (altura): System.). seguido por un nombre de campo simple. rectOne. seguido por el operador punto (. respectivamente.out.height.out. El código que está fuera de la clase del objeto debe utilizar una referencia de objeto o expresión. Para acceder a un campo.println("Width of rectOne: " + rectOne. como en los ejemplos anteriores. cada objeto rectangle tiene campos llamados origin. Los objetos del mismo tipo tienen su propia copia de los mismos campos de instancia. Si el método no requiere ningún argumento. con un operador punto intermedio (. objectReference. Anexe el nombre simple del método a la referencia del objeto. el programa utiliza código similar para mostrar información sobre rectTwo. El objeto no tiene referencia y sus recursos son libres para ser reciclados por la Máquina Virtual de Java. se refiere al campo del objeto particular. el programa ya no tiene una referencia al rectángulo creado. Llamar los métodos de un objeto También puede utilizar una referencia de objeto para invocar el método de un objeto. como en: objectReference. Intentar utilizar los nombres simples width y height del código en la clase CreateObjectDemo no tiene sentido — esos campos existen solamente dentro de un objeto — y resulta en un error del compilador.out.width).widthy rectOne. Recordemos que el operador new devuelve una referencia a un objeto.origin. Así que se puede utilizar el valor devuelto por new para acceder a los campos de un objeto nuevo: int height = new Rectangle(). debido a que el programa no almacena la referencia en ninguna parte. De este modo. width y height. la clase CreateObjectDemo debe usar los nombres rectOne. En este caso.methodName(argumentList). En esencia. puede utilizar una referencia con nombre a un objeto. Tenga en cuenta que después de que esta instrucción ha sido ejecutada.println("Width and height are: " + width + ".println("Height of rectOne: " + rectOne. width y height. la instrucción determina la altura por defecto de un rectángulo.Usted puede utilizar un nombre simple para un campo dentro de su propia clase. el código de la clase CreateObjectDemo está fuera del código de la clase Rectangle. y height dentro del objeto Rectangle llamado rectOne. Además. Por ejemplo. dentro de paréntesis. width. o: . Cuando usted accede a un campo de instancia a través de una referencia al objeto. Esta instrucción crea un nuevo objeto rectángulo e inmediatamente obtiene su altura.height. width y height son nombres simples. Más tarde. Así que para hacer referencia a los campos de origin. Los dos objetos rectOne y rectTwo en el programa de CreateObjectDemo tienen diferentes campos de origin.fieldName Por ejemplo. proporcione. cualquier argumento al método. objectReference.methodName(); La clase rectángulo tiene dos métodos: getArea() para calcular el área del rectángulo y move() para cambiar el origen del rectángulo. Aquí está el código CreateObjectDemo que invoca estos dos métodos: System.out.println("Area of rectOne: " + rectOne.getArea()); ... rectTwo.move(40, 72); La primera declaración invoca el método getArea() de rectOne y muestra los resultados. La segunda línea mueve rectTwo porque el método move() asigna nuevos valores del objeto origin.x y origin.y. Como con campos de instancia, objectReference debe ser una referencia a un objeto. Puede utilizar un nombre de variable, pero también se puede utilizar cualquier expresión que devuelve una referencia al objeto. El operador new devuelve una referencia al objeto, así que puede usar el valor devuelto de new para invocar métodos de un objeto nuevo: new Rectangle(100, 50).getArea() La expresión new Rectangle(100, 50) devuelve una referencia al objeto que se refiere al objeto Rectangle. Como se muestra, puede utilizar la notación de punto para invocar el método getArea() de new Rectangle para calcular el área del nuevo rectángulo. Algunos métodos, como getArea(), devuelven un valor. Para los métodos que devuelven un valor, puede utilizar la invocación del método en las expresiones. Usted puede asignar el valor devuelto por el método a una variable, usarlo para tomar decisiones o para controlar un bucle. Este código asigna el valor devuelto por el método getArea() a la variable areaOfRectangle: int areaOfRectangle = new Rectangle(100, 50).getArea(); Recuerda, invocar un método en un objeto particular es lo mismo que enviar un mensaje a ese objeto. En este caso, el objeto que getArea() invoca en el rectángulo es devuelto por el constructor. El recolector de basura Algunos lenguajes orientados a objetos requieren que usted haga un seguimiento de todos los objetos que crea y que explícitamente los destruya cuando ya no son necesarios. La Gestión de memoria manual o explícita es tedioso y propenso a errores. La plataforma Java te permite crear tantos objetos como tú quieras (limitado, por supuesto, por lo que pueda manejar tu sistema) y no debes preocuparte por destruirlos. El entorno de ejecución de Java (JRE) elimina objetos cuando determina que ya no se están utilizando. Este proceso se denomina recolección de basura. Un objeto es elegible para la recolección de basura cuando no existen más referencias a ese objeto. Las referencias que se llevan a cabo en una variable generalmente se cayeron cuando la variable sale del ámbito. O, usted puede tirar explícitamente una referencia a un objeto estableciendo la variable en el valor especial null. Recuerde que un programa puede tener múltiples referencias al mismo objeto; todas las referencias a un objeto deben “dejarse caer” antes de que el objeto sea elegible para la recolección de basura. El entorno de ejecución Java tiene un recolector de basura que periódicamente libera la memoria utilizada por los objetos a los que ya no se hace referencia. El recolector de basura hace su trabajo automáticamente cuando determina que es el momento adecuado. Más sobre clases Esta sección cubre más aspectos de las clases que dependen del uso de referencias a objetos y el operador dot que has aprendido en las secciones anteriores sobre los objetos:     Devolver valores desde métodos. La palabra clave this. Clase vs. miembros de instancia. Control de acceso. Devuelve un valor desde un método Un método devuelve al código que lo invoca cuando se    completan todas las instrucciones en el método, alcanza una instrucción return , o lanza o emite una excepción (cubierta más adelante), lo que ocurra primero. Puedes declarar un tipo de retorno de un método en su declaración de método. Dentro del cuerpo del método, utilice la instrucción return para devolver el valor. Cualquier método declarado void no devuelve un valor. No necesita contener una instrucción return, pero puede hacerlo. En tal caso, una instrucción return puede utilizarse para ramificar de un bloque de control de flujo y salir del método, y simplemente se utiliza como este: return; Si usted intenta devolver un valor de un método que es declarado void, obtendrá un error del compilador. Cualquier método que no sea declarado void debe contener una instrucción return con un valor de retorno correspondiente, así: return returnValue; El tipo de dato del valor devuelto debe coincidir con el tipo de retorno declarado del método; No se puede devolver un valor entero de un método declarado para devolver un valor booleano. El método getArea() de la clase Rectangle que se discutió en las secciones sobre objetos devuelve un entero: // un método para calcular el área del rectángulo public int getArea() { return width * height; } Este método devuelve el número entero que la expresión width*height evalúa. El método getArea devuelve un tipo primitivo. Un método también puede devolver un tipo de referencia. Por ejemplo, en un programa para manipular objetos de Bicycle, tenemos un método como este: public Bicycle seeWhosFastest(Bicycle myBike, Bicycle yourBike, Environment env) { Bicycle fastest; // código para calcular qué moto es // más rápida, dado el engranaje de cada bicicleta // y la cadencia y dado el // medio ambiente (terreno y viento) return fastest; } Devolviendo una clase o una interfaz Si esta sección te confunde, saltala y regresa después de haber terminado la lección de interfaces y herencia. Cuando un método utiliza un nombre de clase como su tipo de retorno, tales como whosFastest , la clase del tipo de objeto devuelto debe ser una subclase de, o la clase exacta de, el tipo de valor devuelto. Supongamos que usted tiene una jerarquía de clases en la que ImaginaryNumber es una subclase de java.lang.Number, que a su vez es una subclase del Object, como se ilustra en la figura siguiente. La jerarquía de clases para ImaginaryNumber Ahora, supongamos que tiene un método declarado para devolver un Number: public Number returnANumber() { ... } El método returnANumber puede devolver un ImaginaryNumber pero no un Object. ImaginaryNumber es un Number porque es una subclase del Number. Sin embargo, un Object no es necesariamente un Number — podría ser una String u otro tipo. Se puede reemplazar un método y definirlo para devolver una subclase del método original, así: public ImaginaryNumber returnANumber() { ... } Esta técnica, llamada tipo covariante de retorno, significa que el tipo de valor devuelto puede variar en la misma dirección que la subclase. Nota: También puede utilizar nombres de interfaces como tipos de retorno. En este caso, el objeto devuelto debe implementar la interfaz especificada. x. public int y = 0. 1). } } Cada argumento del constructor sombrea uno de los campos del objeto — dentro del constructor x es una copia local del primer argumento del constructor.y = y. Así. la clase Point fue escrita así public class Point { public int x = 0. //constructor public Point(int x. } public Rectangle(int width. Puede referirse a cualquier miembro del objeto actual desde dentro de un método de instancia o un constructor utilizando this. Aquí tiene otra clase de Rectangle. con una implementación diferente de la de la sección de objetos .Usando la palabra clave this Dentro de un método de instancia o un constructor. 1. //constructor public Point(int a. int y) { this.x = x. public class Rectangle { private int x. Usando this con un Constructor Desde dentro de un constructor. y = b. y. this es una referencia al objeto actual — el objeto cuyo método o constructor se esta llamando. Usando this con un campo La razón más común para el uso de la palabra clave this es porque un campo es sombreado por un parámetro de método o constructor. } } Pero podría haber sido escrito así: public class Point { public int x = 0. public Rectangle() { this(0. el constructor debe utilizar this. public int y = 0. se le llama una invocación explícita del constructor. 0. this. Por ejemplo. . height). Para hacer referencia al campo Point x. int b) { x = a. int height) { this(0. width. 0. private int width. también puede utilizar la palabra clave this para llamar a otro constructor en la misma clase. height. Si una clase no tiene ningún modificador (es por defecto. que es visible solamente dentro de su propio paquete (los paquetes son nombres de grupos de clases relacionadas — usted aprenderá acerca de ellos en una lección posterior. Cada constructor inicializa todas o algunas de las variables miembro del rectángulo. una clase siempre tiene acceso a sus propios miembros. El constructor de dos-argumentos llama al constructor de cuatro-argumentos. por una subclase de la clase en otro paquete. protected o package-private (sin modificador explícito). El modificador protected específica que el miembro sólo puede accederse desde dentro de su propio paquete (como con paquete privado) y. int height) { this.x = x.. en el caso de que la clase sea visible para todas las clases de cualquier parte. Para los miembros.width = width. El modificador private especifica que sólo se puede acceder al miembro de su propia clase. también puede utilizar el modificador public o sin modificadores (paquete privado) así como con clases de nivel superior y con el mismo significado. this. int y. el compilador determina qué constructor llamar. y se conoce como paquete privado). Como puedes ver. Los constructores proporcionan un valor por defecto para cualquier variable miembro cuyo valor inicial no es proporcionado por un argumento. pasando el ancho y alto pero siempre utilizando las coordenadas 0. la invocación de un constructor debe ser la primera línea en el constructor. Controlar el acceso a los miembros de una clase Los modificadores de nivel de acceso determinan si otras clases pueden utilizar un campo particular o invocar un método en particular. int width. Puede declarar una clase con el modificador public.0. Por ejemplo. además. Niveles de acceso Modificador Clase Paquete Subclase Mundo public Y Y Y Y protected Y Y Y N sin modificador Y Y N N private N N N Y La primera columna de datos indica si la clase tiene acceso a los miembros definidos por el nivel de acceso. private. this.0. basado en el número y el tipo de argumentos. hay dos modificadores de acceso adicional: private y protected. } Esta clase contiene un conjunto de constructores.y = y. Si se presenta. this. La siguiente tabla muestra el acceso a los miembros permitidos por cada modificador. Como antes. } . el constructor sin-argumentos crea un Rectangle de 1 x 1 en las coordenadas 0. La segunda . En el nivel de miembro —public.} public Rectangle(int x..) En el nivel de miembro.height = height. Existen dos niveles de control de acceso:   En el nivel superior —public o package-private (sin modificador explícito). como las clases en la plataforma Java. La cuarta columna indica si todas las clases tienen acceso a los miembros. Los niveles de acceso afectan de dos maneras. tienes que decidir qué nivel de acceso deben tener todas las variables miembro y cada método en su clase. Vamos a ver una colección de clases y ver cómo afectan los niveles de acceso a la visibilidad.   Use el nivel de acceso más restrictivo que tenga sentido para un determinado miembro. En segundo lugar. La tercera columna indica si las subclases de la clase declarada fuera de este paquete tienen acceso al miembro. Evite los campos public excepto para las constantes. Visibilidad Modificador Alfa Beta Alphasub Gamma public Y Y Y Y protected Y Y Y N sin modificadores Y Y N N private N N N Y Tips para escoger un nivel de acceso: Si otros programadores utilizan su clase. Clases y paquetes del ejemplo para ilustrar los niveles de acceso La siguiente tabla muestra donde los miembros de la clase Alfa son accesibles para cada uno de los modificadores de acceso que se pueden aplicar a ellos. cuando utilizas las clases que vienen de otra fuente. Esto puede ayudar a ilustrar algunos puntos de forma concisa. pero no se recomienda para el código de producción. cuando escribes una clase. Entendiendo a los miembros de la clase En esta sección. En primer lugar. (Muchos de los ejemplos en el tutorial usan los campos públicos.) Los campos públicos tienden a vincularte a una implementación en particular y limitar la flexibilidad de modificar su código. los niveles de acceso determinan que miembros de las clases pueden usar sus propias clases. discutimos el uso de la palabra clave static para crear campos y métodos que pertenecen a la clase. Los niveles de acceso pueden ayudarle a hacerlo. en lugar de a una instancia de la clase.columna indica si las clases en el mismo paquete que la clase (independientemente de su paternidad) tienen acceso al miembro. usted quiere asegurarse de que no pueden ocurrir errores por el uso indebido. Use private a menos que tenga una buena razón para no hacerlo. La siguiente figura muestra las cuatro clases en este ejemplo y cómo se relacionan. . numberOfBicycles Pero esto es desalentado porque no deja en claro que son variables de clase. Puede utilizar el constructor de Bicycle para establecer la variable de instancia de id e incrementar la variable de clase numberOfBicycles : public class Bicycle { private private private private int int int int cadence. private int gear. en lugar de cualquier objeto. pero también se pueden manipular variables de clase sin crear una instancia de la clase. id. sino a la clase como un todo. como en Bicycle. Están asociados con la clase. speed. Los Campos que tienen el modificador static en su declaración se denominan campos estáticos o variables de clase. almacenadas en localizaciones de memoria diferentes.numberOfBicycles Esto pone de manifiesto que son variables de clase. Esto se logra con el modificador static. Este número de identificación es único para cada objeto y por lo tanto es una variable de instancia. . numberOfBicycles. Cualquier objeto puede cambiar el valor de una variable de clase. Para ello es necesario una variable de clase. Cada instancia de la clase comparte una variable de clase. quieres tener variables que son comunes a todos los objetos. A veces.. cada uno tiene sus propias copias diferentes de las variables de instancia. que se encuentra en una posición fija en la memoria. . En el caso de la clase de Bicycle. // añadir una variable de instancia para el ID del objeto private int id. gear. empezando por 1 para el primer objeto. supongamos que desea crear un número de objetos de Bicycle y asignar a cada uno un número de serie. Al mismo tiempo. private int speed. necesitas un campo para hacer un seguimiento de cuántos objetos de Bicycle han sido creados para que sepas qué ID se le asignará al siguiente. Cada objeto Bicycle tiene sus propios valores de estas variables. Un campo no está relacionado a ningún objeto individual.. como sigue: public class Bicycle { private int cadence. // añadir una variable de clase para el // número de objetos de Bicycle instanciados private static int numberOfBicycles = 0. gear y speed. Por ejemplo. las variables de instancia son cadence.Variables de clase Cuando se crea una serie de objetos desde la misma clase plantilla. } Las variables de clase están referenciadas por el nombre de la clase misma. Nota: También puede hacer referencia a campos estáticos con una referencia a un objeto como myBike. methodName(args) Nota: También puede hacer referencia a métodos estáticos con referencia a un objeto como instanceName. Constantes El modificador static. int startSpeed. } No todas las combinaciones de métodos y variables de instancia y clase están permitidas:     Métodos de instancia pueden acceder a las variables de instancia y métodos de instancia directamente. deben ser invocados con el nombre de clase. int startGear){ gear = startGear. El modificador final indica que no puede cambiar el valor de este campo. Los métodos de clase no pueden acceder a las variables de instancia o métodos de instancia directamente. . public Bicycle(int startCadence. speed = startSpeed. Métodos de instancia pueden acceder a variables de clase y métodos de la clase directamente. Métodos de la clase pueden acceder a variables de clase y métodos de la clase directamente.private static int numberOfBicycles = 0. } Métodos de la clase El lenguaje de programación Java soporta métodos estáticos. } .methodName(args) Pero esto es desalentado porque no deja en claro que son métodos de la clase. como en ClassName. -deben utilizar una referencia al objeto. también se utiliza para definir constantes. en combinación con el modificador final. Por ejemplo. } // nuevo método para devolver la variable de instancia ID public int getID() { return id. así como con las variables estáticas.. que tienen el modificador static en sus declaraciones. Un uso común de métodos estáticos es para acceder a los campos estáticos.. sin la necesidad de crear una instancia de la clase. Además. nosotros podríamos añadir un método estático a la clase de Bicycle para acceder al campo estático de numberOfBicycles : public static int getNumberOfBicycles() { return numberOfBicycles. los métodos de clase no pueden utilizar la palabra clave this ya que no hay ninguna instancia para this y referirse a. cadence = startCadence. // número de incrementos de Bicicletas // y asignar el número de identificación id = ++numberOfBicycles. Los métodos estáticos. int startSpeed. speed = startSpeed. id = ++numberOfBicycles. Nota: Si un tipo primitivo o una cadena se define como una constante y el valor es conocido en tiempo de compilación. } .141592653589793. } public int getCadence(){ return cadence. cuyo valor es una aproximación de pi (la proporción de la circunferencia de un círculo y su diámetro): static final double PI = 3. Por Convención. la clase Bicycle es ahora: public class Bicycle { private int cadence. la siguiente declaración de variable define una constante llamada PI. cadence = startCadence. si se está legislado que pi en realidad debería ser 3. } public int getID() { return id. tendrá que volver a compilar las clases que utilizan esta constante para obtener el valor actual. public Bicycle(int startCadence. las palabras están separadas por un guión bajo (_).Por ejemplo.975). los nombres de valores constantes se escriben en mayúsculas. private int speed. private int id. } public void setCadence(int newValue){ cadence = newValue. Las constantes definidas en esta forma no pueden ser reasignadas. Esto se llama una constante de tiempo de compilación. int startGear){ gear = startGear. private static int numberOfBicycles = 0. private int gear. } public static int getNumberOfBicycles() { return numberOfBicycles. Si cambia el valor de la constante en el mundo exterior (por ejemplo. y es un error en tiempo de compilación si su programa intenta hacerlo. Si el nombre está compuesto por más de una palabra. el compilador sustituye el nombre de la constante en todas partes en el código con su valor. La clase de Bicycle Después de todas las modificaciones realizadas en esta sección. Aquí está un ejemplo: static { // cualquier código que se necesita para la inicialización va aquí } . // inicializar a false private boolean full = false. Bloques de inicialización estática Un bloque de inicialización estática es un bloque normal de código encerrado entre llaves. } Esto funciona bien cuando el valor de inicialización esta disponible y la inicialización se puede poner en una sola línea. } public void applyBrake(int decrement){ speed -= decrement. { } y precedido por la palabra clave static. } public int getSpeed(){ return speed. } } Inicializar campos Como has visto. Si la inicialización requiere un poco de lógica (por ejemplo. } public void speedUp(int increment){ speed += increment. la asignación simple es insuficiente. a menudo se puede proporcionar un valor inicial para un campo en su declaración: public class BedAndBreakfast { // inicializar a 10 public static int capacity = 10. Nota: No es necesario declarar campos al principio de la definición de clase.public int getGear(){ return gear. el lenguaje de programación Java incluye bloques de inicialización estática. manejo de errores o un bucle for para llenar una matriz compleja). } public void setGear(int newValue){ gear = newValue. esta forma de inicialización tiene limitaciones debido a su simplicidad. Se puede inicializar las variables de instancia en constructores. aunque esta es la práctica más común. donde el manejo de errores o de otra lógica puede ser utilizado. Sólo es necesario que sean declarados e inicializados antes de que se utilicen. Sin embargo. Para proporcionar la misma capacidad para variables de clase. Una clase utiliza campos que contienen información sobre el estado y los métodos para implementar el comportamiento. Esto se discute en la lección sobre interfaces y herencia. El método es final porque llamar a métodos no-final durante la inicialización de la instancia puede causar problemas. El nombre de la clase puede estar precedido por modificadores. El cuerpo de clase contiene campos. Por lo tanto. Existen dos alternativas al uso de un constructor para inicializar las variables de instancia: bloques inicializadores y métodos finales. Hay una alternativa a los bloques estáticos. Los constructores que inicializan una . pero sin la palabra clave static: { // cualquier código que se necesita para la inicialización va aquí } El compilador de Java copia bloques de inicialización en cada constructor. y pueden aparecer en cualquier parte del cuerpo de la clase. protected final varType initializeInstanceVariable() { // la inicialización del código va aqui } } Esto es especialmente útil si las subclases querrían volver a utilizar el método de inicialización. Los bloques inicializadores para variables de instancia se parecen a los bloques inicializadores estáticos. Inicializar miembros de instancia Normalmente.Una clase puede tener cualquier número de bloques de inicialización estática. métodos y constructores de la clase. El sistema runtime garantiza que la inicialización estática de los bloques sean llamados en el orden en que aparecen en el código fuente. se puede escribir un método estático privado: class Whatever { public static varType myVar = initializeClassVariable(). Aquí está un ejemplo del uso de un método final para inicializar una variable de instancia: class Whatever { private varType myVar = initializeInstanceVariable(). pones código para inicializar una variable de instancia en un constructor. private static varType initializeClassVariable() { // la inicialización del código va aqui } } La ventaja de los métodos estáticos privados es que pueden ser reutilizados más tarde si tienes que reiniciar la variable de clase. Un método final no puede invalidarse en una subclase. este enfoque puede utilizarse para compartir un bloque de código entre varios constructores. Resumen de crear y utilizar clases y objetos Una declaración de clase da nombre a la clase y encierra el cuerpo de la clase entre llaves. methodName(argumentList) o: objectReference.y). } a. a las cuales debe accederse a través de una referencia a la instancia.methodName() El recolector de basura limpia automáticamente los objetos no utilizados. b. así como una referencia a la instancia. Un miembro que no está declarado como static implícitamente es un miembro de instancia. Considere la siguiente clase: public class IdentifyMyParts { public static int x = 7. a. Puede asignar la referencia a una variable o usarlo directamente.y = 6. Se crea un objeto de una clase utilizando el operador new y un constructor. Especifica una variable de clase o un método de clase mediante el uso de la palabra clave static en la declaración del miembro. El nombre de una variable de instancia se ve así: objectReference. IdentifyMyParts b = new IdentifyMyParts().y = " + a. a.x = 1. c. System.variableName El nombre completo de un método se ve así: objectReference. Las instancias de una clase obtienen su propia copia de cada variable de instancia. Las variables de clase son compartidas por todas las instancias de una clase y pueden accederse mediante el nombre de clase. . Preguntas y ejercicios: clases Preguntas 1. El nuevo operador devuelve una referencia al objeto que fue creado.y = 5. public int y = 3. Las variables y métodos de instancia que son accesibles al código fuera de la clase que se declaran pueden ser referidos mediante el uso de un nombre cualificado. Usted puede eliminar explícitamente una referencia estableciendo la variable que contiene la referencia a null. ¿Cuáles son las variables de clase? ¿Cuáles son las variables de instancia? ¿Cuál es la salida del siguiente código: IdentifyMyParts a = new IdentifyMyParts().x = 2. Controlas el acceso a clases y miembros de la misma manera: mediante el uso de un modificador de acceso como el public en su declaración.println("a. b.nueva instancia de una clase utilizan el nombre de la clase y lucen como métodos sin un tipo de retorno. Un objeto no es utilizado si el programa no mantiene más referencias a él.out. b. System.out.println("b.y = " + b.y); System.out.println("a.x = " + a.x); System.out.println("b.x = " + b.x); System.out.println("IdentifyMyParts.x = " + IdentifyMyParts.x); Ejercicios 1. Escribir una clase cuyas instancias representan una sola carta de una baraja de cartas. Jugar a las cartas tienen dos características distintivas: rango y palo. Asegúrese de mantener su solución ya que se le pedirá reescribirla en Enum Types. Sugerencia: Puede utilizar la instrucción assert para comprobar sus asignaciones. Escribe: assert (boolean expression to test); Si la expresión booleana es false, obtendrá un mensaje de error. Por ejemplo, assert toString(ACE) == "Ace"; debe devolver true, así que no habrá ningún mensaje de error. 2. 3. Escribir una clase cuyas instancias representan una baraja completa de cartas. También debe mantener esta solución. Escriba un pequeño programa para poner a prueba tus clases baraja y carta. El programa puede ser tan simple como crear una baraja de cartas y que muestre sus cartas. Preguntas y ejercicios: objetos Preguntas 1. ¿Qué pasa con el siguiente programa? public class SomethingIsWrong { public static void main(String[] args) { Rectangle myRect; myRect.width = 40; myRect.height = 50; System.out.println("myRect's area is " + myRect.area()); } } 2. El código siguiente crea una matriz y un objeto string. ¿Cuántas referencias a esos objetos existen después de que el código se ejecuta? ¿Cualquier objeto es elegible para el recolector de basura? ... String[] students = new String[10]; String studentName = "Peter Parker"; students[0] = studentName; studentName = null; ... 3. ¿Cómo destruye un programa un objeto que crea? Ejercicios 1. 2. Arregle el programa llamado SomethingIsWrong que se muestra en la pregunta 1. Dada la siguiente clase, llamada NumberHolder, escriba algo de código que cree una instancia de la clase, inicialice sus dos variables miembro, y muestre el valor de cada variable miembro. public class NumberHolder { public int anInt; public float aFloat; } Clases anidadas El lenguaje de programación Java permite definir una clase dentro de otra clase. Dicha clase se llama una clase anidada (nested class) y se muestra aquí: class OuterClass { ... class NestedClass { ... } } Terminología: Las clases anidadas se dividen en dos categorías: estática y no estática. Las clases anidadas que se declaran static se denominan clases anidadas estáticas. Clases anidadas no estáticas se denominan clases internas (inner classes). class OuterClass { ... static class StaticNestedClass { ... } class InnerClass { ... } } Una clase anidada es un miembro de la clase a la que pertenece o que la envuelve. Las clases anidadas no estáticas (clases internas) tienen acceso a otros miembros de la clase a la que pertenecen, aunque sean declaradas privadas. Las clases anidadas estáticas no tienen acceso a otros miembros de la clase a la que pertenecen. Como miembro de la OuterClass, una clase anidada puede declararse private, public, protected o package private. (Recordemos que las clases externas sólo pueden ser declaradas public o package private.) ¿Por qué utilizar clases anidadas? Razones convincentes para utilizar clases anidadas incluyen las siguientes:  Es una forma de agrupar lógicamente las clases que se utilizan solamente en un solo lugar: Si una clase es útil sólo a otra clase, entonces es lógico incrustarla en esa clase y mantener las dos juntas. La anidación de tales "Clases ayudantes" hace su paquete más ágil.   Aumenta la encapsulación: considere dos clases de nivel superior, A y B, donde B necesita acceso a los miembros de A que en caso contrario se declararía private. Ocultando la clase B dentro de los miembros de la clase A, A puede ser declarada private y B puede acceder a ellos. Además, la propia B se puede esconder del mundo exterior. Puede generar código más legible y fácil de mantener: Anidar clases pequeñas dentro de clases de nivel superior coloca el código más cerca de donde se utiliza. Clases anidadas estáticas Al igual que con los métodos de clase y variables, una clase anidada estática se asocia con su clase externa. Y al igual que los métodos estáticos de clase, una clase anidada estática no puede referirse directamente a las variables de instancia o métodos definidos en su clase envolvente o a la que pertenece: puede usarlos sólo a través de una referencia de objeto. Nota: Una clase anidada estática interactúa con los miembros de la instancia de la clase externa (y otras clases) justo igual que con cualquier otra clase de nivel superior. En efecto, una clase anidada estática su comportamiento es como una clase de nivel superior que se ha anidado en otra clase de nivel superior para conveniencia del empaquetado. Las clases anidadas estáticas son accedidas usando el nombre de clase a la que pertencece: OuterClass.StaticNestedClass Por ejemplo, para crear un objeto de la clase anidada estática, use esta sintaxis: OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass(); Clases internas Como con métodos y variables de instancia, una clase interna se asocia con una instancia de la clase a la que pertenece y tiene acceso directo a los campos y métodos del objeto. También, debido a que una clase interna esta asociada a una instancia, no se puede definir a cualquier miembro estático por sí mismo. Los objetos que son instancias de una clase interna existen dentro de una instancia de la clase externa. Considere las siguientes clases: class OuterClass { ... class InnerClass { ... } } Una instancia de InnerClass puede existir solamente dentro de una instancia de OuterClass y tiene acceso directo a los campos y métodos de su instancia envolvente. Para crear una instancia de una clase interna, primero debe instanciar la clase externa. Luego, crea el objeto interno dentro del objeto externo con esta sintaxis: OuterClass.InnerClass innerObject = outerObject.new InnerClass(); x = " + this.this. utilice la palabra clave this para representar el ámbito al que pertenece: System.println("ShadowTest.println("this. En consecuencia.out.FirstLevel fl = st. ShadowTest. se crea un array.. Para hacer referencia a la variable miembro de la clase interna FirstLevel.x = " + ShadowTest.this. ShadowTest. cuando se utiliza la variable x en el método methodInFirstLevel. El ejemplo siguiente. Se llama a las variables miembro encerradas en ámbitos mayores por el nombre de clase a la que pertenecen. .out.out. la variable miembro de la clase interna FirstLevel y el parámetro en el método methodInFirstLevel.x). } } public static void main(String.println("x = " + x). En el ejemplo siguiente.x = 1 ShadowTest. la siguiente declaración accede a la variable miembro de la clase ShadowTest desde el método methodInFirstLevel: System. class FirstLevel { public int x = 1.x).this. Usted no puede hacer referencia a una declaración sombreada solo por su nombre.methodInFirstLevel(23). System. Sombreado Si una declaración de un tipo (por ejemplo.x). una clase interna o una definición de método) tiene el mismo nombre que otra declaración en el ámbito al que pertenece. args) { ShadowTest st = new ShadowTest().x = " + this.out.this. fl.out.this. Por ejemplo. una variable de miembro o un nombre de parámetro) en un ámbito determinado (por ejemplo. entonces la declaración sombrea la declaración del ámbito envolvente. System.Hay dos tipos especiales de clases internas: clases locales y anónimas.println("ShadowTest. lo demuestra: public class ShadowTest { public int x = 0.x = " + ShadowTest. llenado con valores enteros y luego da salida a los valores de los índices incluidos en la matriz en orden ascendente.new FirstLevel().println("this. } } La salida de este ejemplo es el siguiente: x = 23 this. considere primero una matriz.x).. void methodInFirstLevel(int x) { System. Ejemplo de la clase interna Para ver una clase interna en uso. se refiere al parámetro del método. La variable x definido como un parámetro del método methodInFirstLevel sombrea la variable de la clase interna FirstLevel.x = 0 Este ejemplo define tres variables denominadas x: la variable miembro de la clase ShadowTest. print(iterator. private int[] arrayOfInts = new int[SIZE]. La clase interna EvenIterator. que se extiende de la interfaz de Iterator< Integer>. } public Integer next() { // graba un valor de un indice incluido en el arreglo. 2. Un método main que crea una instancia de un objeto DataStructure (ds). public DataStructure() { // llena la matriz con valores enteros ascendentes for (int i = 0.println().out.next() + " "). i++) { arrayOfInts[i] = i.out. luego invoca al método printEven para imprimir los elementos del arreglo arrayOfInts con los valores de índice incluidos.util. .Iterator<Integer> { } // la clase interna implementa la interfaz DataStructureIterator. } System. 3 y así sucesivamente) y un método que imprime los elementos del arreglo que tienen un valor de índice incluido. } } public void printEven() { // imprime los valores de los indices incluidos en el arreglo DataStructureIterator iterator = this.java que sigue consiste en:  La clase externa DataStructure. que incluye un constructor para crear una instancia de DataStructure que contiene un arreglo lleno de valores enteros consecutivos (0.En el ejemplo de DataStructure. que implementa la interfaz DataStructureIterator. // que se extiende de la interfaz Iterator<Integer> private class EvenIterator implements DataStructureIterator { // inicia pasando a través de la matriz desde el principio private int nextIndex = 0. i < SIZE.hasNext()) { System. 1. while (iterator. Los Iteradores se utilizan para pasar a través de una estructura de datos y suelen tener métodos de prueba para el último elemento.   public class DataStructure { // Crea un arreglo private final static int SIZE = 15. recuperan el elemento actual y pasan al siguiente elemento. public boolean hasNext() { // Comprueba si el elemento actual es el último de la serie return (nextIndex <= SIZE .1). } interface DataStructureIterator extends java.new EvenIterator(). ds. Se puede declarar una clase interna dentro del cuerpo de un método. Puede utilizar clases internas para implementar clases auxiliares como se muestra en este ejemplo. También puede declarar una clase interna dentro del cuerpo de un método sin nombrar la clase. debes saber cómo utilizar clases internas. porque el mecanismo de control de eventos hace uso extensivo de ellos. Esta sección abarca los siguientes temas:    Declarar clases locales Acceso a miembros de una clase envolvente o Sombreado y clases locales Las clases locales son similares a las clases internas Declarar clases locales . } } public static void main(String s[]) { // llene el arreglo con los valores enteros e imprime solo // los valores de los indices incluidos DataStructure ds = new DataStructure(). } } La salida es: 0 2 4 6 8 10 12 14 Tenga en cuenta que la clase EvenIterator se refiere directamente a la variable de instancia arrayOfInts del objeto DataStructure . Normalmente encontrará clases locales definidas en el cuerpo de un método. public y protected para restringir el acceso a las clases internas.Integer retValue = Integer. // obten el siguiente elemento incluido nextIndex += 2.valueOf(arrayOfInts[nextIndex]). que es un grupo de cero o más instrucciones entre llaves. puedes usar los especificadores de acceso private. Clases locales Las Clases locales son definidos en un bloque. Estas clases son conocidas como clases de anónimas. al igual que las usarias para restringir el acceso a otros miembros de clase. Clases locales y anónimas Hay dos tipos adicionales de clases internas. return retValue. Modificadores Se puede utilizar los mismos modificadores para las clases internas que utilizas para otros miembros de la clase externa. Por ejemplo.printEven(). Estas clases son conocidas como clases locales. Para manejar los eventos de la interfaz de usuario. println("First number is " + myNumber1. else System.out. un bucle for o una condición if. } . // Valid in JDK 8 and later: // int numberLength = 10. // Valid in JDK 8 and later: // myNumber1. } public String getNumber() { return formattedPhoneNumber. // } } PhoneNumber myNumber1 = new PhoneNumber(phoneNumber1). if (myNumber1. if (currentNumber. valida dos números de teléfono. else System. public static void validatePhoneNumber( String phoneNumber1.println("Second number is invalid"). Define la clase local PhoneNumber en el método validatePhoneNumber: public class LocalClassExample { static String regularExpression = "[^0-9]".out.out. ""). PhoneNumber myNumber2 = new PhoneNumber(phoneNumber2).getNumber() == null) System.length() == numberLength) formattedPhoneNumber = currentNumber. El ejemplo siguiente.out.println("Original numbers are " + phoneNumber1 + // " and " + phoneNumber2).println("Second number is " + myNumber2.out. String phoneNumber2) { final int numberLength = 10. LocalClassExample. Por ejemplo.println("First number is invalid").replaceAll( regularExpression. String currentNumber = phoneNumber. declaraciones y los bloques para obtener más información).Puede definir una clase local dentro de cualquier bloque (véase expresiones.getNumber()). puede definir una clase local en un cuerpo de método.getNumber() == null) System.getNumber()). else formattedPhoneNumber = null. } // Valid in JDK 8 and later: // public void printOriginalNumbers() { // System. PhoneNumber(String phoneNumber){ // numberLength = 7.printOriginalNumbers(). class PhoneNumber { String formattedPhoneNumber = null. if (myNumber2. numberLength es una variable capturado. el constructor PhoneNumber accede al miembro LocalClassExample. una clase local tiene acceso a las variables locales.length() == numberLength) formattedPhoneNumber = currentNumber. supongamos que la variable numberLength no está declarado el final. si se declara la clase local en un método. y agrega la instrucción de asignación resaltada en el constructor de PhoneNumber : PhoneNumber(String phoneNumber) { numberLength = 7.out. } El método printOriginalNumbers obtiene acceso a los parámetros phoneNumber1 y phoneNumber2 del método validatePhoneNumber. Cuando una clase local tiene acceso a una variable local o un parámetro del bloque envolvente. Además. Por ejemplo. Como resultado. una clase local puede acceder a las variables locales y parámetros de la envolvente bloque que son definitivos o efectivamente final. String currentNumber = phoneNumber. Por ejemplo. if (currentNumber. el compilador de Java genera un mensaje de error similar a "las variables locales que se hace referencia de una clase interna deben ser final o efectivamente final" donde la clase interna PhoneNumber intenta acceder a la variable numberLength : if (currentNumber. Sin embargo.replaceAll( regularExpression. una clase local sólo puede acceder a variables locales declaradas finales.public static void main(String.regularExpression. args) { validatePhoneNumber("123-456-7890". Por ejemplo. } } En el ejemplo se valida un número de teléfono quitando todos los caracteres del número de teléfono excepto los dígitos 0 a 9. En el ejemplo anterior. Este ejemplo imprime lo siguiente: First number is 1234567890 Second number is invalid Acceso a miembros de una clase envolvente Una clase local tiene acceso a los miembros de su clase envolvente. puede definir el siguiente método en la clase de PhoneNumber local: public void printOriginalNumbers() { System.. a partir de Java SE 8. Sin embargo. ""). } Debido a esta instrucción de asignación. Una variable o parámetro cuyo valor no ha cambiado después de que se inicialice es efectivamente final.length() == numberLength) A partir de Java SE 8.. else formattedPhoneNumber = null. se pueden acceder a los parámetros del método. Después. . comprueba si el número de teléfono contiene exactamente diez dígitos (la longitud de un número de teléfono en América del norte).println("Original numbers are " + phoneNumber1 + " and " + phoneNumber2). capta esa variable o parámetro. la variable numberLength ya no es con eficacia final. el constructor PhoneNumber puede acceder a la variable local numberLength porque se declara final. "456-7890"). out. una variable) en una clase local sombra declaraciones en el ámbito envolvente que tengan el mismo nombre. como la clase PhoneNumber.out. el siguiente fragmento de código no compila porque la interfaz HelloThere se define dentro del cuerpo del método greetInEnglish: public void greetInEnglish() { interface HelloThere { public void greet(). El siguiente fragmento de código compila porque el miembro estático EnglishGoodbye.greet(). Clases locales de métodos estáticos. no pueden contener más clases de declaraciones estáticas. } } HelloThere myGreeting = new EnglishHelloThere().println("Hello " + name). . } Una clase local puede tener miembros estáticos que son variables constantes. Ver Miembros de la clase de comprensión para obtener más información). } class EnglishHelloThere implements HelloThere { public void greet() { System. Clases locales son no estático porque tienen acceso a los miembros de la instancia del bloque envolvente.sayGoodbye se declara static. El siguiente fragmento de código no compila porque el método EnglishGoodbye. Una expresión constante de tiempo de compilación es normalmente una cadena o una expresión aritmética que puede evaluarse en tiempo de compilación. Para obtener más información vea la sombra . que se define en el método estático validatePhoneNumber. Por ejemplo. myGreeting.farewell es una variable constante: public void sayGoodbyeInEnglish() { class EnglishGoodbye { public static final String farewell = "Bye bye".sayGoodbye(). En consecuencia.Clases de sombreado y locales Las declaraciones de un tipo (por ejemplo. El compilador genera un error similar al "modificador 'static' sólo está permitido en la declaración de variable constante" cuando se encuentra con esta definición de método: public void sayGoodbyeInEnglish() { class EnglishGoodbye { public static void sayGoodbye() { System. No puede declarar una interfaz dentro de un bloque. Las clases locales son similares a las clases internas Clases locales son similares a las clases internas porque no pueden definir ni declarar a cualquier miembros estáticos. entonces el compilador de Java genera un error similar a "no estático variable regularExpression no pueden ser referenciados desde un contexto estático". sólo pueden hacer referencia a los miembros estáticos de la clase envolvente. las interfaces son inherentemente estáticas.println(farewell). si no se define la variable miembro regularExpression como estático. } } EnglishGoodbye. public void sayGoodbye() { System. } No puede declarar inicializadores estáticos o interfaces de miembro de una clase local.println("Bye bye"). (Una variable constante es una variable de tipo primitivo o tipo String que se declara final e inicializado con una expresión constante de tiempo de compilación. Por ejemplo.out. lo que significa que la clase se define en otra expresión. } }.sayGoodbye(). HelloWorld frenchGreeting = new HelloWorld() { String name = "tout le monde". public void greet() { greetSomeone("tout le monde"). } public void greetSomeone(String someone) { name = someone. System. } Clases de anónimas Anónimas clases permiten hacer el código más conciso. System. Le permiten declarar y crear una instancia de una clase al mismo tiempo.} } EnglishGoodbye myEnglishGoodbye = new EnglishGoodbye(). } public void sayHello() { class EnglishGreeting implements HelloWorld { String name = "world". } public void greetSomeone(String someone) { name = someone. HelloWorld spanishGreeting = new HelloWorld() { . Esta sección abarca los siguientes temas:     Declarar clases anónimas Sintaxis de clases anónimas Acceder a las Variables locales del ámbito envolvente y declarando y acceder a los miembros de la clase anónima Ejemplos de clases de anónimos Declarar clases anónimas Mientras que las clases locales son declaraciones de clase. public void greet() { greetSomeone("world").out. las clases anónimas son expresiones.println("Hello " + name). HelloWorldAnonymousClasses. utiliza las clases anónimas en las declaraciones de inicialización de las variables locales frenchGreeting y spanishGreeting. Usarlas. si es necesario utilizar una clase local solamente una vez.out. } } HelloWorld englishGreeting = new EnglishGreeting().println("Salut " + name). pero utiliza una clase local para la inicialización de la variable englishGreeting: public class HelloWorldAnonymousClasses { interface HelloWorld { public void greet(). public void greetSomeone(String someone). Son como las clases locales excepto que no tienen un nombre. myEnglishGoodbye. El ejemplo siguiente. La expresión clase anónima consiste en lo siguiente:     El new operador El nombre de una interfaz para implementar o una clase para extender. " + name). Nota: cuando se implementa una interfaz. La sintaxis de la expresión de una clase anónima es como la invocación de un constructor. englishGreeting...println("Hola.greet(). así que utiliza un par de paréntesis. } public void greetSomeone(String someone) { name = someone. que es un órgano de la declaración de clase. como en este ejemplo vacío. } public static void main(String. Un cuerpo.println("Salut " + name).greet().sayHello().out. Más concretamente. la clase anónima está implementando la interfaz HelloWorld. En este ejemplo. System. } }. no hay ningún constructor. Porque la definición de una clase anónima es una expresión. en el cuerpo. args) { HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses(). } } Sintaxis de clases anónimas Como se mencionó anteriormente. declaraciones de métodos están permitidas pero no son declaraciones. System. public void greet() { greetSomeone("tout le monde"). myApp. spanishGreeting. (Esto explica por qué hay un punto y coma después de la abrazadera de cierre. la expresión de la clase anónima es parte de la declaración que crea una instancia del objeto frenchGreeting . Considere la instanciación del objeto frenchGreeting : HelloWorld frenchGreeting = new HelloWorld() { String name = "tout le monde". } }.out. } public void greetSomeone(String someone) { name = someone. En este ejemplo.greetSomeone("Fred"). una clase anónima es una expresión. debe ser parte de una declaración. sólo como una expresión de creación de instancia de clase normal. public void greet() { greetSomeone("mundo"). frenchGreeting.String name = "mundo". Paréntesis que contienen los argumentos de un constructor.) Acceder a las Variables locales del ámbito envolvente y declarando y acceder a los miembros de la clase anónima . excepto que no hay una definición de clase contenida en un bloque de código. Scene. . Considere el ejemplo de JavaFX HelloWorld.scene.Como local las clases. javafx. La expresión clase anónima se destaca: import import import import import import javafx. JavaFX estilo de Getting Started with JavaFX).EventHandler. Ejemplos de clases de anónimos Anónimas clases a menudo se utilizan en aplicaciones de interfaz gráfica de usuario.println("Hello World!").Button. javafx.setText("Say 'Hello World'").control. Para obtener más información vea la sombra . } @Override public void start(Stage primaryStage) { primaryStage. Este ejemplo crea un marco que contiene un botón de decir ' Hola mundo ' .stage. no puede declarar constructores en una clase anónima.scene. } }). btn.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { System. Como una clase anidada. Una clase anónima puede tener miembros estáticos que son variables constantes.scene.out.layout. javafx. tienen el mismo acceso a las variables locales del ámbito envolvente:   Una clase anónima tiene acceso a los miembros de su clase envolvente. javafx.StackPane.ActionEvent. una declaración de un tipo (por ejemplo.java (de la sección Hello World.event. Button btn = new Button(). public class HelloWorld extends Application { public static void main(String[] args) { launch(args). btn. una variable) en una clase anónima ensombrece cualquier otra declaración en el ámbito envolvente que tiene el mismo nombre. javafx.  Las clases anónimas también tienen las mismas restricciones que las clases locales con respecto a sus miembros:   No puede declarar inicializadores estáticos o interfaces de miembro de una clase anónima. Tenga en cuenta que se puede declarar lo siguiente en clases anónimas:     Campos Métodos adicionales (incluso si no implementan los métodos del supertipo) Inicializadores de instancia Clases locales Sin embargo.event. Una clase anónima no puede acceder a variables locales en su ámbito envolvente que no son declaradas como final o final con eficacia. clases anónimas pueden capturar variables.Stage.setTitle("Hello World!"). application. En el siguiente ejemplo de JavaFX es desde la sección Personalización de controles de interfaz de usuario.EventHandler. 300.add(btn).show(). javafx. primaryStage. javafx. root.setConstraints(dollar.setPadding(new Insets(10.setText("Enter a numeric value").Scene.stage.event. GridPane grid = new GridPane(). stage. 0.matches("[a-z. 250)). El código resaltado crea un campo de texto que sólo acepta valores numéricos.layout.StackPane root = new StackPane().setOnAction especifica lo que sucede cuando se selecciona el botón de decir ' Hola mundo'.setScene(scene). Observe que esta expresión es el argumento que se pasa al método btn.HBox.replaceText(start. 150).GridPane.getChildren(). Este método requiere un objeto de tipo EventHandler<ActionEvent>.Group.scene.scene. 300. Scene scene = new Scene(root. el método de invocación btn.setScene(new Scene(root.scene. grid. manejar. 10)). grid. javafx. stage. La interfaz de EventHandler<ActionEvent> contiene solamente un método. En lugar de aplicar este método con una nueva clase. int end. end.Insets. scene. public class CustomTextFieldSample extends Application { final static Label label = new Label(). final TextField sum = new TextField() { @Override public void replaceText(int start.geometry.Application.setVgap(5). javafx. primaryStage. 10.getChildren().setOnAction.ActionEvent. Porque la interfaz EventHandler<ActionEvent> contiene solamente un método. String text) { if (!text. javafx.setHgap(5). } label. import import import import import import import import import import javafx.add(dollar). 10.setTitle("Text Field Sample"). A-Z]")) { super. @Override public void start(Stage stage) { Group root = new Group(). final Label dollar = new Label("$"). javafx. text).Stage. puede utilizar una expresión lambda en lugar de una expresión de la clase anónima. Consulte la sección Expresiones Lambda para obtener más información.scene. 0). javafx.*.layout. grid. Las clases anónimas son ideales para implementar una interfaz que contiene dos o más métodos. } . javafx.event. grid. el ejemplo utiliza una expresión de la clase anónima.control.setRoot(grid). Redefine la implementación predeterminada de la clase TextField con una clase anónima reemplazando los métodos replaceText y replaceSelection heredados de la clase TextInputControl. javafx.scene. GridPane. } } En este ejemplo. clases de anónimas y expresiones Lambda Como se mencionó en la sección Clases anidadas. Utilice una clase anidada estática si no necesita este acceso. } public static void main(String[] args) { launch(args). 3). clases anónimas y expresiones lambda también imparten estas ventajas. 0). Expresión lambda: o Utilizar si usted encapsula una sola unidad de comportamiento que desea pasar a otro código.setText(null). es necesario invocar métodos adicionales más adelante). por ejemplo. GridPane. stage. GridPane. llamar un tipo (. GridPane. } } }. 0). las clases anidadas permiten agrupar lógicamente las clases que se utilizan solamente en un solo lugar.setConstraints(submit.show().getChildren().setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { label. sum. 1).getChildren().add(submit). 2. 0.add(sum). Local clases.setRoot(grid). quieres que sea el tipo más ampliamente disponible. incrementar el uso de encapsulación y crear código más legible y fácil de mantener. grid.setConstraints(label.matches("[a-z. se destinan a ser utilizados para situaciones más específicas:     Clase local: usarlo si usted necesita crear más de una instancia de una clase.setPrefColumnCount(10). 1. } }). Por ejemplo. submit. Clase anónima: usarlo si necesita declarar campos o métodos adicionales. } } Cuándo utilizar clases anidadas.setColumnSpan(label. Button submit = new Button("Submit"). sum. para acceder a su constructor o introducir uno nuevo.@Override public void replaceSelection(String text) { if (!text. Clase anidada: usarlo si sus requerimientos son similares a los de una clase local.replaceSelection(text).setConstraints(sum. Clases locales.getChildren(). A-Z]")) { super. o Utilice una clase anidada no estático (o clase interna) si requiere acceso a campos no públicos y métodos de una instancia envolvente. GridPane. grid.add(label).setPromptText("Enter the total"). y no necesita acceso a variables locales o los parámetros del método. se usaría una expresión lambda si quieres cierta acción . scene. grid. Sin embargo. swing) para ayudar a contestar las siguientes preguntas. } public void displayStrings() { System.out. a.oracle. o cuando un proceso encuentra con un error.com/javase/8/docs/api/javax/swing/Box. ¿Qué es la superclase de la clase interna de la Box? d. } . System.getString() + ".displayStrings(). Utilice la documentación de la API de Java para la clase de Box (en el paquete javax. ¿Cuál es la salida? public class Class1 { protected InnerClass1 ic. cuando se completa un proceso.println(ic. ¿Cómo se crea una instancia de clase de la Box Filler? http://docs.println(ic. } static public void main(String[] args) { Class1 c1 = new Class1(). Utilizarlo si necesitas un ejemplo simple de una interfaz funcional y no se aplica ninguno de los anteriores criterios (por ejemplo. public Class1() { ic = new InnerClass1(). } protected class InnerClass1 { public String getString() { return "InnerClass1: getString invoked". ¿Que de clases anidadas de la Boxse puede usar de cualquier clase? e.").out. Preguntas y Ejercicios: Clases Anidadas Preguntas 1. Compilar y ejecutar Class1.o realizada en cada elemento de una colección. campos o métodos adicionales). El programa no compila Problem.").java. ¿Qué clase interna define Box? c.html Ejercicios 1. ¿Qué necesitas hacer para hacerlo compilar? ¿Por qué? public class Problem { String s. static class Inner { void testMethod() { s = "Set from Inner". } } } 2.getAnotherString() + ". c1. no necesitas un constructor. ¿Qué clase anidada estática define Box? b. llamar un tipo. Pregunta: ¿Qué clase interna conceptúa Box ? Respuesta: Box. Pregunta: ¿Cómo se crean una instancia de clase de la Box Filler ? .awt.java . } } } Las respuestas a las preguntas y ejercicios: clases anidadas Preguntas 1. } } } 2.public String getAnotherString() { return "InnerClass1: getAnotherString invoked".html a.Filler b. Respuesta: Box. http://docs. Una clase estática interna no tiene acceso a los campos de instancia de la clase externa.Filler e. Ver ProblemSolved.]Container.com/javase/8/docs/api/javax/swing/Box.swing ) para ayudar a contestar las siguientes preguntas.java .AccessibleAWTContainer d. Utilice la documentación de la API de Java para la clase Box (en el paquete javax.oracle.AccessibleBox c. Pregunta: el programa no compila Problem. public class ProblemSolved { String s. ¿Qué necesitas hacer para hacerlo compilar? ¿Por qué? Respuesta: eliminar static frente a la declaración de la clase Inner. Pregunta: Cuál de clases anidadas del Boxpuede utilizar de cualquier clase. Pregunta: ¿Qué clase anidada estática conceptúa Box ? Respuesta: Box. Pregunta: ¿Qué es la superclase de la clase interna de la Box? Respuesta: [java. class Inner { void testMethod() { s = "Set from Inner". definimos un tipo enum utilizando la palabra clave enum . } protected class InnerClass1 { public String getString() { return "InnerClass1: getString invoked".java.displayStrings(). especificaría un tipo enum dias-de-la-semana como: public enum Day { . System. Los ejemplos más comunes incluyen direcciones de la brújula (valores de norte. este y oeste) y los días de la semana.out. InnerClass1: getAnotherString invoked.getAnotherString() + ". prefDimension. } } } Respuesta: InnerClass1: getString invoked. For example. c1. Porque son constantes. } static public void main(String[] args) { Class1 c1 = new Class1().println(ic.Filler(minDimension. ¿Cuál es la salida? public class Class1 { protected InnerClass1 ic. sur. maxDimension) Ejercicio 1. La variable debe ser igual a uno de los valores que han sido predefinidos para ello.out. } public String getAnotherString() { return "InnerClass1: getAnotherString invoked".getString() + "."). son los nombres de los campos de un tipo enum en letras mayúsculas. En el lenguaje de programación Java. Compilar y ejecutar Class1. Tipos enumerados Un tipo enum es un tipo especial de datos que permite a una variable ser un conjunto de constantes predefinidas.println(ic. public Class1() { ic = new InnerClass1(). } public void displayStrings() { System.").Respuesta: new Box. Ejercicio: del archivo Class1. out. public EnumTest(Day day) { this. break. .SUNDAY. Aquí hay un código se muestra cómo utilizar la enumeración Day definida anteriormente: public class EnumTest { Day day.out.println("Midweek days are soso. WEDNESDAY.FRIDAY).tellItLikeItIs(). default: System.SUNDAY). break. TUESDAY.WEDNESDAY). EnumTest seventhDay = new EnumTest(Day. sixthDay."). FRIDAY. case SATURDAY: case SUNDAY: System. break.println("Fridays are better.out.MONDAY). las opciones de un menú. parámetros de línea de comandos y así sucesivamente. case FRIDAY: System. fifthDay. EnumTest fifthDay = new EnumTest(Day. SATURDAY } Usted debe usar los tipos enum cualquier momento en que necesite representar un conjunto fijo de constantes.").tellItLikeItIs(). Eso incluye tipos enum naturales tales como los planetas de nuestro sistema solar y los conjuntos de datos donde conoces a todos los valores posibles en tiempo de compilación. EnumTest thirdDay = new EnumTest(Day. break."). } } public static void main(String[] args) { EnumTest firstDay = new EnumTest(Day.SATURDAY).tellItLikeItIs(). MONDAY. firstDay.println("Weekends are best. thirdDay. } public void tellItLikeItIs() { switch (day) { case MONDAY: System.tellItLikeItIs().println("Mondays are bad.out.day = day. por ejemplo. THURSDAY. EnumTest sixthDay = new EnumTest(Day."). Weekends are best.printf("Your weight on %s is %f%n". Estos valores se pasan al constructor cuando se crea la constante.Enum.lang. } } La salida es: Mondays are bad. la lista de constantes enum debe terminar con coma un punto y. Java el lenguaje no soporta herencia múltiple del estado (véase herencia múltiple de estado. Además. Se definen con propiedades de radio y masa constante. El compilador añade automáticamente algunos métodos especiales cuando se crea un enum. En lenguaje de programación Java los tipos enum son mucho más potentes que en sus homólogos. Java exige las constantes definirse en primer lugar. } Nota: Todas las enumeraciones implicit extienden java. Nota: El constructor de un tipo enum debe ser paquete privado o de acceso privado. cuando hay campos y métodos.seventhDay. antes de cualquier campo o métodos. p. Weekends are best.surfaceWeight(mass)).values()) { System. En el ejemplo siguiente. p.tellItLikeItIs(). y por lo tanto no puede extender una enumeración nada más. Midweek days are so-so. No se puede invocar un constructor de enum. Cada constante de enumeración se declara con valores para los parámetros de masa y el radio. Por ejemplo. Fridays are better. . El cuerpo de la clase enum puede incluir métodos y otros campos. implementación y tipo). La declaración enum define una clase (llamada un tipo enum). Porque sólo puede extenderse una clase uno de los padres (véase Declarando clases). Este método se utiliza comúnmente en combinación con la para-cada construcción para iterar sobre los valores de un tipo enum. for (Planet p : Planet.out. este código del ejemplo de la clase de Planet siguiente recorre en iteración todos los planetas del sistema solar. el Planet es un tipo enum representa los planetas del sistema solar. Crea automáticamente las constantes definidas al principio del cuerpo enum. tienen un método estático values que devuelve una matriz que contiene todos los valores de la enumeración en el orden en que se declararon. Por ejemplo. 0518e6). (1.688e+26. 7. (6.Además de sus propiedades y constructor. } double surfaceWeight(double otherMass) { return otherMass * surfaceGravity(). } private double mass() { return mass. 6. Aquí es un programa de muestra lleva el peso de la tierra (en cualquier unidad) y calcula e imprime tu peso en todos los planetas (en la misma unidad): public enum MERCURY VENUS EARTH MARS JUPITER SATURN URANUS NEPTUNE Planet { (3.847567 Your weight on SATURN is 186. // in kilograms private final double radius.107583 Your weight on VENUS is 158. (8. double surfaceGravity() { return G * mass / (radius * radius). double radius) { this. } public static void main(String[] args) { if (args.exit(-1).parseDouble(args[0]).207413 . (4. } } 2.4746e7). (1.686e+25.4397e6).class desde la línea de comandos con un argumento permiso de 175. 2.length != 1) { System. Si capacitar Planet.37814e6). 6. } private double radius() { return radius. obtendrá esta salida: $ java Planet 175 Your weight on MERCURY is 66.printf("Your weight on %s is %f%n".67300E-11.303e+23.374842 Your weight on EARTH is 175.radius = radius.421e+23.976e+24.000000 Your weight on MARS is 66. 3.024e+26. 2.0268e7). (5.values()) System.9e+27. } double earthWeight = Double.552719 Your weight on URANUS is 158.surfaceGravity(). // in meters Planet(double mass.869e+24.279007 Your weight on JUPITER is 442. for (Planet p : Planet. this. (5. 6. p.5559e7).1492e7).3972e6).println("Usage: java Planet <earth_weight>"). } // universal gravitational constant (m3 kg-1 s-2) public static final double G = 6. double mass = earthWeight/EARTH.mass = mass. 2. p. private final double mass. Planet tiene métodos permiten recuperar la gravedad superficial y el peso de un objeto en cada planeta. System.surfaceWeight(mass)).err.397260 Your weight on NEPTUNE is 199.out. qué tipo de anotación predefinidos está disponible en la plataforma Java. entonces el nombre puede ser omitido. una forma de metadatos. nombre de la anotación es Override: @Override void mySuperMethod() { .. Esta lección explica donde anotaciones pueden ser utilizadas. proporcionar datos sobre un programa que no es parte del programa de sí mismo. que puede ser llamado o no identificada. Anotaciones no tienen ningún efecto directo sobre el funcionamiento del código que anotan.. Tiempo de ejecución de procesamiento — algunas anotaciones están disponibles para ser examinados en tiempo de ejecución. En el ejemplo siguiente. como en: @SuppressWarnings("unchecked") void myMethod() { .. } .. cómo aplicar las anotaciones. y hay valores para los elementos: @Author( name = "Benjamin Franklin".. } La anotación puede incluir elementos. Standard Edition (Java SE API)... archivos XML y así sucesivamente.. } o @SuppressWarnings(value = "unchecked") void myMethod() { . una anotación luce como el siguiente: @Entity La arroba carácter (@) indica al compilador que lo que sigue es una anotación. } Si hay un elemento denominado value. Conceptos básicos de anotaciones El formato de una anotación En su forma más simple.Lección: anotaciones Anotaciones. date = "3/27/2003" ) class MyClass() { . cómo tipo annnotations puede utilizarse en conjunción con sistemas de tipo enchufable para escribir código con verificación de tipos más fuerte y cómo implementar la repetición anotaciones. Anotaciones tienen un número de usos. Procesamiento de tiempo de compilación y tiempo de implementación — herramientas de Software pueden procesar información de anotación para generar código. entre ellos:    Información para el compilador — anotaciones pueden utilizarse por el compilador para detectar errores o suprimir advertencias. consulte tipo de anotaciones y sistemas de tipo enchufable. Cuando se utiliza en una declaración.. Override y SuppressWarnings son anotaciones Java predefinidas. A partir de la versión de Java SE 8. } Repitiendo las anotaciones se admiten como del 8 Java SE suelte. Tipo cast: myString = (@NonNull String) str. métodos y otros elementos del programa. Estos son algunos ejemplos:           Expresión de creación de la instancia de clase: new @Interned MyObject().. como se muestra en el ejemplo anterior @Override .Si la anotación no tiene elementos.. cada anotación a menudo aparece. entonces esto se llama una anotación de repetición: @Author(name = "Jane Doe") @Author(name = "John Smith") class MyClass { . } Esta forma de anotación se llama una anotación de tipo. anotaciones pueden aplicarse también para el uso de tipos. cláusula implements : class UnmodifiableList<T> implements @Readonly List<@Readonly T> { . entonces los paréntesis se pueden omitir. También es posible usar varias anotaciones en la misma declaración: @Author(name = "Jane Doe") @EBook class MyClass { . El tipo de anotación puede ser uno de los tipos que se definen en los paquetes java..lang. campos. Declarar un tipo de anotación Muchas anotaciones reemplazar comentarios en código.. En los ejemplos anteriores.. Donde pueden ser utilizadas las anotaciones Las Anotaciones pueden ser aplicadas a las declaraciones: las declaraciones de clases.. Las anotaciones del Author y Ebook en el ejemplo anterior son tipos de anotación personalizadas. Supongamos que un grupo de software comienza tradicionalmente el cuerpo de cada clase con comentarios proporcionando información importante: . por Convención. } Si las anotaciones tienen el mismo tipo. en su propia línea. } Declaración de excepción lanzada: void monitorTemperature() throws @Critical TemperatureException { . Para más información.annotation de la API de Java SE. vea Repitiendo las anotaciones. Para más información.lang o java. También es posible definir su propio tipo de anotación.. int currentRevision() default 1. primero es necesario definir el tipo de anotación.annotation. // Note array notation reviewers = {"Alice". currentRevision = 6. String lastModifiedBy() default "N/A". El cuerpo de la definición anterior anotación contiene elementos de tipo anotación declaraciones. Tipos de anotación son una forma de interfaz. que serán cubiertos en una lección posterior. con los valores de relleno. Después se define el tipo de anotación. String lastModified() default "N/A". usted debe anotar la definición de @ClassPreamble con la anotación @Documented : // import this to use @Documented import java.public class Generation3List extends Generation2List { // // // // // // Author: John Doe Date: 3/17/2002 Current revision: 6 Last modified: 4/12/2004 By: Jane Doe Reviewers: Alice. "Cindy"} ) public class Generation3List extends Generation2List { // class code goes here } Nota: Para ampliar la información en @ClassPreamble en la documentación generada por Javadoc. lastModified = "4/12/2004".lang. Cindy // class code goes here } Para agregar este mismo metadatos con una anotación. puede utilizar las anotaciones de ese tipo. String date(). // Note use of array String[] reviewers(). lastModifiedBy = "Jane Doe". no necesitas comprender las interfaces. La sintaxis para hacer que esto es: @interface ClassPreamble { String author(). } La definición de tipo de anotación es similar a una definición de interfaz donde la palabra clave interface está precedido por la arroba (@) (@ = AT. así: @ClassPreamble ( author = "John Doe". date = "3/17/2002". @Documented @interface ClassPreamble { . Tenga en cuenta que pueden definir valores por defecto opcional. Por el momento. que parecen muchos métodos. Bill. como en el tipo de anotación).*. "Bob". // use a deprecated method and tell // compiler not to generate a warning @SuppressWarnings("deprecation") void useDeprecatedMethod() { // deprecation warning // . debe también ser documentó utilizando la etiqueta @deprecated Javadoc. Si un método marcado con @Override falla reemplazar correctamente un método en uno de sus superclases. @Deprecated @Deprecated anotación indica que el elemento de marcado es obsoleto y ya no debe ser utilizado. tenga en cuenta que la etiqueta de Javadoc comienza con una minúscula d y la anotación se inicia con una mayúscula D.suppressed objectOne. clase o campo con la anotación de @Deprecated . El uso de la arroba (@) en ambos comentarios Javadoc y anotaciones no es casual: se relacionan conceptualmente. // Javadoc comment follows /** * @deprecated * explanation of why it was deprecated */ @Deprecated static void deprecatedMethod() { } } @Override @Override anotación informa al compilador que el elemento está destinado a reemplazar un elemento declarado en una superclase. el compilador genera un error.deprecatedMethod(). Tipos de anotación utilizados por el lenguaje Java @Deprecated @Overridey @SuppressWarnings están los tipos predefinidos anotación definidos en java. Cuando un elemento se considera obsoleto. la anotación causa la advertencia que se debe suprimir. // mark method as a superclass method // that has been overridden @Override int overriddenMethod() { } Mientras que no es necesario usar esta anotación cuando un método.// Annotation element definitions } Tipos de anotación predefinidos Un conjunto de tipos de anotación están predefinidos en la API de Java SE. . y algunas se aplican a otras anotaciones.lang. @SuppressWarnings @SuppressWarnings anotación indica al compilador que suprimir las advertencias específicas que de lo contrario generaría. como se muestra en el ejemplo siguiente. También. sin embargo. El compilador genera una advertencia cada vez que un programa utiliza un método. Métodos se discutirán en las Interfaces y la herencia. se utiliza un método en desuso. Algunos tipos de anotación son utilizados por el compilador de Java. En el ejemplo siguiente. ayuda a evitar errores. En este caso. y el compilador generalmente genera una advertencia. ElementType. ElementType. ElementType. @FunctionalInterface Anotación @FunctionalInterface .PARAMETER puede ser aplicado a los parámetros de un método.METHOD puede aplicarse a una anotación de nivel de método. las anotaciones no están incluidas en Javadoc).CLASS – la anotación marcada es retenida por el compilador en tiempo de compilación.lang. Una anotación de destino especifica uno de los siguientes tipos de elemento como su valor:         ElementType. Existen varios tipos de meta-anotación definidos en java. advertencias relativas al uso de varargs son suprimidas.ANNOTATION_TYPE puede ser aplicado a un tipo de anotación. @Retention @Retention anotación especifica cómo se almacena la anotación marcada:    RetentionPolicy. Cuando se utiliza este tipo de anotación. como se define en la especificación del lenguaje Java. (De forma predeterminada. @Documented @Documented anotación indica que cuando se usa la anotación especifica aquellos elementos deben ser documentados mediante la herramienta Javadoc. utilice la siguiente sintaxis: @SuppressWarnings({"unchecked". Para suprimir varias categorías de advertencias.CONSTRUCTOR se puede aplicar a un constructor. Anotaciones que se aplican a otras anotaciones Las anotaciones que se aplican a otras anotaciones se llaman meta-anotaciones. (Esto no es cierto por defecto). ElementType. "deprecation"}) @SafeVarargs @SafeVarargs anotación. pero es ignorado por la Java Virtual Machine (JVM). RetentionPolicy. afirma que el código no realizar operaciones potencialmente inseguras sobre su parámetro varargs . consulte la página de herramientas de Javadoc. ElementType.annotation. indica que la declaración de tipo pretende ser una interfaz funcional. Cuando el usuario consulta el tipo de anotación y la clase no tiene anotación para este tipo. cuando se aplica a un método o constructor. La advertencia unchecked puede ocurrir cuando con código legado escrito antes de la llegada de los genéricos. RetentionPolicy.PACKAGE puede aplicarse a una declaración de paquete.FIELD puede aplicarse a un campo o propiedad. La especificación del lenguaje Java listas dos categorías: deprecation y unchecked. introducido en Java SE 8. se consulta a la superclase de la clase para el tipo de anotación.} Cada advertencia del compilador pertenece a una categoría.RUNTIME – la anotación marcada es conservada por la JVM así que puede ser utilizado por el entorno de ejecución. Esta anotación se aplica sólo a las declaraciones de clase. . ElementType. @Target @Target anotación marca otra anotación para restringir qué tipo de elementos de Java la anotación se puede aplicar a.LOCAL_VARIABLE se puede aplicar a una variable local.SOURCE – la anotación marcada se conserva sólo en el nivel de la fuente y es ignorado por el compilador. @Inherited @Inherited anotación indica que el tipo de anotación puede ser heredado de la superclase. Para obtener más información.TYPE se puede aplicar a cualquier elemento de una clase. ElementType. Herencia Esta sección describe la manera en la que se puede derivar una clase de otra. el compilador produce una advertencia porque open era deprecated (en la interfaz). } Lección: Interfaces y herencia Interfaces Viste un ejemplo de la implementación de una interfaz en la lección anterior. introducido en Java SE 8. y cómo modificar los métodos que una subclase hereda de superclases. cómo una subclase puede heredar campos y métodos de una superclase. vea Repitiendo las anotaciones. mainDish="pizza") @Meal("dinner". indica que la anotación marcada se puede aplicar más de una vez para el mismo uso declaración o tipo. Usted aprenderá que todas las clases se derivan de la clase Object. . y cómo escribir una. por qué es posible que desee escribir una. void openFrontDoor().. public class MyHouse implements House { public void open() {} public void openFrontDoor() {} public void openBackDoor() {} } Si se compila este programa. mainDish="cereal") @Meal("lunch". Para más información.. Considere esta implementación de la interfaz de House. mainDish="salad") public void evaluateDiet() { . Preguntas y ejercicios: anotaciones Preguntas 1. Esta sección cubre también interfaces como clases abstractas.. } 2.@Repeatable Anotación @Repeatable . void openBackDoor(). ¿Qué pasa con la siguiente interfaz? public interface House { @Deprecated void open().. ¿Qué puede hacer para deshacerse de esa advertencia? 3. Es decir. que se muestra en la pregunta 1. Puedes leer más sobre interfaces aquí — para qué son. } @Meal("breakfast". ¿El siguiente código se compilará sin errores? ¿Por qué si o por qué no? public @interface Meal { . . arrancar. double speedOfCar). int getRadarRear(double distanceToCar. De hecho. métodos estáticos y tipos anidados. por supuesto) que opera el automóvil — parar. double endSpeed). int signalTurn(Direction direction. Los cuerpos de método existen solamente para métodos por defecto y métodos estáticos. imaginemos una sociedad futurista donde los coches robóticos controlados por computadora transportan pasajeros por las calles sin un operador humano. Otro grupo industrial. // más firmas de métodos } . las interfaces son esos contratos. Las interfaces No pueden ser instanciadas— sólo pueden ser implementadas por las clases o extendidas por otras interfaces. una interfaz es un tipo de referencia. Ninguno de los dos grupos industriales necesita saber Cómo es que implementa el otro grupo el software. double radius. . sistemas informáticos que reciben datos de posición GPS (Global Positioning System) y la transmisión inalámbrica de las condiciones del tráfico. cada grupo considera su software altamente patentado y se reserva el derecho de modificarlo en cualquier momento. LEFT int turn(Direction direction. de cualquier fabricante). La Extensión se discute más adelante en esta lección. acelerar. fabricantes del instrumento electrónico de posicionamiento. double startSpeed. usan esa información para conducir el coche. que puede contener sólo constantes. Cada grupo debe ser capaz de escribir su código sin ningún conocimiento de cómo se escribe el código del otro grupo. Interfaces en Java En el lenguaje de programación Java. siempre que continue adherido a la interfaz publicada. girar a la izquierda. En términos generales.. Fabricantes de automóviles escriben software (Java. boolean signalOn).. int getRadarFront(double distanceToCar. double startSpeed. int changeLanes(Direction direction. y así sucesivamente.. double speedOfCar). firmas de métodos. métodos por defecto. Por ejemplo. Los fabricantes de automóviles deben publicar una interfaz estándar de la industria que explica en detalle qué métodos pueden invocarse para mover el coche (cualquier coche. similar a una clase. si la hay // firmas de métodos // una enumeración con valores RIGHT.. Los fabricantes del posicionamiento pueden entonces escribir software que invoca los métodos descritos en la interfaz para dirigir el coche.Interfaces Hay una serie de situaciones en ingeniería de software cuando es importante para los grupos dispares de programadores acordar un "contrato" que detalle cómo interactúa su software. Definir una interfaz es similar a la creación de una nueva clase: public interface OperateCar { // declaraciones de constantes. double endSpeed). son los fabricantes de automóviles quienes implementarán la interfaz. Cuando una clase instanciable implementa una interfaz. mapas digitales y datos de tráfico para conducir el coche. con la implementación -// por ejemplo: int signalTurn(Direction direction. public class OperateBMW760i implements OperateCar { // las firmas del método OperateCar. cambiar de carril. acelerar y así sucesivamente. su implementación de la API es mantenida como un secreto muy bien guardado. frenar. La empresa entonces invoca los métodos con las firmas de procesamiento de imágenes y devuelve los tipos definidos en la interfaz. Interfaces como APIs El ejemplo del Coche robótico muestra una interfaz que se utiliza como una Interfaz de programación de aplicaciones (API) estándar de la industria. el sistema de guía invocará los métodos de interfaz: girar. una lista separada por comas de interfaces padre (si corresponde) y el cuerpo de la interfaz. Interface2. que son los clientes de la interfaz. Definir una interfaz Una declaración de interfaz consta de modificadores. La Implementación de un Chevrolet será sustancialmente diferente a la de un Toyota. según sea necesario -por ejemplo. Mientras que la API de la compañía de procesamiento de imágenes se hace pública (a sus clientes). Por ejemplo: public interface GroupedInterface extends Interface1. Los fabricantes del posicionamiento. de hecho. escriba una clase que implementa la interfaz. pero ambos fabricantes se adherirán a la misma interfaz. proporciona un cuerpo de método para cada uno de los métodos declarados en la interfaz. que hace pública a sus clientes. La compañía de procesamiento de imágenes escribe sus clases para implementar una interfaz. puede revisar la implementación en una fecha posterior mientras continúa implementando la interfaz original en la que sus clientes han confiado.718282. boolean signalOn) { // código para encender la luz direccional IZQUIERDA del BMW // código para apagar la luz direccional IZQUIERDA del BMW // código para encender la luz direccional DERECHA del BMW // código para apagar la luz direccional DERECHA del BMW } // otros miembros. . el nombre de la interfaz. Las API’s también son comunes en los productos de software comercial. Por lo general. por supuesto. las clases // auxiliares no visibles a los clientes de la interfaz } En el ejemplo del coche robótico anterior. Al hacerlo. basarán sus sistemas que utilizan datos de GPS en la ubicación del coche. Interface3 { // declaraciones de constantes // base de los logaritmos naturales double E = 2. Para utilizar una interfaz. una empresa vende un paquete de software que contiene métodos complejos que otra empresa quiere utilizar en su propio producto de software. la palabra clave interface. Por ejemplo.Tenga en cuenta que las firmas de los métodos no tienen llaves y se terminan con un punto y coma. Un ejemplo sería un conjunto de métodos que se venden a las empresas para hacer programas de gráficos para el usuario final de procesamiento de imágenes digitales. por defecto y estáticos en una interfaz son implícitamente public. La declaración de interfaz incluye una lista separada por comas de todas las interfaces que se extiende. Si no se especifica que la interfaz es pública. Para strings. Para objetos planos geométricos. incluye una cláusula implements en la declaración de clase. podría ser el número de páginas. para los estudiantes. } Si quieres ser capaz de comparar el tamaño de objetos similares. considerando que una clase puede extender sólo de otra clase. Cualquier clase puede implementar Relatable si hay alguna forma de comparar el relativo "tamaño" de los objetos instanciados de la clase. para libros. si es que existe. o menor que otro public int isLargerThan(Relatable other). -1 // si este es mayor que. se pueden omitir estos modificadores. entonces se puede omitir el modificador public. El cuerpo de la interfaz El cuerpo de la interfaz puede contener métodos abstractos. Todos los valores constantes definidos en una interfaz son implícitamente public. y así sucesivamente. Por Convención. mientras que volumen trabajaría para objetos geométricos tridimensionales. Una vez más. static y final. double x). podría ser número de caracteres. Los Métodos por defecto se definen con el modificador default y los métodos estáticos con la palabra clave static. Implementar una interfaz Para declarar una clase que implementa una interfaz. Todas estas clases pueden implementar el método isLargerThan(). pero sin llaves (un método abstracto no contiene una implementación). public interface Relatable { // este (objeto llamando isLargerThan) // y otros deben ser instancias // de los retornos de clase 1. independientemente de lo que son. así como una subclase de la clase o ampliar otra clase. } El especificador de acceso public indica que la interfaz se puede utilizar por cualquier clase en cualquier paquete. la cláusula implements sigue a la cláusula extends. Una interfaz puede extender otras interfaces. una interfaz puede contener declaraciones de constantes. // igual a. métodos por defecto y métodos estáticos. puede ser peso. Un método abstracto dentro de una interfaz es seguido por un punto y coma. . así que la palabra clave implements es seguida por una lista separada por comas de las interfaces implementadas por la clase. Una interfaz de muestra. 0. Además. Todos los métodos abstractos. su interfaz es accesible sólo para las clases definidas en el mismo paquete que la interfaz. La clase puede implementar más de una interfaz.// firmas de métodos void doSomething (int i. Sin embargo. la clase que instancía debería implementar Relatable. una interfaz puede extender cualquier número de interfaces. el área sería una buena opción (véase la clase RectanglePlus que sigue). Relatable Considere una interfaz que define cómo comparar el tamaño de los objetos. int doSomethingElse(String s). } // a method for moving the rectangle public void move(int x. } public RectanglePlus(Point p) { origin = p. int y) { origin. 0). width = w. public class RectanglePlus implements Relatable { public int width = 0.Si sabes que una clase implementa Relatable. int w.getArea() < otherRect. } // un método necesario para implementar // la interfaz Relatable public int isLargerThan(Relatable other) { RectanglePlus otherRect = (RectanglePlus)other. } public RectanglePlus(Point p.y = y. } } Porque RectanglePlus implementa Relatable. entonces usted sabe que puede comparar el tamaño de los objetos instanciados desde esa clase.getArea()) return 1.getArea()) return -1. int h) { origin = new Point(0. Implementa la interfaz Relatable Aquí está la clase Rectangle que fue presentada en la sección de Crear objetos . else return 0. } // un método para calcular // el area del rectangulo public int getArea() { return width * height. public Point origin. .x = x. reescrita para implementar Relatable. int h) { origin = p. public int height = 0. height = h. if (this. // cuatro constructores public RectanglePlus() { origin = new Point(0. else if (this. origin. se puede comparar el tamaño de los dos objetos RectanglePlus . 0).getArea() > otherRect. height = h. } public RectanglePlus(int w. width = w. Si haces un punto de la implementación de Relatable en una amplia variedad de clases. aquí esta un método para encontrar el objeto más grande en un par de objetos. está definiendo un nuevo tipo de dato de referencia. donde pueden tener comportamiento desde una interfaz y una superclase.Nota: El método isLargerThan. Como ejemplo. Esto les da la algunas de las ventajas de herencia múltiple. Relatable obj2 = (Relatable)object2. La línea de código. Si define una variable de referencia cuyo tipo es una interfaz. if ((obj1). else return false. Cuando implementan Relatable. Puede utilizar nombres de interfaces en cualquier lugar puede utilizar cualquier otro nombre de tipo de dato. Invocando getArea directamente en la instancia other (other. pueden ser de su propio tipo de clase (o superclase) y un tipo de Relatable. } public boolean isEqual(Object object1. } Por casting del object1 a un tipo Relatable. Asimismo. } Estos métodos funcionan para cualquier objeto "relatable". cualquier objeto que se asigna debe ser una instancia de una clase que implementa la interfaz. los objetos instanciados desde cualquiera de esas clases pueden ser comparados con el método findLargest() — siempre que ambos objetos sean de la misma clase. Relatable obj2 = (Relatable)object2. Usando una interfaz como un tipo Cuando define una nueva interfaz. . if ((obj1). tal como se define en la interfaz de Relatable.getArea()) fallaría la compilación porque el compilador no entiende que other es actualmente una instancia de RectanglePlus. no importa cuál sea su herencia de clases. Object object2) { Relatable obj1 = (Relatable)object1. else return object2. Relatable obj2 = (Relatable)object2.isLargerThan(obj2) < 0) return object1. if ( (obj1). pueden todos ser comparados con los siguientes métodos: public Object findSmallest(Object object1. toma un objeto de tipo Relatable. puede invocar al método isLargerThan.isLargerThan(obj2) > 0) return object1. Este tipo de casting indica al compilador qué objeto realmente es. Object object2) { Relatable obj1 = (Relatable)object1.isLargerThan(obj2) == 0) return true. para cualquier objeto que es instanciado desde una clase que implementa Relatable: public Object findLargest(Object object1. Object object2) { Relatable obj1 = (Relatable)object1. que se muestra en negrita en el ejemplo anterior. else return object2. castea o arroja other a una instancia RectanglePlus. double x). para que la interfaz se convierta en: public interface DoIt { void doSomething(int i. Los programadores confiando en esta interfaz protestarán en voz alta. double x. String s). double x). en un momento posterior. El ejemplo siguiente define un método por defecto denominado didItWork: public interface DoIt { void doSomething(int i. double x). Si desea agregar métodos adicionales en una interfaz. } Ahora los usuarios de su código pueden optar por seguir utilizando la interfaz vieja o para actualizar a la nueva interfaz. Métodos por defecto . Alternativamente. default boolean didItWork(int i. int doSomethingElse(String s). boolean didItWork(int i. desea agregar un tercer método para DoIt.Evolución de las Interfaces Considere una interfaz que has desarrollado llamada DoIt: public interface DoIt { void doSomething(int i. int doSomethingElse(String s). } Supongamos que. Trate de anticipar todas las aplicaciones para su interface y definirla completamente desde el principio. double x. String s) { // Method body } } Tenga en cuenta que usted debe proporcionar una implementación de métodos por defecto. Los usuarios que tienen las clases que implementan las interfaces mejoradas con nuevo valor por defecto o métodos estáticos no tienen que modificarlos o recompilarlos para acomodar los métodos adicionales. todas las clases que implementan la interfaz vieja DoIt romperán porque ya no implementan la interfaz antigua. usted puede definir sus nuevos métodos como métodos por defecto. } Si se realiza este cambio. usted tiene varias opciones. String s). También puede definir nuevos métodos estáticos para interfaces existentes. Se puede crear una interfaz DoItPlus que se extiende de DoIt: public interface DoItPlus extends DoIt { boolean didItWork(int i. double x. int doSomethingElse(String s). int minute. timeToSet). a sus coches? Estos fabricantes tendrían que especificar nuevos métodos para permitir que otras empresas (como los fabricantes de instrumentos de posicionamiento electrónico) adapten su software para autos voladores. TimeClient. } public void setDateAndTime(int day.now(). dateAndTime = LocalDateTime. dateAndTime = LocalDateTime. minute.util. } La clase siguiente. public class SimpleTimeClient implements TimeClient { private LocalDateTime dateAndTime. void setDate(int day.from(dateAndTime). LocalTime timeToSet = LocalTime. Si los añaden como métodos estáticos. int month. no como esenciales. implementa TimeClient: package defaultmethods. public interface TimeClient { void setTime(int hour. LocalTime currentTime = LocalTime. LocalDateTime getLocalDateTime().time.from(dateAndTime).time.*.*. int month. int second) { LocalDate currentDate = LocalDate.La sección Interfaces describe un ejemplo que involucra a fabricantes de coches controlados por computadora que publican las interfaces estándar de la industria que describen los métodos que pueden invocarse para operar sus coches. import java. ¿Dónde declararían estos fabricantes de automóviles estos nuevos métodos relacionados con los vuelos? Si los añaden a sus interfaces originales.*. int month. tales como vuelo.of(day. import java. currentTime). } public void setDate(int day. void setDateAndTime(int day.of(currentDate.of(hour. month. int hour. Los Métodos por defecto permiten añadir nuevas funciones a las interfaces de sus bibliotecas y asegurar la compatibilidad binaria con código escrito para las versiones más antiguas de las interfaces. int minute. year). second). ¿Qué pasa si los fabricantes de coches controlados por computadora añaden nuevas funciones. int year). public SimpleTimeClient() { dateAndTime = LocalDateTime. como métodos básicos. entonces los programadores los considerarían como métodos de utilidad. int second). int hour. como se describe en respuestas a las preguntas y ejercicios: Interfaces: import java. int second). Considere la siguiente interfaz. SimpleTimeClient. int year. int year) { LocalDate dateToSet = LocalDate.lang. int year.*. int month.of(dateToSet. int minute. los programadores que han implementado las interfaces tendrían que reescribir sus implementaciones. int minute. import java. } public void setTime(int hour. int second) { . void setDateAndTime(int day. int second). } } . } A raíz de esta modificación a la interfaz TimeClient . dateAndTime = LocalDateTime. int month.of(zoneString). month. int hour. int second). System."). int year). public interface TimeClient { void setTime(int hour.. int year).. int second).systemDefault(). LocalTime timeToSet = LocalTime. package defaultmethods.*.toString(). } catch (DateTimeException e) { System.of(day. ZonedDateTime getZonedDateTime(String zoneString). en lugar de dejar getZonedDateTime como abstract (como en el ejemplo anterior). return ZoneId.println(myTimeClient. second). int month. int month. } public LocalDateTime getLocalDateTime() { return dateAndTime. LocalDateTime getLocalDateTime(). LocalDateTime getLocalDateTime(). void setDate(int day. Sin embargo.out. en su lugar se puede definir una implementación por defecto. static ZoneId getZoneId (String zoneString) { try { return ZoneId. int minute.err. (Recuerde que un método abstracto es un método declarado sin una implementación). } } Suponga que desea añadir nuevas funciones a la interfaz TimeClient. } public static void main(String. int year. void setDateAndTime(int day. year). también tendrías que modificar la clase SimpleTimeClient e implementar el método getZonedDateTime. using default time zone instead. como la capacidad de especificar una zona horaria a través de un objeto ZonedDateTime (que es como un objeto LocalDateTime excepto que almacena información de zona horaria): public interface TimeClient { void setTime(int hour. int month. int hour.time.of(dateToSet. } public String toString() { return dateAndTime.toString()). int second). int minute. void setDate(int day.of(hour. int minute. args) { TimeClient myTimeClient = new SimpleTimeClient(). int year. timeToSet).println("Invalid time zone: " + zoneString + ".LocalDate dateToSet = LocalDate. import java. int minute. minute. getZonedDateTime.println("Current time: " + myTimeClient.*.*. import java. incluyendo métodos por defecto. System.default ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime. Redefina el método por defecto.toString()).toString()). invoca al método getZonedDateTime desde una instancia de SimpleTimeClient: package defaultmethods.util. getZoneId(zoneString)).*. El ejemplo siguiente. Vuelva a declarar el método por defecto.getZonedDateTime("Blah blah"). usted no tiene que modificar la clase SimpleTimeClient. } . TestSimpleTimeClient.of(getLocalDateTime(). deje que su interfaz extendida herede el método por defecto.out.println("Time in California: " + myTimeClient.time. puede hacer lo siguiente:    No mencione en absoluto el método por defecto. } } Extender Interfaces que contienen métodos por defecto Cuando se extiende una interfaz que contiene un método por defecto. import java.out. Supongamos que se extiende la interfaz TimeClient como sigue: public interface AbstractZoneTimeClient extends TimeClient { public ZonedDateTime getZonedDateTime(String zoneString). } } Especifica que una definición de método en una interfaz es un método por defecto con la palabra clave default al principio de la firma del método.. import java. Todas las declaraciones de método en una interfaz. System. Supongamos que se extiende la interfaz TimeClient como sigue: public interface AnotherTimeClient extends TimeClient { } Cualquier clase que implemente la interfaz AnotherTimeClient tendrá la aplicación especificada por el método por defecto TimeClient. puede omitir el modificador public . que lo reemplaza. implícitamente son public. tendrá el método getZonedDateTime ya definido. que lo convierte en abstract. Con esta interfaz. y esta clase (y cualquier clase que implemente la interfaz TimeClient). public class TestSimpleTimeClient { public static void main(String. args) { TimeClient myTimeClient = new SimpleTimeClient().lang.. err.of(getLocalDateTime(). using default time zone instead. static public ZoneId getZoneId (String zoneString) { try { return ZoneId. Esto hace más fácil para que usted pueda organizar métodos auxiliares en sus bibliotecas. return ZonedDateTime. (Un método estático es un método que se asocia con la clase en la que se define en lugar de con cualquier objeto. puede omitir el modificador public. Todas las declaraciones de método en una interfaz.of(getLocalDateTime().systemDefault()). } } default public ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(zoneString). incluyendo métodos estáticos. Puedes quedarte con métodos estáticos específicos en una interfaz en la misma interfaz en lugar de una clase aparte."). utiliza la zona horaria del sistema por defecto si no hay ningún objeto ZoneId correspondiente al identificador determinado.of(getLocalDateTime().systemDefault(). .. Supongamos que se extiende la interfaz TimeClient como sigue: public interface HandleInvalidTimeZoneClient extends TimeClient { default public ZonedDateTime getZonedDateTime(String zoneString) { try { return ZonedDateTime. } catch (DateTimeException e) { System.println("Invalid time zone: " + zoneString + ". Cada instancia de la clase comparte sus métodos estáticos).of(zoneString))."). El ejemplo siguiente define un método estático que recupera un objeto ZoneId correspondiente a un identificador de zona horaria. Métodos estáticos Además de los métodos por defecto.Cualquier clase que implemente la interfaz AbstractZoneTimeClient tendrá que implementar el método getZonedDateTime.println("Invalid zone ID: " + zoneString + ". } catch (DateTimeException e) { System.ZoneId. } } } Cualquier clase que implemente la interfaz HandleInvalidTimeZoneClient utilizará la implementación de getZonedDateTime especificado por esta interfaz en lugar del especificado por la interfaz TimeClient. se pueden definir métodos estáticos en las interfaces. return ZoneId.ZoneId. } } Como los métodos estáticos en clases. (Como resultado. Este método es un método abstract como todos los demás que no son métodos por defecto (y no estáticos) en una interfaz. getZoneId(zoneString)).err. using the default time zone instead.. implícitamente son public. se especifica que una definición de método en una interfaz es un método estático con la palabra clave static al principio de la firma del método. puede simplificar el método getZonedDateTime): public interface TimeClient { // . } } public enum Rank { DEUCE (2 . public interface Card extends Comparable<Card> { public enum Suit DIAMONDS (1. this.value = value. } public int value() {return value. La interfaz de la Card contiene dos tipos de enum (Suit y Rank) y dos métodos abstractos (getSuit y getRank): package defaultmethods.Suit getSuit(). CLUBS (2.} public String text() {return text.value = value. THREE (3 . Considere las clases de Card y la Deck que se describe en preguntas y ejercicios: clases. FIVE (5 . } public int value() {return value. "Nine" ). Rank(int value. SEVEN (7 . "Eight"). HEARTS (3.} } public Card. JACK (11. "Ten" ). KING (13. "Three"). SIX (6 . "Clubs" ). EIGHT (8 . this. "Hearts" ). métodos predeterminados permiten agregar métodos que aceptan expresiones lambda como parámetros para interfaces existentes. NINE (9 . private final int value. { "Diamonds").Integración de métodos por defecto en bibliotecas existentes Los Métodos por defecto permiten añadir nuevas funciones a las interfaces existentes y asegurar la compatibilidad binaria con código escrito para las versiones más antiguas de las interfaces. Suit(int value. private final String text. ACE (14. "Five" ). } . "Two" ). TEN (10.text = text. En este ejemplo reescribe las clases Card y Deck como interfaces. "Seven").} public String text() {return text. FOUR (4 . En particular. "Spades" ). String text) { this. "Ace" ). SPADES (4. public Card. String text) { this.Rank getRank(). QUEEN (12. private final int value. "Queen").text = text. "Six" ). "Jack" ). private final String text. "Four" ). "King" ). Esta sección muestra cómo ha mejorado la interfaz Comparator con por defecto y métodos estáticos. void shuffle()... y la clase StandardDeck implementa la interfaz Deck.sort(entireDeck). } .*. void addDeck(Deck deck).o. // .*. String deckToString(). void addCards(List<Card> cards). El miembro entireDeck es una instancia de List cuyos elementos son del tipo de Card.util...value()-1)*13)+rank. import java. int numberOfCards) throws IllegalArgumentException. public interface Deck { List<Card> getCards().sort ordena una instancia de List cuyo tipo de elemento implementa la interfaz Comparable. } La clase PlayingCard implementa la interfaz de Card. void sort().value().stream. } El método Collections. que se extiende a Comparable.compareTo de la siguiente manera: public int hashCode() { return ((suit.lang. La clase PlayingCard implementa el método Comparable. int size(). public void sort() { Collections.La interfaz de Deck contiene varios métodos que manipulan las cartas de una baraja: package defaultmethods. Deck> deal(int players. } // .util.hashCode() . import java. void sort(Comparator<Card> c).sort como sigue: public class StandardDeck implements Deck { private List<Card> entireDeck.*. import java. } public int compareTo(Card o) { return this. void addCard(Card card). Map<Integer. Deck deckFactory(). La clase StandardDeck implementa el método abstracto Deck.hashCode(). public class SortByRankThenSuit implements Comparator<Card> { public int compare(Card firstCard.value() . secondCard) -> firstCard.sort() ordene primero la baraja de cartas por pallo y luego por la rango.value().shuffle(). Comparator<? super T> c) (la versión del método de sort que incluye un parámetro de Comparator ). else return firstCard.*.value() secondCard.lang.secondCard.sort(entireDeck. ¿Qué defecto o métodos estáticos ¿podría añadir a la interfaz de Comparator para permitir a que otros desarrolladores más fácilmente especifican criterios de ordenación? Para empezar. } } La siguiente invocación ordena la baraja de cartas primero por su rango. ¿Qué pasa si desea ordenar la baraja primero que el rango. sería mejor si puede especificar qué que desea ordenar. myDeck. supongamos que desea ordenar la baraja de cartas por rango. se puede especificar cómo el método Collections. no Cómo desea ordenarlo. Usted puede invocar el método StandardDeck. Supongamos que usted es el desarrollador quien escribió la interfaz Comparator.*.getSuit().getRank(). Puede definir el siguiente método en la clase StandardDeck: public void sort(Comparator<Card> c) { Collections.stream. myDeck.getRank(). if (compVal != 0) return compVal.getRank().sort de la siguiente manera: StandardDeck myDeck = new StandardDeck(). c). .util. import java. Sin embargo.value() ). este enfoque es muy detallado. import java.sort( (firstCard.getSuit(). Card secondCard) { int compVal = firstCard.value() secondCard. } Con este método.shuffle(). independientemente del palo. myDeck.sort ordena a instancias de la clase de Card .sort(new SortByRankThenSuit()). luego por palo? Necesitaría implementar la interfaz Comparator para especificar nuevos criterios de clasificación y utilice el método sort(List<T> list.*.El método compareTo hace que el método StandardDeck.getRank(). import java. Una manera de hacer esto es implementar la interfaz Comparator para especificar cómo desea las tarjetas ordenadas.util.value(). luego por traje: StandardDeck myDeck = new StandardDeck(). myDeck. El ejemplo SortByRankThenSuit hace esto: package defaultmethods. value() secondCard.value() secondCard.getRank sólo. Se ha mejorado la interfaz Comparator con esta capacidad con el método por defecto del thenComparing: myDeck.comparing((card) -> card. Se ha mejorado la interfaz Comparator con otras versiones del del método por defecto thenComparing (como thenComparingDouble y thenComparingLong) que permiten construir instancias Comparator que comparar otros tipos de datos.shuffle(). Por ejemplo. se puede utilizar una expresión lambda para especificar los criterios de ordenación: StandardDeck myDeck = new StandardDeck(). En este ejemplo. En particular. sería útil si sus desarrolladores podrían crear una instancia de Comparator que compara a cualquier objeto que puede devolver un valor numérico de un método getValue como hashCode. ¿cómo sería que ordenar la baraja de cartas primero por fila y luego por traje? Como antes. Sería más simple para sus desarrolladores si pudieran construir una instancia de Comparator de una serie de instancias de Comparator. la expresión lambda compara dos valores enteros. Esta invocación mejor demuestra que para ordenar en lugar de Cómo hacerlo.getRank())).sort( Comparator .getSuit(). Ha mejorado la interfaz Comparator con esta capacidad con el método estático comparing : myDeck.sort(Comparator.comparing(Card::getRank)). ¿cómo sería que ordenar la baraja de cartas primero por orden descendente de rango.sort(Comparator.comparing(Card::getSuit))).thenComparing(Comparator. Por ejemplo. Sería más simple para sus desarrolladores si podían crear una instancia de Comparator invocando el método Card. puede utilizar una expresión lambda como argumento para el método de sort. puede utilizar una Referencia de método en su lugar: myDeck. else return firstCard. secondCard) -> { int compare = firstCard.Porque la interfaz Comparator es una interfaz funcional.getRank(). Supongamos que sus desarrolladores le gustaría crear una instancia de Comparator que permite ordenar una colección de objetos en orden inverso. Supongamos que sus desarrolladores le gustaría crear una instancia de Comparator que podría comparar objetos con más de uno de los criterios. Se ha mejorado la interfaz Comparator con otras versiones del método estático comparing tales como comparingDouble y comparingLong que permiten crear instancias Comparator que comparar otros tipos de datos.sort( (firstCard.getSuit().value(). En este ejemplo. } ).getRank(). myDeck. myDeck.value(). if (compare != 0) return compare. desde el as hasta dos (en lugar de entre dos y .comparing(Card::getRank) . ¿Qué pasa con la siguiente interfaz? public interface SomethingIsWrong { void aMethod(int aValue){ System. y método referencias para crear métodos más expresivos de la biblioteca cuyos programadores de funcionalidad pueden deducir rápidamente mirando cómo ellos son invocados.println("Hi Mom").out. Este ejemplo muestra cómo se ha mejorado la interfaz Comparator con métodos predeterminados. 3. Arreglar la interfaz en la pregunta 2. El Nombre de una interfaz puede ser usado en cualquier lugar que se pueda usar un tipo. puede especificar otra expresión lambda. Se ha mejorado la interfaz Comparator con esta capacidad con el método de predeterminado reversed : myDeck.sort( Comparator.As)? Como antes. métodos estáticos.thenComparing(Comparator. Los únicos métodos que tienen implementaciones son por defecto y métodos estáticos. } } 2. Utilice estas construcciones para mejorar las interfaces en las bibliotecas. Supongamos que usted ha escrito un servidor de hora que notifica periódicamente a sus clientes la fecha y hora actual.comparing(Card::getSuit))). ¿Es válida la siguiente interfaz? public interface Marker { } Ejercicios 1. métodos estáticos y definiciones de constantes. .reversed() . Preguntas y ejercicios: Interfaces Preguntas 1. Una clase que implementa una interfaz debe implementar todos los métodos declarados en la interfaz.comparing(Card::getRank) . Escriba una interfaz que podría utilizar el servidor para cumplir un protocolo concreto con sus clientes. Sin embargo. sería más sencillo para los desarrolladores podrían revertir un Comparator de existente mediante la invocación de un método. métodos por defecto. Resumen de Interfaces Una declaración de interfaz puede contener firmas de métodos. expresiones lambda. clase extendida o clase de niño). así que ellos no se heredan de las subclases. En ausencia de cualquier otro superclase explícita. pero puede invocar el constructor de la superclase desde la subclase. La idea de la herencia es simple pero poderosa: cuando desea crear una nueva clase y ya hay una clase que incluye parte del código que usted quiere. Las clases cerca de la parte inferior de la jerarquía proporcionan un comportamiento más especializado. cada clase implícitamente es una subclase de Object.lang. Al hacer esto. Una subclase hereda todos los miembros (campos. puede derivar su nueva clase de la clase existente. formando una jerarquía de clases. Todas las clases en la plataforma Java son descendientes de Object En la parte superior de la jerarquía. las clases pueden ser derivadas de otras clases. usted puede reutilizar los campos y métodos de la clase existente sin tener que escribir (y depurar) los mismos. métodos y clases anidadas) de su superclase. Las clases se pueden derivar de las clases que se derivan de las clases que se derivan las clases y así sucesivamente y deriva en última instancia de la clase superior. La clase de la cual se deriva la subclase se llama una superclase (también una clase base o una clase padre). otras clases se derivan de algunas de esas clases y así sucesivamente. La jerarquía de clases de la plataforma Java La clase de Object. el cual no tiene ninguna superclase. Definiciones: Una clase que se deriva de otra clase se llama una subclase (también una clase derivada. . Object. Esa clase se dice que desciende de todas las clases en la cadena de herencia que se remontan a Objeto. definida en el paquete java. Con la excepción de Object. usted ha visto herencia mencionado varias veces. cada clase tiene sólo una superclase directa (herencia simple). el Object es la más general de todas las clases. Los constructores no son miembros. En la plataforma Java.Herencia En las lecciones anteriores. muchas clases se derivan directamente de Object. así heredar Campos y métodos de las clases. En el lenguaje Java. define e implementa el comportamiento común a todas las clases — incluyendo las que escribes. startSpeed. } public void speedUp(int increment) { speed += increment. int startSpeed. } public void applyBrake(int decrement) { speed -= decrement. seatHeight = startHeight. } public void setGear(int newValue) { gear = newValue. int gear. // the Bicycle class has one constructor public Bicycle(int startCadence. } // the Bicycle class has four methods public void setCadence(int newValue) { cadence = newValue. // la subclase MountainBike tiene un constructor public MountainBike(int startHeight. speed = startSpeed. } } . startGear). cadence = startCadence.Un ejemplo de herencia Aquí está el código de ejemplo para una posible implementación de una clase de Bicycle que se presentó en la lección de clases y objetos: public class Bicycle { // the public public public Bicycle class has three fields int cadence. int startCadence. int startSpeed. int startGear) { gear = startGear. int speed. } } Una declaración de clase para una clase MountainBike que es una subclase de la Bicycle podría verse así: public class MountainBike extends Bicycle { // la subclase MountainBike añade un campo public int seatHeight. } // la subclase MountainBike añade un método public void setHeight(int newValue) { seatHeight = newValue. int startGear) { super(startCadence. así reemplazar todo. MountainBike es descendiente de Bicycle y de Object. es como si hubieras escrito una nueva clase de MountainBike completamente desde cero. Se pueden declarar nuevos campos en la subclase que no estén en la superclase. también hereda a los miembros del paquete-privado de los padres. Los métodos heredados pueden ser utilizados directamente como son. Sin embargo. así sobreescribiendolo. al igual que cualquier otro campo. una MountainBike es un Bicycle y es también un Object. Puede declarar un campo en la subclase con el mismo nombre como el de la superclase. Del mismo modo. Una clase anidada tiene acceso a todos los miembros privados de su clase envolvente — ambos métodos y campos. si escribimos: public MountainBike myBike = new MountainBike(). Esto sería especialmente útil si los métodos de la clase Bicycle fueran complejos y hubieran tomado tiempo considerable para depurarse. Se pueden declarar nuevos métodos en la subclase que no estén en la superclase. Excepto por el constructor. Casting de Objetos Hemos visto que un objeto es del tipo de datos de la clase de la cual se ha instanciado. Miembros privados en una superclase Una subclase no hereda los miembros privados de su clase padre. Las secciones siguientes en esta lección se expandirán sobre estos temas. pero no lo es necesariamente. si la superclase tiene métodos públicos o protegidos para acceder a sus campos privados. un Object puede ser una Bicycle o una MountainBike. Puedes escribir un constructor de la subclase que invoca al constructor de la superclase. Sin embargo. pero no necesariamente. éstos también pueden ser utilizados por la subclase. implícita o mediante el uso de la palabra clave super. y puede ser utilizado dondequiera que se llame a objetos Bicycle u Object. Si la subclase está en el mismo paquete como su padre. Puede escribir un nuevo método estático en la subclase que tiene la misma firma como el de la superclase. así ocultandolo (no recomendado). Puede escribir un nuevo método de instancia de la subclase que tiene la misma firma como el de la superclase. no importa qué paquete es la subclase. Lo que se puede hacer en una subclase Una subclase hereda todos los miembros public y protected de su padre. Usted puede utilizar a los miembros heredados como están. Entonces myBike es de tipo MountainBike. Por lo tanto.MountainBike hereda todos los campos y métodos de Bicycle y agrega el campo seatHeight y un método para establecerlo. Por ejemplo. . reemplazarlos. ocultarlos o complementarlos con nuevos miembros:         Los campos heredados pueden utilizarse directamente. con campos de cuatro y cinco métodos. no tenías que hacer todo el trabajo. una clase anidada pública o protegida heredada por una subclase tiene acceso indirecto a todos los miembros privados de la superclase. La inversa no es necesariamente cierta: una Bicycle puede ser una MountainBike. Por lo tanto. Si. lo que no puedes hacer en las interfaces. por el contrario. se lanza una excepción. Nota: Puedes hacer una prueba lógica en cuanto al tipo de un objeto determinado utilizando el operador instanceof. que se definen en las clases. Por ejemplo. Además. Este cast inserta una comprobación en tiempo de ejecución de que obj es asignado a MountainBike para que el compilador pueda asumir con seguridad que obj es un MountainBike. Por ejemplo. Si obj no es un MountainBike en tiempo de ejecución. si escribimos: Object obj = new MountainBike(). usted puede crear instancias de una clase para crear un objeto. Sin embargo. que es la capacidad para heredar campos de varias clases. Los problemas que surgen con este tipo de herencia múltiple. } Aquí el operador instanceof verifica que obj se refiere a un MountainBike para que podamos hacer el cast con el conocimiento de que no habrá lanzamiento de excepción en tiempo de ejecución. la implementación y el tipo Una diferencia significativa entre las clases e interfaces es que las clases pueden tener campos mientras que las interfaces no pueden. La implementación de herencia múltiple es la capacidad de heredar las definiciones de métodos desde múltiples clases. Herencia múltiple de estado. obj es tanto un Object como un MountainBike (hasta el momento en que obj es asignado a otro objeto que no es un MountainBike). Esto se llama casting implícito. Como se explica en la sección ¿qué es un objeto?. un objeto almacena su estado en los campos. Una de las razones de por qué el lenguaje de programación Java no permite extender más de una clase es evitar los problemas de la herencia múltiple de estado.El Casting muestra el uso de un objeto de un tipo en lugar de otro tipo. Por ejemplo: if (obj instanceof MountainBike) { MountainBike myBike = (MountainBike)obj. ¿Qué pasa si los métodos o constructores de superclases diferentes son instanciados del mismo campo? ¿Qué método o constructor tendrá prioridad? Debido a que las interfaces no contienen campos. tendríamos un error de compilación porque obj no es conocido por el compilador para ser un MountainBike. . Cuando se crea un objeto instanciando la clase. escribimos MountainBike myBike = obj. supongamos que usted es capaz de definir una nueva clase que se extiende de varias clases. entre los objetos permitidos por la herencia y las implementaciones. podemos decirle al compilador que prometemos asignarle un MountainBike para obj por casting explícito: MountainBike myBike = (MountainBike)obj. ese objeto heredará campos de todas las superclases de la clase. usted no tiene que preocuparse acerca de los problemas que se derivan de la herencia múltiple de estado. Esto puede ahorrar un error en tiempo de ejecución debido a un cast inadecuado. Para obtener más información sobre @Override. vea Annotations. Esto significa que si una variable se declara como el tipo de una interfaz. el compilador detecta que el método no existe en una de las superclases. En este caso. El lenguaje de programación Java soporta herencia múltiple de tipo. El compilador de Java proporciona algunas reglas para determinar qué método predeterminado utiliza una clase en particular. Si por alguna razón. Además. El método sobreescrito tiene el mismo nombre. Los métodos por defecto introducen una forma de implementación de herencia múltiple.son tales como conflictos de nombres y ambigüedad. La capacidad de una subclase de sobreescribir un método permite que una clase herede de una superclase cuyo comportamiento es "lo suficientemente cerca" y luego modifique el comportamiento según sea necesario. Como con la implementación de la herencia múltiple. La versión del método estático hidden que se invoca depende de si se invoca de la superclase o la subclase. Examinemos un ejemplo que contiene dos clases. Sobreescribir y ocultar métodos Métodos de instancia Un método de instancia de una subclase con la misma firma (nombre. a veces no pueden determinar el miembro o método para acceder o invocar. Un método sobreescrito también puede devolver un subtipo del tipo devuelto por el método que lo sobreescribe. Una clase puede implementar más de una interfaz. La distinción entre ocultar un método estático y reemplazar o socreescribir un método de instancia tiene implicaciones importantes:   La versión del método de instancia overridden que se invoca es el de la subclase. Un objeto puede tener varios tipos: el tipo de su propia clase y los tipos de todas las interfaces que implementa la clase. Métodos estáticos Si una subclase define un método estático con la misma firma que un método estático en la superclase. entonces el método de la subclase oculta la de la superclase. Este subtipo se llama un tipo de retorno covariante. el compilador o el usuario deben decidir cuál usar. una clase puede heredar diferentes implementaciones de un método definido (como por defecto o estático) en las interfaces que extiende. Esto se discute en la sección utilizando una interfaz como un tipo. que es la capacidad de una clase para implementar más de una interfaz. número y tipo de parámetros y tipo de valor devuelto como el método que lo sobreescribe. tal vez quieras usar la anotación @Override que indica al compilador que pretende sobreescribir un método en la superclase. que puede contener métodos por defecto que tengan el mismo nombre. un programador puede introducir involuntariamente un conflicto de nombres mediante la adición de un nuevo método de una superclase. entonces se generará un error. que contiene un método de instancia y un método estático: . El primero es el Animal. más el número y el tipo de sus parámetros) y el tipo de retorno como un método de instancia en la superclase sobreescribe el método de la superclase. Cuando se sobreescribe un método. Cuando los compiladores de lenguajes que admiten este tipo de herencia múltiple de programación encuentran superclases que contienen métodos con el mismo nombre. entonces su valor puede hacer referencia a cualquier objeto que es instanciado desde cualquier clase que implemente la interfaz. public class Animal { public static void testClassMethod() { System. } public static void main(String[] args) { Cat myCat = new Cat(). } .testInstanceMethod().println("The instance method in Animal"). El método main en esta clase crea una instancia de Cat e invoca testClassMethod() en la clase y testInstanceMethod() en la instancia.".out. } public void testInstanceMethod() { System.println("The static method in Animal"). } } public interface Flyer { default public String identifyMyself() { return "I am able to fly.println("The instance method in Cat"). Considere las siguientes clases e interfaces: public class Horse { public String identifyMyself() { return "I am a horse. se llama Cat: public class Cat extends Animal { public static void testClassMethod() { System. Métodos de interfaz Los métodos por defecto y los métodos abstractos en interfaces son heredados como métodos de instancia. una subclase de Animal. } public void testInstanceMethod() { System. cuando los supertipos de una clase o interfaz proporcionan varios métodos por defecto con la misma firma. Animal. Estas reglas son conducidas por los siguientes dos principios:  Los métodos de instancia son preferidos sobre los métodos de interfaz por defecto. y la versión del método de instancia overridden que se invoca es el de la subclase. myAnimal.out. Animal myAnimal = myCat. } } La clase Cat reemplaza el método de instancia en Animal y esconde el método estático en Animal.out.out.".testClassMethod(). La salida de este programa es como sigue: The static method in Animal The instance method in Cat Como se prometió. el compilador de Java sigue las reglas de herencia para resolver el conflicto de nombres. la versión del método estático oculto que se invoca es el de la superclase. } } La segunda clase.println("The static method in Cat"). Sin embargo. } } El método Dragon.  Los métodos que ya están sobreescritos por otros candidatos son ignorados..identifyMyself devuelve la cadena I am a horse. default public int startEngine(EncryptedKey key) { // Implementation } } public interface FlyCar { // ..out. } } public interface FireBreather extends Animal { } public class Dragon implements EggLayer.identifyMyself devuelve la cadena I am able to lay eggs.. FireBreather { public static void main (String. o un método por defecto entran en conflicto con un método abstracto.out.identifyMyself()). Tiene dos interfaces (OperateCar y FlyCar) que proporciona implementaciones por defecto para el mismo método. } } El método Pegasus. System. Explícitamente debe sobreescribir los métodos del supertipo. System. default public int startEngine(EncryptedKey key) { // Implementation } } .". Si dos o más conflictos de métodos independientemente definidos por defecto. Mythical { public static void main(String...println(myApp.} public interface Mythical { default public String identifyMyself() { return "I am a mythical creature. } } public class Pegasus extends Horse implements Flyer.".println(myApp. args) { Pegasus myApp = new Pegasus().identifyMyself()). Esta circunstancia puede surgir cuando los supertipos comparten un ancestro común.". args) { Dragon myApp = new Dragon()... Considere el ejemplo de coches controlados por computadora que ahora pueden volar.. (startEngine): public interface OperateCar { // . entonces el compilador de Java produce un error del compilador. Considere las siguientes interfaces y clases: public interface Animal { default public String identifyMyself() { return "I am an animal. } } public interface EggLayer extends Animal { default public String identifyMyself() { return "I am able to lay eggs. ". un método de instancia protegido en la superclase puede hacerse público.. Por ejemplo. FlyCar { // . } public class Horse { public String identifyMyself() { return "I am a horse. Los métodos de instancia heredados de las clases pueden sobreescribir métodos de interfaz abstracta. Esta forma de invocación de método no se limita a diferenciar entre múltiples interfaces implementadas que contienen métodos por defecto con la misma firma.super. acceso que el método sobreescrito. Nota: nunca se heredan métodos estáticos en interfaces.identifyMyself devuelve la cadena I am a horse. } } El método Mustang. Considere las siguientes interfaces y clases: public interface Mammal { String identifyMyself(). public int startEngine(EncryptedKey key) { FlyCar. } } public class Mustang extends Horse implements Mammal { public static void main(String.identifyMyself()). args) { Mustang myApp = new Mustang(). Se podría invocar cualquiera de las implementaciones por defecto con la palabra clave super. Obtendrá un error de compilación si se intenta cambiar un método de instancia en la superclase a un método estático en la subclase y viceversa. } } El nombre anterior super (en este ejemplo.. en la subclase. Resumen La siguiente tabla resume lo que sucede cuando se define un método con la misma firma como un método en una superclase. System. que reemplaza el método abstracto del mismo nombre en la interfaz de Mammal.startEngine(key).. Modificadores El especificador de acceso para un método sobreescrito puede permitir más. pero no privado.startEngine(key). public class FlyingCar implements OperateCar.super. pero no menos. Definir un método con la misma firma como método de una superclase . OperateCar. Puede utilizar la palabra clave super para invocar un método por defecto en ambas.Una clase que implementa tanto OperateCar como FlyCar debe reemplazar el método startEngine.println(myApp..out. La clase Mustang hereda el método identifyMyself de la clase de Horse. FlyCar u OperateCar) debe hacer referencia a una superinterface directa que define o hereda un valor por defecto para el método invocado. clases e interfaces. } Para demostrar las características polimórficas en el lenguaje Java. únicos de la subclase. que es un valor String que indica si la moto tiene un amortiguador delantero. ").out.cadence + " and travelling at a speed of " + this. O. int startSpeed. . Por ejemplo. Las subclases de una clase pueden definir sus propios comportamientos únicos y aún compartir la misma funcionalidad de la clase padre. } public void setSuspension(String suspensionType) { this. int startGear.println("\nBike is " + "in gear " + this.gear + " with a cadence of " + this.suspension. Polimorfismo La definición del diccionario de polimorfismo se refiere a un principio de biología en el cual un organismo o especie puede tener muchas formas diferentes o etapas. Aquí está la clase actualizada: public class MountainBike extends Bicycle { private String suspension. Tales métodos sobrecargados ni ocultan ni sobreescriben los métodos de instancia de la superclase — son nuevos métodos. podría añadirse un método printDescription a la clase que muestra todos los datos almacenados actualmente en una instancia. Polimorfismo puede demostrarse con una pequeña modificación a la clase de Bicycle. Front. public void printDescription(){ System.speed + ". se pueden sobrecargar los métodos heredados de la superclase. Dual. Este principio puede aplicarse también a la programación orientada a objetos y lenguajes como el lenguaje Java. la moto tiene un amortiguador delantero y trasero. startSpeed. Para MountainBike. startGear). se agrega un campo para la suspension. String suspensionType){ super(startCadence.setSuspension(suspensionType).suspension = suspensionType. se extiende la clase Bicycle con una MountainBike y una clase RoadBike. } public String getSuspension(){ return this. public MountainBike( int startCadence. this.Método de instancia de la superclase Método de instancia de la subclase Método estático de la subclase Método estático de la superclase Sobreescribir Genera un error en tiempo de compilación Genera un error en tiempo de compilación Ocultar Nota: En una subclase. out. se muestra información sobre el ancho del neumático. se agrega un atributo para rastrear el ancho del neumático. } public void printDescription(){ super. Las dos subclases sobreescriben el método printDescription e imprimen información única."). el método printDescription ha sido sobreescrito. .tireWidth = newTireWidth. bike02. se incluye en la salida datos adicionales sobre la suspensión. Para resumir. A continuación. int startSpeed. } } Note una vez más.printDescription(). Aquí está la clase RoadBike: public class RoadBike extends Bicycle{ // In millimeters (mm) private int tireWidth."). System.printDescription(). Además de la información facilitada antes. System. int newTireWidth){ super(startCadence. public class TestBikes { public static void main(String[] args){ Bicycle bike01. cree la clase RoadBike. Aquí esta un programa de prueba que crea tres variables de Bicycle. } public int getTireWidth(){ return this. bike01 = new Bicycle(20.setTireWidth(newTireWidth). } public void setTireWidth(int newTireWidth){ this. Esta vez. this. startGear). public RoadBike(int startCadence. MountainBike y RoadBike. 1). Porque las bicicletas de carretera o de carreras tienen neumáticos delgados. bike03.tireWidth. Cada variable se asigna a una de las tres clases de bicicleta. } } Notese el método sobreescrito printDescription. hay tres clases: Bicycle.} public void printDescription() { super. Luego se imprime cada variable. int startGear. 10. startSpeed.out.println("The " + "MountainBike has a" + getSuspension() + " suspension.println("The RoadBike" + " has " + getTireWidth() + " MM tires. no es recomendable ocultar campos ya que hace difícil leer el código. que se cubre en la sección siguiente. llamada Subclass. En lugar de ello. incluso si sus tipos son diferentes. el campo debe accederse a través de super.out. Dentro de la subclase. Bike is in gear 5 with a cadence of 20 and travelling at a speed of 10. Usando la palabra clave super Acceso a miembros de la superclase Si tu método sobreescribe uno de los métodos de su superclase.printDescription(). } } Aquí está una subclase. bike03. 8. También puede utilizar super para referirse a un campo oculto (aunque ocultar campos se desaconseja). Considere esta clase. . "Dual"). La Java virtual machine (JVM) llama al método adecuado para el objeto al que se hace referencia en cada variable. The MountainBike has a Dual suspension.println("Printed in Superclass. 5. The RoadBike has 23 MM tires. 10. que reemplaza a printMethod(): public class Subclass extends Superclass { // sobreescribe printMethod en Superclass public void printMethod() { super. 23).bike02 = new MountainBike(20. bike01. un campo que tiene el mismo nombre que un campo de la superclase oculta el campo de la superclase. Este comportamiento se conoce como invocación de método virtual y muestra un aspecto de las características importantes del polimorfismo en el lenguaje Java.printDescription(). Bike is in gear 8 with a cadence of 40 and travelling at a speed of 20. Ocultar campos Dentro de una clase. 20.printMethod().printDescription(). En términos generales. el campo de la superclase no puede ser referenciado por su nombre simple. bike02."). bike03 = new RoadBike(40. No llama al método que esta definido por el tipo de la variable. puede invocar el método sobreescrito mediante el uso de la palabra clave super. Superclass: public class Superclass { public void printMethod() { System. } } La salida del programa de prueba es el siguiente: Bike is in gear 1 with a cadence of 20 and travelling at a speed of 10. s. startSpeed. Así que. no hay problema. se llama al constructor sin-argumentos de la superclase. } La invocación de un constructor de la superclase debe ser la primera línea en el constructor de la subclase. el nombre simple printMethod() se refiere al declarado en la Subclass.out.System. Printed in Subclass Los constructores de la subclase El ejemplo siguiente muestra cómo utilizar la palabra clave super para invocar un constructor de una superclase. todo el camino de regreso al constructor de Object. La sintaxis para llamar a un constructor de la superclase super(). este es el caso. Al compilar y ejecutar Subclass imprime lo siguiente: Printed in Superclass. Object tiene un constructor. startGear). para hacer referencia a printMethod() heredado de la Superclass. se llama al constructor de la superclase con una lista de parámetros coincidentes. ya sea explícita o implícitamente. que sobreescribe en la Superclass. el compilador de Java inserta automáticamente una llamada al constructor sin-argumentos de la superclase. int startGear) { super(startCadence. Si la clase super no tiene un constructor sin-argumentos. De hecho.printMethod(). } public static void main(String[] args) { Subclass s = new Subclass(). se podría pensar que habrá toda una cadena de constructores llamados. Recordemos del ejemplo de Bicycle que MountainBike es una subclase de Bicycle. Este es el constructor de MountainBike (subclase) que llama al constructor de la superclase y a continuación agrega su propio código de inicialización: public MountainBike(int startHeight. seatHeight = startHeight. Con super(parameter list). Si un constructor de la subclase invoca un constructor de su superclase. o: super(parameter list). Nota: Si un constructor no invoca explícitamente a un constructor de superclase. Se le llama encadenamiento del constructor. . int startCadence. y tienes que ser consciente de ello cuando hay una larga línea de descenso de clase. Subclass debe utilizar un nombre cualificado.println("Printed in Subclass"). Con super(). int startSpeed. obtendrá un error en tiempo de compilación. } } Dentro de Subclass. así que si Object es la única superclase. usando super como se muestra. Objeto como una superclase La clase de Object. puede que necesites sobreescribirlos con código específico en tu clase. usted puede utilizar el método clone() para crear una copia de un objeto existente. notifyAll y wait todos juegan un papel en la sincronización de las actividades de los subprocesos que se ejecutan de forma independiente en un programa. de la clase Object. o una de sus superclases. La implementación de Object en este método comprueba si el objeto sobre el que se invocó clone() implementa la interfaz Cloneable . No necesitas utilizar cualquiera de estos métodos. Cada clase es un descendiente.clone(). tienes que saber que clone() deben ser declarado como protected Object clone() throws CloneNotSupportedException o: public Object clone() throws CloneNotSupportedException . Cada clase que utilizas o escribes hereda los métodos de instancia de Object. implementa la interfaz Cloneable. que se discute en una lección posterior y no se cubre aquí. pero si decides hacerlo. especialmente el método clone. Si el objeto no lo hace. Los métodos heredados de Object que se describen en esta sección son:       protected Object clone() throws CloneNotSupportedException Crea y devuelve una copia de este objeto. El manejo de excepciones será cubierto en una lección posterior. Por el momento. Para crear un clon. int nanos) Nota: Hay algunos aspectos sutiles a un número de estos métodos. el método produce una excepción CloneNotSupportedException. Hay cinco de estos métodos:      public public public public public final final final final final void void void void void notify() notifyAll() wait() wait(long timeout) wait(long timeout. Los métodos de Object: notify. public boolean equals(Object obj) Indica si algún otro objeto es "igual a" éste.lang. escribe: aCloneableObject. se situa en la parte superior del árbol de la jerarquía de clase. El método clone() Si una clase. protected void finalize() throws Throwable Llamado por el recolector de basura en un objeto cuando el recolector de basura determina que no existen más referencias al objeto public final Class getClass() Devuelve la clase runtime de un objeto. en el paquete java. directo o indirecto. public int hashCode() Devuelve un valor de código hash para el objeto. public String toString() Devuelve una representación de cadena del objeto. El método equals() El método equals() compara dos objetos para igualdad y devuelve true si son iguales. Para tipos de datos primitivos.Si vas a escribir un método clone() para sobreescribir el de Object. si los objetos comparados son el mismo objeto exacto.equals((Book)obj. Para los objetos.getISBN()). else return false. } Este programa muestra objects are equal aunque firstBook y secondBook referencia a dos objetos distintos. no lo hace. para que el objeto y su clon sean verdaderamente independientes. . Para comprobar si dos objetos son iguales en el sentido de equivalencia (que contengan la misma información). Se consideran iguales porque los objetos comparados contienen el mismo número de ISBN. a continuación. } } Considere este código prueba dos instancias de la clase Book para igualdad: // Swing Tutorial. if (firstBook. El método equals() proporcionado en la clase de Object utiliza el operador de identidad (==) para determinar si dos objetos son iguales. Sin embargo.out.println("objects are not equal"). } else { System. Entonces el objeto original hace referencia a ObjExternal y el clon hace referencia a un clon de ObjExternal. De lo contrario.out. Esto significa que el objeto original y su clon no son independientes — para desvincularlos. debe sobreescribir clone() así que clona el objeto y ObjExternal. El método equals() proporcionado por Object prueba si las referencias de objeto son iguales — es decir. es necesario reemplazar el método equals().equals(secondBook)) { System. La forma más sencilla de hacer tu clase clonable es agregar implements Cloneable a la declaración de la clase.println("objects are equal"). 2nd edition Book firstBook = new Book("0201914670"). un cambio en ObjExternal de un objeto será visible en su clon también. el comportamiento por defecto del método clone() de Object funciona muy bien. Book secondBook = new Book("0201914670"). Para algunas clases. Si el objeto sobre el que se invocó clone() implementa la interfaz Cloneable . public boolean equals(Object obj) { if (obj instanceof Book) return ISBN.. Aquí hay un ejemplo de una clase de Book que reemplaza equals(): public class Book { . esto da el resultado correcto. los objetos pueden invocar el método clone(). es decir ObjExternal. si un objeto contiene una referencia a un objeto externo. sin embargo.. la implementación de Object del método clone() crea un objeto de la misma clase que el objeto original e inicializa las variables miembro del nuevo objeto para tener los mismos valores que las variables miembro correspondiente del objeto original. necesitará sobreescribir clone() para obtener el comportamiento correcto. cambia la forma en que se comparan dos objetos y la implementación de Object del hashCode() ya no es válida. es incierto. El método finalize()puede ser llamado automáticamente por el sistema.getClass(). Por definición. el siguiente método obtiene y muestra el nombre de clase de un objeto: void printClassName(Object obj) { System.getSimpleName()).Siempre debe sobreescribir el método equals() si el operador de identidad no es el apropiado para su clase. Por ejemplo. que es la dirección de memoria del objeto en hexadecimal. Por ejemplo.out. este puede ser invocado por un objeto cuando se convierte en basura. también debe reemplazar el método hashCode(). Por ejemplo. El método finalize() La clase Object proporciona un método de devolución de llamada. } La clase Class en el paquete java. Si reemplaza el método equals(). es posible que se quede sin descriptores de archivos. El método getClass() Usted no puede sobreescribir getClass. . Nota: Si sobreescribe equals(). finalize(). o incluso si se llama. Usted puede ver lo que los campos del objeto (getFields()) o lo que sus métodos son (getMethods()) y así sucesivamente. pero cuando se llama. El método hashCode() El valor devuelto por hashCode() es código hash del objeto. Por lo tanto. no debe confiar en este método para hacer la limpieza por usted. como su nombre (getSimpleName()). como liberando recursos. si dos objetos son iguales. su superclase (getSuperclass()) y las interfaces que implementa (getInterfaces()). que tiene métodos que puede utilizar para obtener información acerca de la clase. una interfaz (isInterface()) o una enumeración (isEnum()).lang. deberá sobreescribir hashCode() también.println("The object's" + " class is " + obj. tiene un gran número de métodos (más de 50). El método toString() Siempre debe considerar sobreescribir el método toString() en sus clases. sus códigos hash también deben ser iguales. Por lo tanto. se puede probar para ver si la clase es una anotación (isAnnotation()). El método getClass() devuelve un objeto Class . si reemplaza el método equals() . si no cierra los descriptores de ficheros en el código después de realizar la I/O y esperas finalize() para cerrarlas por usted. La implementación de Object de finalize() no hace nada — puede sobreescribir finalize() para hacer limpieza. así: abstract void moveTo(double deltaX. como una instancia de Book: System. Un método abstracto es un método que se ha declarado sin una implementación (sin llaves y seguido por un punto y coma). Una clase que se declara final no puede tener subclases... Esto es particularmente útil. Por ejemplo.El método toString() del Object devuelve una representación de String del objeto. Que seria. double deltaY). La clase Object hace esto — un número de sus métodos son final. que es muy útil para la depuración. como esto: ISBN: 0201914670. final ChessPlayer getFirstPlayer() { return ChessPlayer.out.println(firstBook. Puede utilizar toString() junto con System. Use la palabra final en una declaración de método para indicar que el método no puede ser sobreescrito por las subclases.. para un método toString() sobreescrito apropiadamente. } . pero pueden tener subclases. una subclase puede redefinir el método con resultados sorpresivos o indeseables. por eso tienes que sobreescribir toString() en tus clases. Si una clase incluye métodos abstractos. 2nd Edition Escribir clases y métodos finales Se pueden declarar algunos o todos los métodos de una clase final. luego la propia clase debe ser declarada abstract. podrías querer hacer final el método getFirstPlayer en esta clase ChessAlgorithm : class ChessAlgorithm { enum ChessPlayer { WHITE. por ejemplo. Si un constructor llama a un método no-final. Tal vez desea hacer un método final si tiene una implementación que no debe ser cambiada y es fundamental para el estado consistente del objeto. Clases y métodos abstractos Una clase abstracta es una clase que se declara abstract— puede o no incluir métodos abstractos.. Tenga en cuenta que también puede declarar una clase completa final. Las clases abstractas no pueden ser instanciadas. cuando se crea una clase inmutable como la clase String. } Los métodos llamados desde los constructores generalmente deben declararse como finales.out.WHITE. The Swing Tutorial.toString()). BLACK } .println() para mostrar una representación de un objeto. como en: . imprime algo útil. La representación de String de un objeto depende del objeto. A Guide to Constructing GUIs. que forma parte de las Colecciones. se puede deducir que una instancia de HashMap (independientemente del desarrollador o empresa que implementa la clase) pueden ser clonados. si alguna de estas afirmaciones se aplican a su situación: o o o  ¿Quieres compartir código entre varias clases estrechamente relacionadas? Esperas que las clases que extienden de la clase abstracta tengan muchos campos o métodos comunes. sea o no abstracta. . con las clases abstractas. V>. ¿Quieres tomar ventaja de la herencia múltiple de tipo? Un ejemplo de una clase abstracta en el JDK es AbstractMap. Un ejemplo de una clase en el JDK que implementa varias interfaces es HashMap. puede declarar campos que no son estáticos y finales y definir métodos concretos públicos. es serializable (lo que significa que puede ser convertido en un byte corriente. todos los campos son automáticamente públicos. Nota: Los métodos de una interfaz (véase la sección Interfaces ) que no se declararon como por defecto o estáticos son implícitamente abstractos. Además. ¿Que debería utilizar. Por ejemplo. (Puede ser utilizado. o requieren modificadores de acceso que no sean públicos (como protegido y privado). Con las interfaces. pero es innecesario). } Cuando una clase abstracta tiene subclases. Al leer esta lista de interfaces. Cloneable y Map<K. privados y protegidos. y pueden contener una mezcla de métodos declarados con o sin implementación. Sin embargo. considerando que puede implementar cualquier número de interfaces. Considere el uso de interfaces si alguna de estas afirmaciones se aplican a su situación: o o o Espera que las clases no-relacionadas pudieran implementar su interfaz. y todos los métodos que se declaran o definen (como los métodos por defecto) son públicos. Quieres especificar el comportamiento de un tipo particular de datos.public abstract class GraphicObject { // campos declarados // métodos no-abstractos declarados abstract void draw(). estáticos y finales. si no es así. Sus subclases (que incluyen HashMap. Sin embargo. y tiene la funcionalidad de un mapa. vea la sección Objetos serializables). V> con muchos métodos por defecto como merge y forEach que no tienen clases mayores que han implementado esta interfaz para definir. TreeMap y ConcurrentHashMap) comparten muchos métodos get que define AbstractMap. Las clases abstractas en comparación con las Interfaces Las clases abstractas son similares a las interfaces. la subclase generalmente proporciona implementaciones de todos los métodos abstractos de su clase padre. No se pueden crear instancias de ellas. las interfaces Comparable y Cloneable son implementadas por muchas clases no-relacionadas. así que no se utiliza el modificador abstract con los métodos de la interfaz. Además. entonces la subclase debe también ser declarada abstract. pero no esta preocupado por quién implementa su comportamiento. clases abstractas o interfaces?  Considere el uso de las clases abstractas. se puede extender una sola clase. ¿Quieres declarar campos no estáticos o no finales? Esto le permite definir métodos que pueden acceder y modificar el estado del objeto al que pertenecen. se ha mejorado la interfaz de Map<K. que implementa las interfaces Serializable. Esta es una situación perfecta para una superclase abstracta. líneas. rectángulos. } abstract void draw(). rotar.. GraphicObject. } void resize() { . } . Todos estos objetos tienen ciertos Estados (por ejemplo: posición. . Sólo se diferencian en cómo lo hacen.. } void resize() { .. Un ejemplo de clase abstracta En una aplicación de dibujo orientado a objetos. color de línea. cambiar el tamaño o dibujar)... color de relleno) y comportamientos (por ejemplo: moveTo. color de relleno y moveTo). } Cada subclase nonabstract de GraphicObject. curva y rectángulo heredan de GraphicObject En primer lugar. y. la clase HashMap implementa varias interfaces y también extiende la clase abstracta AbstractMap. } } class Rectangle extends GraphicObject { void draw() { .. int newY) { . como el Circle y el Rectangle. void moveTo(int newX. tales como la posición actual y el método moveTo. orientación. puede dibujar círculos..Tenga en cuenta que muchas bibliotecas de software utilizan tanto las clases abstractas como las interfaces. Usted puede tomar ventaja de las similitudes y declarar todos los objetos gráficos que hereda el mismo objeto abstracto (por ejemplo. como draw o resize. debe proporcionar implementaciones para los métodos de draw y resize: class Circle extends GraphicObject { void draw() { . que deben aplicarse todas las subclases. redimensionar.. dibujar) en común. pero debe implementarse de diferentes maneras... La clase de GraphicObject puede ser algo así: abstract class GraphicObject { int x. se declara una clase abstracta. abstract void resize(). para proporcionar las variables miembro y métodos que son totalmente compartidos por todas las subclases. Algunos de estos Estados y comportamientos son los mismos para todos los objetos gráficos (por ejemplo: posición.. línea. GraphicObject también declara métodos abstractos para métodos. curvas Bezier y muchos otros objetos gráficos. Las clases Círculo. GraphicObject) como se muestra en en la siguiente figura. Todos los GraphicObject deben ser capaces de dibujar o cambiar el tamaño de ellos mismos.. Otros requieren diferentes implementaciones (por ejemplo. directa o indirecta.} Cuando una clase abstracta implementa una interfaz En la sección de Interfaces. implementar Y. Puede evitar que una clase de ser subclases mediante la palabra clave final en declaración de la clase. equals(). abstract class X implements Y { // implements all but one method of Y } class XX extends X { // implements the remaining method in Y } En este caso. Puede utilizar a estos miembros estáticos con una referencia de la clase (por ejemplo. siempre que la clase se declara ser abstract. se observó que una clase que implementa una interfaz debe implementar todos los métodos de la interfaz. Una subclase puede reemplazar métodos que hereda. Una clase hereda campos y métodos de todos sus superclases. Resumen de la herencia Con excepción de la clase de Object . Una clase abstracta puede solamente ser subclases. (Nota que ocultar campos es generalmente mala práctica de programación. porque de hecho. Por ejemplo. Es posible. la clase XX . puede impedir que un método siendo reemplazadas por las subclases declarándola como forma final. Preguntas y ejercicios: herencia Preguntas 1. sin embargo. o pueden ocultar campos o métodos que hereda. Todas las clases son descendientes de esta clase y heredan los métodos. clone()y getClass(). No puede ser instanciada. una clase tiene exactamente una superclase directa. clase X debe ser abstract no implementa completamente Y. Métodos útiles heredados de Object incluyen toString(). Asimismo. Miembros de la clase Una clase abstracta puede tener campos static y métodos static.staticMethod()) como lo haría con cualquier otra clase. Una clase abstracta puede contener métodos abstractos — métodos que son declarados pero no implementados. AbstractClass. La clase de Object es la parte superior de la jerarquía de clases.) La tabla en sección de anulación y ocultar métodos muestra el efecto de declarar un método con la misma firma que un método de la superclase. para definir una clase que no implementa todos los métodos de la interfaz. considere las siguientes dos clases: public class ClassA { . Subclases proporcionan las implementaciones de los métodos abstractos. sus subclases y las situaciones donde se usaría instancias de estas clases en lugar de los tipos primitivos de número. Además. esta sección habla de otras clases que deben trabajar con números. En particular. En el lenguaje de programación Java. son una secuencia de caracteres. Esta sección presenta también las clases de PrintStream y DecimalFormat. ¿Qué hacen los otros métodos? Lección: Números y cadenas Números Esta sección comienza con una discusión de la clase Number (en el paquete java.lang. funciones exponenciales y así sucesivamente.lang) y sus subclases. hay una discusión sobre autoboxing y unboxing. Esta clase tiene métodos para las funciones trigonométricas. esta sección habla sobre las situaciones donde se usaría instancias de estas clases en lugar de los tipos de datos primitivos. Finalmente.lang. También compara las clases String y StringBuilder. Números Esta sección comienza con una discusión sobre el Number de clase en el paquete java. . una característica del compilador que simplifica su código. tales como el formato o el uso de funciones matemáticas para complementar los operadores incorporados en la lengua. que son ampliamente utilizadas en programación Java. Por último. las strings son objetos. Esta sección describe cómo utilizar la clase String para crear y manipular cadenas. ¿Qué método oculta un método en la superclase? c. que proporciona métodos para escribir con formato de salida numérica. ¿Qué método sobreescribe un método en la superclase? b.public } public } public } public } void methodOne(int i) { void methodTwo(int i) { static void methodThree(int i) { static void methodFour(int i) { } public class ClassB extends ClassA { public static void methodOne(int i) { } public void methodTwo(int i) { } public void methodThree(int i) { } public static void methodFour(int i) { } } a. se discute la clase de Math en java. Contiene las funciones matemáticas para complementar los operadores incorporados en la lengua. Strings Las strings. y la plataforma Java proporciona clases contenedoras para cada uno de los tipos de datos primitivos. que proporcionan los límites superiores e inferiores del tipo de datos. octal. La tabla siguiente enumeran los métodos de instancia que implementan todas las subclases de la clase de Number. el compilador unboxes el objeto para ti. Sin embargo. Como argumento de un método que espera un objeto (a menudo usado al manipular colecciones de números). byte mask = 0xff. A menudo. 3. si utilizas un primitivo donde se espera un objeto. hexadecimal. BigDecimal y BigInteger se utilizan para los cálculos de alta precisión. Para utilizar métodos de la clase para convertir valores de a y de otros tipos primitivos. . Para obtener más información. float gpa = 3. Para utilizar constantes definidas por la clase. Hay tres razones que puede utilizar un objeto Number en lugar de una primitiva: 1. binario). el compilador cajas la primitiva en su envoltorio clase para usted. para convertir a y desde las cuerdas y para convertir entre sistemas de numeración (decimal. la mayoría del tiempo utilizas los tipos primitivos en el código. hay razones para usar objetos en lugar de primitivos. vea Autoboxing y Unboxing Todas las clases contenedoras numéricos son subclases de la clase abstracta Number: Nota: Hay cuatro otras subclases de Number que no se discuten aquí. 2. Similarmente. Por ejemplo: int i = 500. la envoltura se realiza por el compilador.65f.Las clases de números Cuando se trabaja con números. Estas clases "envuelven" la primitiva en un objeto. si utilizas un objeto number cuando un hombre primitivo y se espera. como MIN_VALUE y MAX_VALUE. AtomicInteger y AtomicLong se utilizan para aplicaciones de subprocesos múltiples. Métodos implementada por todas las subclases de número Método byte byteValue() short shortValue() int intValue() long longValue() float floatValue() double doubleValue() Descripción Convierte el valor de este objeto Number al tipo de datos primitivo volvió. static int parseInt(String s. Cada clase Number contiene otros métodos que son útiles para la conversión de números y de las cadenas y para convertir entre sistemas de numeración. boolean equals(Object obj) Determina si este objeto number es igual al argumento. Por ejemplo. . String toString() Devuelve un objeto String que representa el valor de este Integer. Los métodos de devuelven true si el argumento no es null y es un objeto del mismo tipo y con el mismo valor numérico. clase Integer Método Descripción static Integer decode(String s) Descodifica una cadena en un entero. analizada con el valor de raíz. el método devuelve el equivalente de base diez entero del número octal 333. static int parseInt(String s) Devuelve un entero (decimal solamente). dada una representación de cadena del decimal. si s = "333" y radix = 8. static Integer valueOf(String s. static String toString(int i) Devuelve un objeto String que representa el entero especificado. Puede aceptar representaciones de cadena de números decimales. 2. static Integer valueOf(int i) Devuelve un objeto Integer sosteniendo el valor de lo primitivo especificado. octales o hexadecimales como entrada. int radix) Devuelve un objeto Integer sosteniendo el valor entero de la representación de la cadena especificada. int radix) Devuelve un entero. Métodos para las otras subclases de Number son similares: Métodos de conversión. Hay algunos requisitos adicionales para el Double y Float los objetos que se describen en la documentación de la API de Java. octal o hexadecimal (radix equivale a 10. 8 o 16 respectivamente) números como entrada. La tabla siguiente enumera estos métodos en la clase Integer . static Integer valueOf(String s) Devuelve un objeto Integer sosteniendo el valor de la representación de cadena especificado.int compareTo(Byte anotherByte) int compareTo(Double anotherDouble) int compareTo(Float anotherFloat) int compareTo(Integer anotherInteger) int compareTo(Long anotherLong) int compareTo(Short anotherShort) Compara el objeto de este Number a la discusión. binario. que son caracteres especiales que los argumentos del Object. puede utilizar format o printf en cualquier lugar en el código donde has previamente usado print o println. El familiar System. format y printf. Cada uno tiene una versión con la siguiente sintaxis: public PrintStream format(Locale l. i). que le permiten ejercer mucho más control sobre su salida de la impresión cuando se incluyen números. Estos métodos.. System. así que usted puede invocar métodos de PrintStream en System. documentadas en java.).. puede utilizar estos métodos para imprimir una mezcla arbitraria de cadenas y números. banderas y especificadores. format. es una cadena de formato especifica cómo los objetos en el segundo parámetro. (La notación Object. args se llama varargs. El lenguaje de programación Java tiene otros métodos. Especificadores de formato comienzan con un signo de porcentaje (%) y terminan con un convertidor..io. stringVar).out.format("The value of i is: %d%n". El convertidor es un personaje que indica el tipo de argumento para ser formateado... La salida es: The value of i is: 461012 Los métodos printf y format están sobrecargados..format("The value of " + "the float variable is " + "%f.out. Por ejemplo. floatVar. Por lo tanto. " + "and the string is %s". La sintaxis de estos dos métodos de java. Los métodos printf y formato El paquete java. Existen muchos conversores.out. args. System...out que usted ha estado usando pasa a ser un objeto de PrintStream . La cadena de formato contiene texto así como especificadores de formato. args) .Formato de impresión numérica Antes que viste el uso de los métodos print y println para impresión cuerdas a la salida estándar (System.out.. son ser formateado. Entre el signo de porcentaje (%) y el convertidor puedes tener especificadores y banderas opcionales.io incluye una clase de PrintStream que tiene dos métodos de formato que se pueden utilizar para reemplazar a print y println. El %d especifica que la única variable es un entero decimal.. El primer parámetro.util. args) donde el format es una cadena que especifica el formato para ser utilizado y args es una lista de las variables a imprimir utilizando ese formato.Formatter Aquí está un ejemplo básico: int i = 461012.out).. que significa que puede variar el número de argumentos). equivalen a uno al otro. intVar. sin embargo. Un ejemplo sencillo sería System.format(.PrintStream es la misma: public PrintStream format(String format. while the value of the " + "integer variable is %d. Object. El %n es un caracter independiente de la plataforma. Ya que todos números pueden convertirse en cadenas (como se verá más adelante en esta lección). String format. Object.. argsdel formato. intVar.format(Locale. and the string is %s%n". while the " + "value of the integer variable " + "is %d. TP Una conversión de fecha y hora — locale específico am/pm (en minúsculas).java.Para imprimir números en el sistema francés (donde se utiliza una coma en lugar de la posición decimal en la representación inglesa de números de coma flotante). TM Una conversión de fecha y hora — meses en 2 dígitos. TL Una conversión de fecha y hora: hora en el reloj de 12 horas.java Convertidor Bandera Explicación d Un entero decimal. con los principales ceros como sea necesario.FRANCE. nombre completo locale específico del mes. + Incluye la señal. n Un nuevo personaje de línea correspondiente a la plataforma de ejecución de la aplicación. Ty tY Una conversión de fecha y hora — ty = año de 2 dígitos. . tD Una conversión de fecha y hora — fecha como % tm % td % ty 08 Ocho caracteres de ancho. Incluye caracteres de agrupación local específico. "The value of the float " + "variable is %f.out. TD. stringVar). floatVar. ya sea positiva o negativa. utilice: System. Siempre debe usar %n. en lugar de \n. tB Una conversión de fecha y hora. tY = año de 4 dígitos. no te. f Un flotador. Un ejemplo La tabla siguiente enumeran algunos de los convertidores y banderas que se utilizan en el programa de la muestra. Convertidores y banderas utilizadas en TestFormat. . con los principales ceros como sea necesario. con los principales ceros como sea necesario. TestFormat. por ejemplo. TD tiene llevando ceros como sea necesario. te Una conversión de fecha y hora: día 2 dígitos del mes. tM Una conversión de fecha y hora: minutos en 2 dígitos. que sigue en la tabla. // --> "3.out.out. c. // --> System.util.3 Tres lugares después del punto decimal.8d%n". en la página de "Formato".format("%+.text. System..FRANCE. c.3f%n". // --> "+461. // --> " +461012" System. %tY%n".format("%10. pi). public class TestFormat { public static void main(String[] args) { long n = 461012.8d%n%n".out. // --> "May 29.format("%tD%n".format("%-10. n). // --> System.format(Locale. bien justificada. c). "%-10. pi). n).format("%.out.Calendar. separadores de agrupación (miles) y el separador de decimales. La clase DecimalFormat Usted puede utilizar la clase java. n).out.out. Utilizando String. // --> "461012" System.4f%n%n". "2:34 am" 2006" System. que . El ejemplo siguiente crea un objeto DecimalFormat .out. El siguiente programa muestra algunos de los que puedes hacer con formatformato.out. pi). pi).format y para crear cadenas está cubierto de cadenas. generando una cadena de patrón para el constructor DecimalFormat .3 Diez caracteres de ancho.format("%tl:%tM %tp%n". System. La salida se muestra dentro de comillas dobles en el comentario incrustado: import java.format("%f%n". con tres lugares después del punto decimal.012" double pi = Math.util. // --> System. Luego se invoca el método format() .out.- Justifica a la izquierda.format("%+8d%n". // --> "00461012" System. // --> System.Locale. n). .PI.out.out.format("%08d%n". c. n).getInstance().DecimalFormat para controlar la visualización de iniciales y ceros.142" "3. System.1416" Calendar c = Calendar.012" System. myFormatter.142" "3.141593" "3. pero puede hacer más compleja su código.3f%n". pi). Más detalles pueden encontrarse en la sección de Basic I/O del camino esencial. c). // --> " 461.3f%n". DecimalFormat ofrece una gran flexibilidad en el formato de números.out. prefijos y sufijos. c.format("%tB %te. c).out.. System.format("%d%n". import java. // --> // --> "05/29/06" } } Nota: La discusión en esta sección cubre sólo los conceptos básicos de los métodos de format y printf .142" " 3.format("%. 10. ### 123.out. 123456. la coma es un marcador de posición para el separador de la agrupación y el período es un marcador de posición para el separador decimal.*.789 ###.67).780 El pattern especifica iniciales y ceros.format(value).## 123456.79 123.###". 123456.000". } static public void main(String[] args) { customFormat("###.### $12. Tenga en cuenta que precede inmediatamente el dígito más a la izquierda en el formato de output.67 La siguiente tabla explica cada línea de salida.###.###".789 ###.78 000000.789). public class DecimalFormatDemo { static public void customFormat(String pattern.345.## 123456.78 000000.###.000 000123.println(value + " " + pattern + " " + output). System.DecimalFormat hereda de NumberFormat.###. String output = myFormatter.###.67 $###.789 ###.789). $12. 123. 123.456. 12345. customFormat("$###.345.text.000 000123.### 123. Salida DecimalFormat. porque el carácter 0 se utiliza en lugar del signo de número (#). double value ) { DecimalFormat myFormatter = new DecimalFormat(pattern).67 El primer personaje en el pattern es el signo de dólar ($).###. customFormat("###. 12345. pero el pattern tiene sólo dos.789 123456. El método de format maneja esto por redondeo. } } La salida es: 123456. customFormat("000000.java Valor Patrón Salida Explicación 123456.##".456.789 ###. 123456. por myFormatter— acepta un valor double como argumento y devuelve el número con formato en una cadena: Aquí es un programa de ejemplo que ilustra el uso de DecimalFormat: import java.780 12345.###.67 $###.### Más allá de la aritmética básica .79 El value tiene tres dígitos a la derecha del punto decimal.789 El signo de número (#) denota un dígito.78). PI. Esto le permite invocar los métodos de la clase de Math por sus nombres. float arg2) int min(int arg1. . La tabla siguiente enumera una serie de los métodos básicos.E. no tienes que escribir Math frente a todas las funciones matemáticas: import static java. cual es la proporción de la circunferencia de un círculo y su diámetro. Nota: Mediante la función de lengua static import .lang. y Math. double floor(double d) Devuelve el entero más grande que sea menor o igual al argumento. así: Math.Math. / y %. a la discusión. Volvió como un doble. Constantes y métodos básicos La clase de Math incluye dos constantes:   Math. double rint(double d) Devuelve el número entero más cercano en el valor del argumento. La clase de Math en el paquete java. según lo indicado por el tipo de retorno del método. así se llaman directamente de la clase. double arg2) float min(float arg1. que es la base de los logaritmos naturales.lang proporciona métodos y constantes para hacer el cálculo matemático más avanzado.El lenguaje de programación Java soporta aritmética básica con sus operadores aritméticos: +. La clase de Math también incluye más de 40 métodos estáticos. int arg2) long min(long arg1. double min(double arg1. long round(double d) int round(float f) Devuelve el más cercano larga o int. Volvió como un doble. long arg2) Devuelve el menor de los dos argumentos. -. Volvió como un doble.cos(angle). Métodos básicos de matemáticas Método Descripción double abs(double d) float abs(float f) int abs(int i) long abs(long lng) Devuelve el valor absoluto del argumento. double ceil(double d) Devuelve el entero más pequeño que es mayor o igual que el argumento. *.*. Los métodos en la clase de Math son todo estáticos. Por ejemplo: cos(angle). out.0f%n".635 is 191.out. System. double b = 43.2f is %. El siguiente programa. int c = 16.printf("The ceiling of " + "%.printf("The max of %d and " + "%d is %d%n". d = 45. long arg2) Descripción Devuelve el mayor de los dos argumentos.rint(b)).abs(a)). b. BasicMathDemo .out.ceil(b)). float arg2) int max(int arg1. b.printf("The floor of " + "%. ilustra cómo utilizar algunos de estos métodos: public class BasicMathDemo { public static void main(String[] args) { double a = -191.635 ceiling of 43.0f%n". System. d)).Métodos básicos de matemáticas Método double max(double arg1. b.out.printf("The rint of %.out.out. d. Math.2f " + "is %. double arg2) float max(float arg1. d)).3f%n". Math.printf("The absolute value " + "of %. c.635.printf("The min of of %d " + "and %d is %d%n".74. System.74 is 44 max of 16 and 45 is 45 min of 16 and 45 is 16 Métodos de funciones logarítmicos y exponenciales La siguiente tabla enumera los métodos de la clase Math funciones logarítmicos y exponenciales. int arg2) long max(long arg1. Math. Math. Métodos de funciones logarítmicos y exponenciales Método Descripción .floor(b)). System. Math. } } Aquí está la salida de este programa: The The The The The The absolute value of -191.max(c. System.0f%n".3f is %. d.74 is 43 rint of 43.74 is 44 floor of 43. c.2f is %. System. a. Math.min(c. x.exp(x)). El valor pasado en cada uno de estos métodos es un ángulo expresado en radianes.printf("exp(%.pow(x.out. System. System. Métodos de funciones trigonométricos Método double sin(double d) Descripción Devuelve el seno del doble valor especificado.635.3f) " + "is %.635) is 3. Math. double pow(double base.double exp(double d) Devuelve la base de los logaritmos naturales.3f) " + "is %. entonces llamadas cada uno de los métodos enumerado en la tabla anterior arbitrariamente elegido números: public class ExponentialDemo { public static void main(String[] args) { double x = 11. x.76. a la potencia de la discusión.4f%n". System.3f%n".635) is 2. e.printf("log(%. que se resumen en la tabla siguiente. System. double y = 2.3f%n". System.454 pow(11. Math. double exponent) Devuelve el valor del primer argumento elevado a la potencia del segundo argumento.760) is 874.out.printf("The value of " + "e is %.3f%n". double sqrt(double d) Devuelve la raíz cuadrada del argumento. 2.831 log(11.7183 exp(11. ExponentialDemo. double log(double d) Devuelve el logaritmo natural del argumento.635) is 112983.out.printf("pow(%.out.008 sqrt(11.3f%n". y)).411 Métodos de funciones trigonométricos La clase de Math también proporciona una colección de funciones trigonométricas.log(x)). x. Math. Puede utilizar el método toRadians para convertir de grados a radianes.sqrt(x)).E). Math. y. %.printf("sqrt(%. Las siguientes pantallas de programa. } } Aquí está la salida verás al ejecutar ExponentialDemo: The value of e is 2.out. el valor de e.3f) is " + "%.635.3f) is " + "%. .3f. x. Math. format("The sine of %. Math. Math. theta) y devuelve theta.cos(radians)))).out.format("The arcsine of %. Math.4f " + "is %.toDegrees(Math. .double cos(double d) Devuelve el coseno del valor doble especificado. double acos(double d) Devuelve el arcoseno de doble valor especificado. double x) Coordenadas rectangulares (x.sin(radians). System.0.4f degrees %n".1f " + "degrees is %. que utiliza cada uno de estos métodos para calcular varios valores de funciones trigonométricos para un ángulo de 45 grados: public class TrigonometricDemo { public static void main(String[] args) { double degrees = 45.out. double atan2(double y.out. System.4f degrees %n".1f " + "degrees is %.asin(Math. y) se convierte en coordenadas polares (r. Math. degrees. Math. System. System. System.toRadians(degrees).1f " + "degrees is %.4f%n".PI).sin(radians)))).format("The value of pi " + "is %. System.4f " + "is %. degrees. Math. double tan(double d) Devuelve la tangente del valor doble especificado. Aquí es un programa. TrigonometricDemo.format("The arccosine of %. double atan(double d) Devuelve el arco tangente del doble valor especificado. degrees. System. double radians = Math. Math.cos(radians). double toDegrees(double d) double toRadians(double d) El argumento se convierte en grados o radianes.format("The arctangent of %.acos(Math.toDegrees(Math.out.format("The cosine of %.out. Math.cos(radians)).4f degrees %n".out.out. Math.tan(radians).format("The tangent of %.4f " + "is %.sin(radians)).4f%n".4f%n".4f%n". double asin(double d) Devuelve el arcoseno de doble valor especificado.tan(radians)). Como alternativa. Float. Utilizando Math.0 pero no 1. si usted está utilizando un valor de carácter individual. puede utilizar los métodos printf() o format() en la clase de PrintStream . } } La salida de este programa es como sigue: The The The The The The The value of pi is 3. En otras palabras: 0. para la generación de números aleatorios. para generar un número entero entre 0 y 9. La clase Math contiene una variedad de métodos de la clase para realizar funciones matemáticas. El byteValue.0000 is 45. El método valueOf convierte una cadena en un número.0. otra vez cuando sea necesario. Longo Short – para envolver un número de tipo primitivo en un objeto.7071 is 45. Por ejemplo: .0 degrees is 0.7071 tangent of 45. shortValuey métodos similares convierten a un tipo numérico a otro.tan(radians)))). Double. Resumen de números Utiliza uno de las clases contenedoras – Byte.Math.7071 is 45. utilizará el tipo primitivo char.0 y 1. escribiría: int number = (int)(Math. Por ejemplo. Integer. Para obtener un número en un rango diferente. incluyendo métodos exponenciales.0000 degrees Números aleatorios El método random() devuelve un número pseudo aleatoriamente seleccionado entre 0.toDegrees(Math. puede utilizar la clase NumberFormat para personalizar formatos numéricos usando patrones.0.0. Para dar formato a una cadena que contenga números de salida. la gama de valores posibles se convierte 0.0000 degrees arctangent of 1. debe crear una instancia de java.random() < 1.0 degrees is 0.0.0 degrees is 1. Caracteres La mayoría de las veces. logarítmicos y trigonométricos. Multiplicando el valor por 10. Si necesita generar una serie de números al azar. El Number clases incluye constantes y métodos de la clase útil. La gama incluye 0.Random e invocar métodos en ese objeto para generar números. El compilador de Java automáticamente envuelve a primitivas (cajas) para que cuando sea necesario y unboxes.1416 sine of 45.0000 degrees arccosine of 0.0000 arcsine of 0. Las constantes MIN_VALUE y MAX_VALUE contienen los valores más pequeños y más grandes que pueden contener un objeto de ese tipo.atan(Math.random() * 10). tales como valor absoluto y redondeo y un método random().7071 cosine of 45.0 <= Math. puede realizar aritmética en el valor devuelto por el método aleatorio.0 <= number < 10.util.random funciona bien cuando usted necesita generar un número aleatorio. y el método toString convierte a un número en una cadena. Math también incluye funciones aritméticas básicas. vea Autoboxing y Unboxing. Para obtener más información sobre autoboxing y unboxing. Esta característica se llama autoboxing— o unboxing. pero no es exhaustiva. Para una lista completa de todos los métodos de esta clase (hay más de 50). 'e' }. Métodos útiles en la clase de Character Método Descripción boolean isLetter(char ch) boolean isDigit(char ch) Determina si el valor especificado char es una letra o un dígito. si pasas un primitivo char en un método que espera un objeto. // Unicode for uppercase Greek omega character char uniChar = '\u03A9'. respectivamente. Nota: La clase de Character es inmutable. 'b'. consulte la especificación java. Hay veces. // an array of chars char[] charArray = { 'a'. . Puede crear un objeto de Character con el constructor de Character: Character ch = new Character('a'). boolean isWhitespace(char ch) Determina si el valor especificado char es el espacio en blanco.Character API. La tabla siguiente enumera algunos de los métodos más útiles en la clase de Character. Por ejemplo. cuando tienes que usar un char como un objeto — por ejemplo. El lenguaje de programación Java proporciona una clase contenedora que "envuelve" el char en un objeto de Character para este propósito. el compilador convierte automáticamente el char a un Character para ti. cuyo tipo es char.char ch = 'a'. char toUpperCase(char ch) char toLowerCase(char ch) Devuelve la forma mayúscula o minúscula de los char especificado valor. 'c'.lang. Esta clase de caracteres también ofrece una serie de útiles clases (es decir. como un argumento de método donde se espera un objeto. estáticos) métodos para manipular caracteres. sin embargo. respectivamente. El compilador de Java también creará un objeto de Character para usted bajo ciertas circunstancias. 'd'. boolean isUpperCase(char ch) boolean isLowerCase(char ch) Determina si el valor especificado char es mayúscula o minúscula. no se puede cambiar un objeto de Character. si la conversión va al revés. Un objeto de tipo Character contiene un solo campo. de modo que una vez que se crea. el compilador lo interpreta en consecuencia. \b Inserte un retroceso en el texto en este momento. \\ Insertar un carácter de barra diagonal inversa en el texto en este momento.Devuelve un objeto String que representa el carácter especificado valor — es decir. toString(char ch) Secuencias de escape Un carácter precedido por una barra invertida (\) es una secuencia de escape y tiene un significado especial para el compilador. En el lenguaje de programación Java. Por ejemplo. \n Insertar un salto de línea en el texto en este momento. \f Inserte del formfeed en el texto en este momento. La plataforma Java proporciona la clase String para crear y manipular cadenas. \r Insertar un retorno de carro en el texto en este momento. son una secuencia de caracteres. Para imprimir la sentencia She said "Hello!" to me. Strings Las strings. que son ampliamente utilizadas en programación Java. las strings son objetos.println("She said \"Hello!\" to me. Cuando se encuentra una secuencia de escape en una instrucción print."). \ ". si usted quiere poner citas entre comillas debe utilizar la secuencia de escape. \' Insertar un carácter de comilla simple en el texto en este momento. sobre las comillas interiores. Creación de strings .out. La siguiente tabla muestra las secuencias de escape de Java: Secuencias de escape Secuencia de escape Descripción \t Inserte una ficha en el texto en este momento. una cadena de un carácter. usted escribiría System. \" Insertar un carácter de comillas dobles en el texto en este momento. i < len. que parecen modificar cadenas. La clase String tiene un número de métodos.charAt(i). Un palíndromo es una palabra o frase que es simétrica. } // reverse array of chars for (int j = 0.println(helloString). Cuando se encuentra con una cadena literal en el código. public class StringDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod". contados a partir de 0. puede crear objetos String utilizando la palabra clave new y un constructor. // put original string in an // array of chars for (int i = 0. haciendo caso omiso de caso y la puntuación. En este caso. Puesto que las cadenas son inmutables. '.' }. La clase String tiene trece constructores que permita proporcionar el valor inicial de la cadena utilizando diversas fuentes. Aquí es un programa corto e ineficiente para revertir una cadena palíndromo. j++) { . 'e'. 'l'.out. se escribe el mismo hacia adelante y hacia atrás. len equivale a 17: String palindrome = "Dot saw I was Tod". "¡Hola mundo!" es una cadena literal— una serie de caracteres en el código que está entre comillas dobles. de modo que una vez que se crea un objeto String no puede cambiarse. i++) { tempCharArray[i] = palindrome. char[] charArray = new char[len]. 'o'. tales como una matriz de caracteres: char[] helloArray = { 'h'. j < len. estos métodos realmente qué es crear y devolver una cadena nueva que contiene el resultado de la operación. char[] tempCharArray = new char[len]. algunos de los cuales serán discutidos más abajo. Longitud de cadena Métodos utilizados para obtener información acerca de un objeto son conocidos como métodos de descriptor de acceso. que devuelve el número de caracteres contenidos en el objeto string. int len = palindrome. Después de las dos líneas de código siguientes han sido ejecutadas. que devuelve la ith carácter de la cadena. int len = palindrome. System. 'l'.length(). Hello world! Como con cualquier otro objeto. String helloString = new String(helloArray). Un método de descriptor de acceso que se puede usar con las cadenas es el método length() . Invoca la String método charAt(i). el compilador crea un objeto String con su valor — en este caso. Nota: La clase String es inmutable.La manera más directa para crear una cadena es escribir: String greeting = "Hello world!".length(). La última línea de este fragmento de código muestra hello. para convertir una cadena o una parte de una cadena. que imprime Dot saw I was Tod Tan una concatenación puede ser una mezcla de cualquier objeto.j]. Para cada objeto que no es una String.out. } } Ejecutar el programa produce esta salida: doT saw I was toD Para lograr la revocación de la cadena.charArray[j] = tempCharArray[len . System. Las cadenas son más comúnmente concatenadas con el + operador.concat("Rumplestiltskin").out. tempCharArray. Esto devuelve una nueva cadena que cadena1 con cadena2 añadida al final. System.println("Dot " + string1 + "Tod").concat(string2). } String reversePalindrome = new String(charArray). el programa tenía que convertir la cadena en una matriz de caracteres (primera for bucle).println(reversePalindrome).1 . se llama a su método toString() para convertirlo en una String. La clase String incluye un método getChars(). len." + " world" + "!" que se traduce en "Hello. Por ejemplo: String string1 = "saw I was ". en una matriz de caracteres así nos podríamos reemplazar el primer bucle for en el programa por encima con palindrome. world!" El + operador es ampliamente utilizado en las declaraciones print . 0). También puede utilizar el método concat() con los literales de cadena. reversa la matriz una segunda matriz (segundo for bucle) y luego convertir a una cadena. como en: "My name is ". como en "Hello. .getChars(0. Concatenación de cadenas La clase String incluye un método para concatenar dos cadenas: string1. out. ValueOfDemo . Creación de cadenas de formato Has visto el uso de los métodos printf() y format() para salida con números con formato de impresión. while " + "the value of the " + "integer variable is %d. Usted puede escribir String fs. " + "and the string is %s". intVar. La clase String tiene un método de clase equivalente. stringVar). Rompiendo cadenas entre líneas usando el + operador de concatenación es. un programa termina con datos numéricos en un objeto string — un valor introducido por el usuario.println(fs). en contraposición a una sola instrucción print. Float. " + " and the string is %s".out. Integer.Nota: El lenguaje de programación Java no permite literales para abarcar las líneas en archivos de código fuente. intVar. floatVar. stringVar).format("The value of the float " + "variable is %f. System. Por ejemplo: String quote = "Now is the time for all good " + "men to come to the aid of their country. convierte a los números y realiza las operaciones aritméticas en los valores: public class ValueOfDemo { public static void main(String[] args) { // this program requires two .printf("The value of the float " + "variable is %f. así que usted debe usar el + operador de concatenación al final de cada línea en una cadena de múltiples líneas. format(). fs = String. Aquí hay un ejemplo. que devuelve un objeto String en lugar de un objeto de PrintStream . Longy Short) cada proporcionan un método de clase llamado valueOf que convierte una cadena en un objeto de ese tipo. while " + "the value of the " + "integer variable is %d. una vez más. muy común en las declaraciones print . que obtiene dos cadenas de la línea de comandos. floatVar.". en vez de System. Por ejemplo. Método String's estática format() le permite crear una cadena con formato que se puede reutilizar. Conversión entre números y cadenas Conversión de cadenas a números Con frecuencia. Las subclases de Number que envuelven primitivos tipos numéricos ( Byte. Double. por ejemplo. Puesto que se devuelve un tipo primitivo en lugar de un objeto. conversion is handled for you.out. Por ejemplo.println("a * b = " + (a * b)). } } } La siguiente es la salida del programa cuando utilizas 4.5 Nota: Cada una de las subclases de Number que envuelven los tipos primitivos numéricos también proporciona un método parseXXXX() (por ejemplo.println("a % b = " + (a % b)). System. // do some arithmetic System.5 y 87.floatValue().7 392.").println("This program " + "requires two command-line arguments.println("a + b = " + (a + b)).out. o // The valueOf class method.floatValue().out.println("a . } else { System. float b = Float. Por ejemplo: . toString(). Convertir números en cadenas A veces es necesario convertir a un número en una cadena porque necesita funcionar con el valor en su forma de cadena.parseFloat(args[1]). System. String s2 = String.7 -82.valueOf(i).out. Hay varias maneras sencillas para convertir a un número en una cadena: int i. String s1 = "" + i. que convertirá a su tipo primitivo en una cadena.2 por los argumentos de línea de comandos: a a a a a + * / % b b b b b = = = = = 91. System.// arguments on the command line if (args.b = " + (a .println("a / b = " + (a / b)). Cada una de las subclases Number incluye un método de clase.4 0. el método parseFloat() es más directo que el método valueOf() .valueOf(args[0])). en el programa ValueOfDemo . parseFloat()) que puede utilizarse para convertir cadenas en números primitivos. // Concatenate "i" with an empty string.valueOf(args[1])). System.parseFloat(args[0]). necesitamos: float a = Float. float b = (Float.out.out.b)).0516055 4.length == 2) { // convert strings to numbers float a = (Float. O roar again!".toString(d). System. el programa utiliza algunos métodos de cadena para calcular el número de dígitos antes y después del punto decimal: public class ToStringDemo { public static void main(String[] args) { double d = 858.indexOf('. } } La salida de este programa es: 3 digits before decimal point. mientras que el índice del último carácter es length()-1.48.int i. puede utilizar el método substring .out. así es el carácter del índice 9 ' o '. cambiando el caso y otras tareas. String s3 = Integer.toString(i).length() .dot . El ejemplo ToStringDemo utiliza el método toString para convertir a un número en una cadena. Manipulación de caracteres de una cadena La clase String tiene un número de métodos para examinar el contenido de las cadenas. El método substring tiene dos versiones. Entonces. int dot = s.charAt(9). encontrar caracteres o subcadenas dentro de una cadena.println(dot + " digits " + "before decimal point. String s4 = Double. como se ilustra en la figura siguiente: Si desea obtener más de un carácter consecutivo de una cadena. String s = Double. el código siguiente obtiene el carácter en el índice 9 en una cadena: String anotherPalindrome = "Niagara. 2 digits after decimal point.toString(d).1) + " digits after decimal point. Caracteres y subcadenas Índice Puede obtener el carácter en un índice en particular dentro de una cadena invocando el método de descriptor de acceso charAt() . double d. como se muestra en la siguiente tabla: .'). El índice del primer carácter es 0. Los índices comienzan en 0. char aChar = anotherPalindrome.out."). Por ejemplo. System.").println( (s. int endIndex) Devuelve una nueva cadena es una subcadena de esta cadena. El primer argumento entero especifica el índice del primer carácter. El argumento entero opcional especifica el tamaño máximo de la matriz devuelta. El argumento entero especifica el índice del primer carácter.1. int endIndex) Devuelve una nueva secuencia de carácter construida a partir de índice beginIndex hasta endIndex . El código siguiente obtiene desde el Palíndromo Niagara la subcadena que se extiende desde índice 11. String roar = anotherPalindrome. Las expresiones regulares están cubiertas en la lección titulada "Expresiones regulares". la subcadena devuelta se extiende hasta el final de la secuencia original. int limit) Busca un partido según lo especificado por el argumento de cadena (que contiene una expresión regular) y se divide esta cadena en una matriz de cadenas en consecuencia. O roar again!". La clase String proporciona métodos de descriptor de acceso que devuelven la . pero no incluyendo. índice 15. El segundo argumento entero es el índice del último carácter . String toLowerCase() String toUpperCase() Devuelve una copia de esta cadena que se puede convertir a mayúsculas o minúsculas. Si no hay conversiones son necesarias.substring(11. que es el palabra "rugido": String anotherPalindrome = "Niagara.1. String trim() Devuelve una copia de esta cadena con quitar espacios en blanco iniciales y finales. String substring(int beginIndex) Devuelve una nueva cadena es una subcadena de esta cadena. estos métodos devuelven la cadena original. CharSequence subSequence(int beginIndex. 15). Aquí.La substring métodos en la clase String Método Descripción String substring(int beginIndex. Otros métodos para manipular cadenas Aquí hay varios otros métodos de String para manipular cadenas: Otros métodos de la clase String para manipular cadenas Método Descripción String[] split(String regex) String[] split(String regex. La búsqueda de caracteres y subseries de caracteres en una cadena Aquí están algunos otros métodos de String para encontrar caracteres o subcadenas dentro de una cadena. devuelve true si la cadena contiene una secuencia de carácter particular. int fromIndex) int lastIndexOf(String str. boolean contains(CharSequence s) Devuelve true si la cadena contiene la secuencia de caracteres especificado. char newChar) Devuelve una nueva cadena resultante de reemplazar todas las apariciones de oldChar en esta cadena con newChar. String replace(CharSequence target. puede utilizar una cadena como argumento para el método contains() . int fromIndex) Devuelve el índice de la primera aparición (última) del carácter especificado. La tabla siguiente describen los distintos métodos de búsqueda de cadena. Los métodos de búsqueda en la clase String Método Descripción int indexOf(int ch) int lastIndexOf(int ch) Devuelve el índice de la primera aparición (última) del carácter especificado. no son necesarios: puede crear una nueva cadena de concatenación de subcadenas tienes que quitar de una cadena con la subcadena que desee insertar. y los métodos lastIndexOf() buscar hacia atrás desde el extremo de la cuerda. En general. Ellos son: Métodos de la clase String para manipular cadenas Método Descripción String replace(char oldChar. La clase String tiene cuatro métodos para reemplazar encontró caracteres o subcadenas. int indexOf(String str. int indexOf(String str) int lastIndexOf(String str) Devuelve el índice de la primera aparición (último) de la subcadena especificada. Si no se encuentra un carácter o subcadena. contains. Utilice este método cuando sólo tienes que saber que la cadena contiene una secuencia de caracteres. indexOf() y lastIndexOf() devuelven -1. Por lo tanto. pero la ubicación exacta no es importante. Nota: CharSequence es una interfaz implementada por la clase String . . CharSequence replacement) Sustituye cada subcadena de esta cadena que coincide con la secuencia de destino literal con la secuencia especificada reemplazo literal. int fromIndex) int lastIndexOf(int ch. Sustitución de caracteres y subseries de caracteres en una cadena La clase String tiene muy pocos métodos para insertar una cadena de caracteres o subcadenas. búsqueda hacia adelante (hacia atrás) en el índice especificado. Los métodos indexOf() buscar hacia delante desde el principio de la cadena.posición dentro de la cadena de un carácter específico o subcadena: indexOf() y lastIndexOf(). La clase String también proporciona un método de búsqueda. int fromIndex) Devuelve el índice de la primera aparición (último) de la subsecuencia especificada. int indexOf(int ch. sin embargo. búsqueda hacia adelante (hacia atrás) en el índice especificado. String replaceAll(String regex, String replacement) Sustituye cada subcadena de esta cadena que coincide con la expresión regular dada con el reemplazo del dado. String replaceFirst(String regex, String replacement) Reemplaza la primera subcadena de esta cadena que coincide con la expresión regular dada con el reemplazo del dado. Un ejemplo La clase siguiente, Filename, ilustra el uso de lastIndexOf() y substring() a aislar las diferentes partes de un nombre de archivo. Nota: Los métodos en la clase siguiente de Filename no hacer ninguna comprobación de errores y asumir que su argumento contiene una ruta de directorio completo y un nombre de archivo con la extensión. Si estos métodos fueron código de producción, verificaría que sus argumentos fueron construidos correctamente. public class Filename { private String fullPath; private char pathSeparator, extensionSeparator; public Filename(String str, char sep, char ext) { fullPath = str; pathSeparator = sep; extensionSeparator = ext; } public String extension() { int dot = fullPath.lastIndexOf(extensionSeparator); return fullPath.substring(dot + 1); } // gets filename without extension public String filename() { int dot = fullPath.lastIndexOf(extensionSeparator); int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(sep + 1, dot); } public String path() { int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(0, sep); } } Aquí es un programa, FilenameDemo, que construye un objeto de Filename y llama a todos sus métodos: public class FilenameDemo { public static void main(String[] args) { final String FPATH = "/home/user/index.html"; Filename myHomePage = new Filename(FPATH, '/', '.'); System.out.println("Extension = " + myHomePage.extension()); System.out.println("Filename = " + myHomePage.filename()); System.out.println("Path = " + myHomePage.path()); } } Y aquí está la salida del programa: Extension = html Filename = index Path = /home/user Como se muestra en la figura siguiente, nuestro método de extension utiliza lastIndexOf para localizar la última aparición del punto (.) en el nombre del archivo. Luego substring utiliza el valor devuelto de lastIndexOf para extraer la extensión de nombre de archivo — es decir, la subcadena de la época hasta el final de la cadena. Este código asume que el nombre de archivo tiene un período Si el nombre del archivo no tiene un período, lastIndexOf devuelve -1, y el método substring lanza un StringIndexOutOfBoundsException. Además, observe que el método de extension utiliza dot + 1 como argumento de substring. Si el personaje período (..) es el último carácter de la cadena, dot + 1 es igual a la longitud de la cadena, que es uno más grande que el mayor índice en la cadena (porque los índices comienzan en 0). Este es un argumento legal para substring porque ese método acepta un índice igual, pero no superior a la longitud de la cadena y lo interpreta en el sentido de "el final de la cadena". Comparación de cadenas y porciones de cadenas La clase String tiene un número de métodos para comparar cadenas y porciones de las cuerdas. La tabla siguiente enumera estos métodos. Métodos para comparar cadenas Método Descripción boolean endsWith(String suffix) boolean startsWith(String prefix) Devuelve true si esta cadena termina con o comienza con la subcadena especificada como argumento al método. boolean startsWith(String prefix, int offset) Considera que el principio de la cadena en el índice de offsety devuelve true si se inicia con la subcadena especificada como argumento. int compareTo(String anotherString) Compara dos cadenas lexicográfico. Devuelve un entero que indica si esta cadena es mayor que (el resultado es > 0), igual a (el resultado es = 0), o menos (el resultado es < 0) el argumento. int compareToIgnoreCase(String str) Compara dos cadenas lexicográfico, ignorando las diferencias en el caso. Devuelve un entero que indica si esta cadena es mayor que (el resultado es > 0), igual a (el resultado es = 0), o menos (el resultado es < 0) el argumento. boolean equals(Object anObject) Devuelve true si y sólo si el argumento es un objeto String que representa la misma secuencia de caracteres que este objeto. boolean equalsIgnoreCase(String anotherString) Devuelve true si y sólo si el argumento es una String objeto representa la misma secuencia de caracteres que este objeto, ignorando las diferencias en el caso. boolean regionMatches(int toffset, String other, int ooffset, int len) Comprueba si la región determinada de esta cadena coincide con la región determinada del argumento. Región de longitud len y comienza en el índice toffset de esta cadena y ooffset para la otra cadena. Comprueba si la región determinada de esta cadena coincide con la región determinada del argumento. boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) Región de longitud len y comienza en el índice toffset de esta cadena y ooffset para la otra cadena. El argumento booleano que indica si el caso debe ser ignorado; Si es true, caso se omite al comparar caracteres. boolean matches(String regex) Comprueba si esta cadena coincide con la expresión regular especificada. Las expresiones regulares se discuten en la lección titulada "Expresiones regulares". El siguiente programa, RegionMatchesDemo, utiliza el método regionMatches para buscar una cadena dentro de otra cadena: public class RegionMatchesDemo { public static void main(String[] args) { String searchMe = "Green Eggs and Ham"; String findMe = "Eggs"; int searchMeLength = searchMe.length(); int findMeLength = findMe.length(); boolean foundIt = false; for (int i = 0; i <= (searchMeLength - findMeLength); i++) { if (searchMe.regionMatches(i, findMe, 0, findMeLength)) { foundIt = true; System.out.println(searchMe.substring(i, i + findMeLength)); break; } } if (!foundIt) println("No match found. Internamente. anexar un objeto StringBuilder es más eficiente Longitud y capacidad La clase StringBuilder. si necesitas concatenar un gran número de cadenas. En cualquier momento. StringBuilder(int initCapacity) Crea un constructor de cadena vacía con la capacidad inicial especificada. estos objetos son tratados como arrays de longitud variable que contienen una secuencia de caracteres. Las strings siempre deben ser usadas a menos que los constructores de cadenas ofrecen una ventaja en términos de código más simple (ver el programa muestra al final de esta sección) o mejor rendimiento. el número de espacios de carácter que han sido asignados. capacity 16 StringBuilder sb = new StringBuilder(). el siguiente código // creates empty builder. Para cada personaje. es siempre mayor o igual a la longitud (generalmente mayor) y se expandirá automáticamente según sea necesaria para acomodar las adiciones al constructor string. la longitud y el contenido de la secuencia pueden ser cambiados a través de invocaciones de método. más un extra de 16 elementos vacíos siguiendo la CharSequence. } } La salida de este programa es Eggs. cada constructor string también tiene una capacidad. StringBuilder(String s) Crea un constructor string cuyo valor es inicializado por la cadena especificada. // adds 9 character string at beginning . Los pasos del programa a través de la cadena de referidos por searchMe un carácter a la vez. StringBuilder Constructores Constructor Descripción StringBuilder() Crea un constructor de cadena vacía con una capacidad de 16 (16 elementos vacíos). StringBuilder(CharSequence cs) Construye un constructor string que contiene los mismos caracteres que el especificado CharSequence. el programa llama al método regionMatches para determinar si el principio de la subcadena con el carácter actual coincide con la cadena que está buscando el programa. excepto que se puede modificar. Por ejemplo.System. La clase StringBuilder Objetos StringBuilder son como objetos String.out."). La capacidad. como la clase String . además de un extra 16 elementos vacíos se arrastra la cadena. que es devuelto por el método capacity(). Por ejemplo. A diferencia de las cuerdas. tiene un método length() que devuelve la longitud de la secuencia de caracteres en el constructor. int offset. Operaciones de StringBuilder Las principales operaciones en un StringBuilder que no están disponibles en String son los métodos append() y insert() . la capacidad aumenta automáticamente. caracteres nulos se agregan al final de la secuencia de caracteres. Un número de operaciones (por ejemplo. Si newLength es menor que length().append("Greetings"). mientras que el método insert añade los caracteres en un punto especificado. se truncan los últimos caracteres en la secuencia de caracteres. Cuando esto sucede. append(). Cada uno convierte su argumento en una cadena y luego anexa o inserta los caracteres de la cadena a la secuencia de caracteres en el configurador de cadena. producirá un constructor de cadena con una longitud de 9 y una capacidad de 16 años: La clase StringBuilder tiene algunos métodos relacionados con la longitud y capacidad que no tiene la clase String : Longitud y capacidades métodos Método Descripción void setLength(int newLength) Establece la longitud de la secuencia de caracteres. void ensureCapacity(int minCapacity) Asegura que la capacidad es igual o superior al mínimo especificado. insert()o setLength()) puede aumentar la longitud de la secuencia de caracteres en el configurador de cadena para que la resultante length() sería mayor que el actual capacity(). Los datos se convierten en una cadena antes de que lleva a cabo la operación de anexado. int len) StringBuilder append(double d) StringBuilder append(float f) StringBuilder append(int i) StringBuilder append(long lng) Descripción Anexa el argumento para el constructor de esta cadena. Si newLength es mayor que length(). . El método append agrega siempre estos personajes al final de la secuencia de caracteres existentes.sb. que están sobrecargados para aceptar datos de cualquier tipo. Varios métodos de StringBuilder Método StringBuilder append(boolean b) StringBuilder append(char c) StringBuilder append(char[] str) StringBuilder append(char[] str. Aquí están varios de los métodos de la clase StringBuilder . float f) StringBuilder insert(int offset. El segundo método borra el carácter situado en el index. int offset. Entonces convertir la cadena en un constructor string utilizando el constructor StringBuilder(String str) . double d) StringBuilder insert(int offset. long lng) StringBuilder insert(int offset. StringBuilder insert(int offset. String s) void setCharAt(int index. int i) StringBuilder insert(int offset. int len) StringBuilder insert(int offset. char[] tempCharArray = new char[len]. Aquí.StringBuilder append(Object obj) StringBuilder append(String s) StringBuilder delete(int start. Los datos se convierten en una cadena antes de la operación de inserción lleva a cabo.length(). String toString() Devuelve una cadena que contiene la secuencia de caracteres en el constructor. StringDemo revirtió un palíndromo. StringBuilder reverse() Invierte la secuencia de caracteres en el constructor de esta cadena. int end. Object obj) StringBuilder insert(int offset. boolean b) StringBuilder insert(int offset. char c) Sustituye el carácter especificado en el constructor de esta cadena. StringBuilder replace(int start. es su lista: public class StringDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod". int end) StringBuilder deleteCharAt(int index) El primer método elimina el subsequence de principio a fin-1 (ambos inclusive) en secuencia el StringBuilderde char. . char c) StringBuilder insert(int offset. char[] charArray = new char[len]. char[] str) StringBuilder insert(int index. El primer argumento entero indica el índice antes de que los datos se va a insertar. char[] str. Un ejemplo El programa StringDemo que se enumera en la sección titulada "Strings" es un ejemplo de un programa que sería más eficaz si se utilizaron un StringBuilder en lugar de una String. una vez más. Nota: Puede utilizar cualquier método de String en un objeto StringBuilder primero convirtiendo el constructor string a una cadena con el método toString() de la clase StringBuilder . String s) Inserta el segundo argumento del constructor string. int len = palindrome. reverse(). } } Ejecutar este programa produce el mismo resultado: doT saw I was toD Tenga en cuenta que println() imprime un constructor de cadena.j]. Hace el código más simple y más fácil de leer: public class StringBuilderDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod". excepto que es segura para subprocesos en virtud de tener sus métodos sincronizados. puede utilizar el método reverse() en la clase StringBuilder . sb. } // reverse array of chars for (int j = 0. como es con cualquier otro objeto en una invocación println() . Hilos de rosca se discutirá en la lección en simultaneidad. Si convierte la cadena palindrome a un constructor de cadena. } String reversePalindrome = new String(charArray). System. j++) { charArray[j] = tempCharArray[len . porque sb. .toString() se llama implícitamente. StringBuilder sb = new StringBuilder(palindrome). Nota: También hay una clase StringBuffer que es exactamente el mismo que el StringBuilder clase.1 .println(sb). como en: System. i++) { tempCharArray[i] = palindrome.println(reversePalindrome). j < len. i < len. el programa convierte la cadena en una matriz de caracteres (primera for bucle).out.println(sb).charAt(i). // reverse it System.out. en un segundo se invierte la matriz array (segundo bucle for ) y luego de regreso se convierte en una cadena. } } Ejecutar el programa produce esta salida: doT saw I was toD Para lograr la revocación de la cadena.// put original string in an // array of chars for (int i = 0.out. Puede convertir una cadena a un constructor de cadena utilizando un constructor de StringBuilder . hay también una clase StringBuilder . En el lenguaje de programación Java. cuando tienes que usar un char como un objeto — por ejemplo. Las subclases Number también tienen métodos para convertir cadenas a números y viceversa. convertir un int a un número entero. Hay veces. La clase String tiene más de 60 métodos y 13 constructores. La clase String también incluye un número de métodos de utilidad. El lenguaje de programación Java proporciona una clase contenedora que "envuelve" el char en un objeto de Character para este propósito. Si todavía no estás familiarizado con la sintaxis de los genéricos. sin embargo. La clase String tiene muchos métodos para buscar y recuperar subcadenas. sin embargo. El resto de los ejemplos de esta sección utilizar medicamentos genéricos. Además de la clase String . un doble con un dobley así sucesivamente. vea la lección de los medicamentos genéricos (actualizado) . En general. i += 2) . for (int i = 1. Entonces estos pueden montarlo fácilmente en nuevas cadenas utilizando el + operador de concatenación. Autoboxing y Unboxing Autoboxing es la conversión automática que hace que el compilador de Java entre los tipos primitivos y sus correspondientes clases contenedoras de objeto. Trabajando con StringBuilder objetos pueden ser a veces más eficientes que trabaja con cadenas. si usted está utilizando un valor de carácter individual. split(). en lugar de utilizar uno de los constructores de la String . Aquí es el ejemplo más simple de autoboxing: Character ch = 'a'. la clase String tiene una amplia variedad de métodos. estática) métodos para manipular caracteres. utilizará el tipo primitivo char. se crea una cadena con una declaración como String s = "Hello world!". entre ellos reverse(). Esta clase de Character también ofrece una serie de útil clase (es decir. las cadenas son objetos. i < 50. como un argumento de método donde se espera un objeto. El último método es indispensable para convertir cadenas de entrada del usuario a números. Comúnmente. Si la conversión va al revés. La clase StringBuilder ofrece algunos métodos que pueden ser útiles para las cadenas. esto se llama unboxing.Resumen de caracteres y cadenas La mayoría de las veces. toLowerCase()y toUpperCase(). Las cadenas son una secuencia de caracteres y son ampliamente utilizados en programación Java. Un constructor de cadena se puede convertir en una cadena con el método toString() . Un objeto de tipo Character contiene un campo cuyo tipo es char. Por ejemplo. entre ellos valueOf(). Considere el siguiente código: List<Integer> li = new ArrayList<>(). i < 50.ArrayList. Considere el siguiente método: public static int sumEven(List<Integer> li) { int sum = 0.valueOf(i)).intValue().util. Asignada a una variable de la correspondiente clase contenedora. for (Integer i: li) if (i % 2 == 0) sum += i. El Unboxing ejemplo muestra cómo funciona esto: import java. Asignado a una variable del tipo primitivo correspondiente. public class Unboxing { public static void main(String[] args) { . se preguntarán por qué el compilador de Java no emite un error en tiempo de compilación. por ejemplo) en un objeto de la correspondiente clase contenedora (entero) se llama autoboxing.li. } Convertir un objeto de un tipo de contenedor (Integer) a su correspondiente primitivo (int) se llama valor unboxing. for (int i = 1.add(Integer. el compilador convierte el código anterior al siguiente en tiempo de ejecución: List<Integer> li = new ArrayList<>(). Por lo tanto. for (Integer i : li) if (i. sino como objetos enteros . return sum. Aunque agrega los valores int tipos primitivos. El compilador no generará un error porque invoca el método intValue para convertir un número entero a un int en tiempo de ejecución: public static int sumEven(List<Integer> li) { int sum = 0. el código se compila. se preguntarán por qué el compilador Java compila el método sin emitir ningún error. import java. return sum. } Porque el resto (%) y los operadores unarios plus (+=) no se aplican a objetos enteros . no una lista de valores int . a li.List. El compilador de Java aplica unboxing cuando es objeto de una clase contenedora:   Pasa como parámetro a un método que espera un valor del tipo primitivo correspondiente.intValue() % 2 == 0) sum += i.util. El compilador no generará un error porque se crea un objeto Integer de i y agrega el objeto a li. Convertir un valor primitivo (un int.add(i). El compilador de Java aplica autoboxing cuando un valor primitivo es:   Pasa como parámetro a un método que espera un objeto de la correspondiente clase contenedora. i += 2) li. Li es una lista de objetos enteros . Unboxing through assignment double pi = ld. que son utilizados por el compilador de Java para autoboxing y unboxing: Tipo primitivo Clase contenedora Boolean Boolean Byte Byte Char Personaje flotador Flotador int Número entero largo Largo corto Corto doble Doble . Unboxing through method invocation int absVal = absoluteValue(i). System. La tabla siguiente enumera los tipos primitivos y sus correspondientes clases contenedoras. } public static int absoluteValue(int i) { return (i < 0) ? -i : i.println("absolute value of " + i + " = " + absVal).Integer i = new Integer(-8).println("pi = " + pi).1416).add(3.out. // Π is autoboxed through method invocation. } } El programa imprime lo siguiente: absolute value of -8 = 8 pi = 3.out. List<Double> ld = new ArrayList<>().1416 Autoboxing y unboxing permite los desarrolladores escribir limpiador el código. // 2. // 1.get(0). System. haciéndolo más fácil de leer. ld.
Copyright © 2024 DOKUMEN.SITE Inc.