0% encontró este documento útil (0 votos)
78 vistas166 páginas

Manual Java I

Este manual introduce Java desde cero para principiantes. Explica conceptos básicos como variables, operadores, estructuras de control como if/else y bucles, vectores, métodos, clases, herencia y polimorfismo. El manual guía al lector paso a paso para preparar su entorno de desarrollo Java y comenzar a escribir su primer programa.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
78 vistas166 páginas

Manual Java I

Este manual introduce Java desde cero para principiantes. Explica conceptos básicos como variables, operadores, estructuras de control como if/else y bucles, vectores, métodos, clases, herencia y polimorfismo. El manual guía al lector paso a paso para preparar su entorno de desarrollo Java y comenzar a escribir su primer programa.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 166

Manual Java I

Aprende a programar con Java desde 0

José Ángel Navarro


V 1.0 (2022)

Esta obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-


CompartirIgual 4.0 Internacional
José A. Navarro Java desde 0. Programación I

Índice
1. Introducción ........................................................................................................................ 11
2. Lenguajes de programación ................................................................................................ 12
2.1 Tipos ............................................................................................................................ 12
2.2 Programación estructurada ........................................................................................ 15
3. Lo primero que tenemos que aprender .............................................................................. 17
4. ¿Qué es Java? ...................................................................................................................... 18
5. Preparación de nuestro entorno de desarrollo................................................................... 19
5.1 Instalando Java ............................................................................................................ 19
5.1.1 JDK ....................................................................................................................... 19
5.1.2 Geany .................................................................................................................. 25
6. Comenzando ....................................................................................................................... 29
7. Conceptos iniciales .............................................................................................................. 35
7.1 Variables ...................................................................................................................... 38
7.2 Constantes................................................................................................................... 42
7.3 Operaciones ................................................................................................................ 42
7.4 Operadores de asignación........................................................................................... 45
7.5 Operadores unarios aritméticos ................................................................................. 45
7.6 Prioridad de operadores ............................................................................................. 46
7.7 Casting ......................................................................................................................... 47
7.8 Ejercicios...................................................................................................................... 48
8. Estructuras de control ......................................................................................................... 49
8.1 Estructuras condicionales ........................................................................................... 49
8.1.1 if ........................................................................................................................... 49
8.1.2 switch .................................................................................................................. 59
8.2 Estructuras de repetición ............................................................................................ 62
8.2.1 while .................................................................................................................... 62
8.2.2 do......................................................................................................................... 64
8.2.3 for ........................................................................................................................ 65
8.2.4 ¿Cuál debo de usar? ............................................................................................ 66
8.2.5 Break y continue.................................................................................................. 68
8.3 Ejercicios...................................................................................................................... 69
9. API ....................................................................................................................................... 70
10. Entrada por teclado ......................................................................................................... 73
10.1 Ejercicios...................................................................................................................... 78
11. Vectores .......................................................................................................................... 79

2
José A. Navarro Java desde 0. Programación I

11.1 Ordenación .................................................................................................................. 83


11.2 Matrices....................................................................................................................... 85
11.3 Ejercicios...................................................................................................................... 88
12. Métodos .......................................................................................................................... 89
12.1 Static ............................................................................................................................ 90
12.2 Modificador de ámbito ............................................................................................... 90
12.3 Return.......................................................................................................................... 91
12.4 Paso de parámetros .................................................................................................... 93
12.5 Recursividad ................................................................................................................ 98
12.6 Ejercicios.................................................................................................................... 100
13. Clases ............................................................................................................................. 101
13.1 Clases vs objetos ....................................................................................................... 102
13.2 ¿Qué pasos sigue java para crear un objeto? ........................................................... 104
13.3 Constructores ............................................................................................................ 104
13.4 La referencia this ....................................................................................................... 107
13.5 Modificadores de acceso........................................................................................... 108
13.6 Static .......................................................................................................................... 111
13.7 Final ........................................................................................................................... 112
14. Herencia ........................................................................................................................ 113
14.1 Sobreescritura ........................................................................................................... 118
14.2 Sobrecarga................................................................................................................. 119
14.3 toString ...................................................................................................................... 120
14.4 Clases abstractas ....................................................................................................... 120
14.5 Polimorfismo ............................................................................................................. 122
14.6 Ejercicios.................................................................................................................... 126
15. Object ............................................................................................................................ 128
15.1 toString() ................................................................................................................... 128
15.2 equals() ...................................................................................................................... 130
15.3 Asignación de Objetos ............................................................................................... 133
15.4 Constructor copia ...................................................................................................... 135
15.5 Wrappers ................................................................................................................... 136
16. Interfaces....................................................................................................................... 137
16.1 Declaración de una interfaz ...................................................................................... 137
16.2 Implementación de una interfaz en una clase .......................................................... 138
16.3 Jerarquía entre interfaces ......................................................................................... 138
16.4 Interfaces como tipos ................................................................................................ 138

3
José A. Navarro Java desde 0. Programación I

16.5 Cambios en JDK8 ....................................................................................................... 140


16.5.1 Default ............................................................................................................... 140
16.5.2 Interface funcional ............................................................................................ 141
16.5.3 Expresiones Lambda .......................................................................................... 141
16.6 ¿Qué es Comparable? ............................................................................................... 143
16.6.1 ¿Para qué sirve Comparable?............................................................................ 143
16.6.2 ¿Cómo funciona compareTo? ........................................................................... 143
16.6.3 ¿Cómo comparar dos objetos? ......................................................................... 144
16.6.4 ¿Cómo llamar a compareTo? ............................................................................ 144
16.6.5 Ejercicio ............................................................................................................. 145
17. La clase String ................................................................................................................ 146
18. La clase Math................................................................................................................. 149
19. Anexo I. ArrayList .......................................................................................................... 151
19.1 Estructuras para recorrer colecciones ...................................................................... 154
20. Anexo II. Excepciones .................................................................................................... 158
21. Anexo III. Algebra de Boole ........................................................................................... 161
22. Bibliografía .................................................................................................................... 163
23. Ejercicios........................................................................................................................ 164

4
José A. Navarro Java desde 0. Programación I

Índice de imágenes
Ilustración 1. Ejemplo código máquina ....................................................................................... 12
Ilustración 2. Ejemplo ensamblador............................................................................................ 12
Ilustración 3. Ejemplo Python ..................................................................................................... 13
Ilustración 4. Compilador C ......................................................................................................... 14
Ilustración 5. Interprete Python .................................................................................................. 14
Ilustración 6. Compilador Java .................................................................................................... 15
Ilustración 7. Instalador JDK ........................................................................................................ 20
Ilustración 8.Instalación JDK........................................................................................................ 21
Ilustración 9.Instalación JDK 2..................................................................................................... 21
Ilustración 10. Fin instalación JDK ............................................................................................... 21
Ilustración 11. Carpeta BIN ......................................................................................................... 22
Ilustración 12. Propiedades equipo ............................................................................................ 22
Ilustración 13. Configuración avanzada ...................................................................................... 23
Ilustración 14. Variables de entorno ........................................................................................... 23
Ilustración 15. Variables de entorno 2 ........................................................................................ 24
Ilustración 16. Añadir variable de entorno ................................................................................. 24
Ilustración 17. Classpath ............................................................................................................. 25
Ilustración 18. Classpath 2 .......................................................................................................... 25
Ilustración 19. Instalación de Geany ........................................................................................... 26
Ilustración 20. Instalación de Geany 2 ........................................................................................ 26
Ilustración 21. Icono de Geany .................................................................................................... 26
Ilustración 22. Entorno del IDE.................................................................................................... 26
Ilustración 23. Crear una nueva clase ......................................................................................... 27
Ilustración 24. Comandos de construcción ................................................................................. 27
Ilustración 25. Configuración de los comandos .......................................................................... 28
Ilustración 26. Creación de un nuevo programa ......................................................................... 30
Ilustración 27. Código predefinido .............................................................................................. 30
Ilustración 28. Botones de Geany ............................................................................................... 31
Ilustración 29. Compilación ......................................................................................................... 31
Ilustración 30. Resultado de ejecución ....................................................................................... 32
Ilustración 31. Comentarios ........................................................................................................ 32
Ilustración 32. Salida comentarios .............................................................................................. 32
Ilustración 33. Comentarios 2 ..................................................................................................... 33
Ilustración 34. Bloque de código ................................................................................................. 33
Ilustración 35. Punto y coma ....................................................................................................... 34
Ilustración 36. Primer ejemplo .................................................................................................... 35
Ilustración 37. Tipos de datos ..................................................................................................... 35
Ilustración 38. Tabla ASCII ........................................................................................................... 36
Ilustración 39. Nueva línea .......................................................................................................... 37
Ilustración 40. Ejemplo nueva línea ............................................................................................ 37
Ilustración 41. Ejemplo rango de datos....................................................................................... 38
Ilustración 42. Ejemplo rango de datos 2.................................................................................... 38
Ilustración 43. Variables no inicializadas..................................................................................... 38
Ilustración 44. Variables no inicializadas 2 .................................................................................. 39
Ilustración 45. Variables inicializadas 2 ....................................................................................... 40
Ilustración 46. Variables inicializadas .......................................................................................... 40

5
José A. Navarro Java desde 0. Programación I

Ilustración 47. Tipos de variable 2............................................................................................... 41


Ilustración 48. Tipos de variable ................................................................................................. 41
Ilustración 49. Constantes ........................................................................................................... 42
Ilustración 50. Operadores aritméticos ...................................................................................... 43
Ilustración 51. Salida operadores ................................................................................................ 43
Ilustración 52. División decimal................................................................................................... 44
Ilustración 53. Resultado división decimal .................................................................................. 44
Ilustración 54. Concatenación ..................................................................................................... 44
Ilustración 55. Ejemplo concatenado .......................................................................................... 44
Ilustración 56. Suma con asignación ........................................................................................... 45
Ilustración 57. Suma sin asignación ............................................................................................ 45
Ilustración 58. Post incremento .................................................................................................. 46
Ilustración 59.Pre incremento ..................................................................................................... 46
Ilustración 60. Resultado Pre incremento ................................................................................... 46
Ilustración 61. Resultado Post incremento ................................................................................. 46
Ilustración 62. Casting implícito .................................................................................................. 47
Ilustración 63. Casting explícito .................................................................................................. 47
Ilustración 64.Estructura del if .................................................................................................... 49
Ilustración 65.Primer if ................................................................................................................ 50
Ilustración 66. Ejecución primer if .............................................................................................. 50
Ilustración 67Ejecución del primer if 2........................................................................................ 50
Ilustración 68. Segundo if ............................................................................................................ 50
Ilustración 69. Ejecución segundo if ............................................................................................ 51
Ilustración 70. Tercer if ............................................................................................................... 51
Ilustración 71. Ejecución tercer if ................................................................................................ 52
Ilustración 72. Estructura completa del if ................................................................................... 52
Ilustración 73. Cuarto if ............................................................................................................... 52
Ilustración 74. Quinto if............................................................................................................... 53
Ilustración 75. If anidados ........................................................................................................... 53
Ilustración 76. Resultado if anidados 1 ....................................................................................... 53
Ilustración 77. Resultado if anidados 2 ....................................................................................... 54
Ilustración 78. Resultado if anidados 3 ....................................................................................... 54
Ilustración 79. Ejemplo sin identación ........................................................................................ 54
Ilustración 80. Operadores lógicos.............................................................................................. 56
Ilustración 81. Salida operadores lógicos .................................................................................... 56
Ilustración 82. Condiciones cortas .............................................................................................. 57
Ilustración 83. Operador ternario ............................................................................................... 58
Ilustración 84. Estructura switch ................................................................................................. 59
Ilustración 85. switch aprox1 ...................................................................................................... 59
Ilustración 86. Salida switch aprox1 ............................................................................................ 59
Ilustración 87. switch aprox2 ...................................................................................................... 60
Ilustración 88. Salida switch aprox2 ............................................................................................ 60
Ilustración 89.switch aprox3 ....................................................................................................... 60
Ilustración 90. Salida switch aprox3 ............................................................................................ 60
Ilustración 91. switch aprox4 ...................................................................................................... 61
Ilustración 92. Salida switch aprox4 ............................................................................................ 61
Ilustración 93. switch aprox5 ...................................................................................................... 61
Ilustración 94. Estructura while .................................................................................................. 62

6
José A. Navarro Java desde 0. Programación I

Ilustración 95. while aprox 1 ....................................................................................................... 62


Ilustración 96. Salida while aprox 1............................................................................................. 63
Ilustración 97. while aprox 2 ....................................................................................................... 63
Ilustración 98. Salida while aprox 2............................................................................................. 63
Ilustración 99. Estructura do ....................................................................................................... 64
Ilustración 100. do....................................................................................................................... 64
Ilustración 101. Estructura for .................................................................................................... 65
Ilustración 102. for ...................................................................................................................... 65
Ilustración 103. for inverso ......................................................................................................... 66
Ilustración 104. Condición con char ............................................................................................ 67
Ilustración 105. Salida condición char ......................................................................................... 67
Ilustración 106. Break.................................................................................................................. 68
Ilustración 107. API 1................................................................................................................... 70
Ilustración 108. API 2................................................................................................................... 70
Ilustración 109. API 3................................................................................................................... 71
Ilustración 110. API 4................................................................................................................... 71
Ilustración 111. API 5................................................................................................................... 71
Ilustración 112. API 6................................................................................................................... 72
Ilustración 113. Prueba Scanner ................................................................................................. 74
Ilustración 114. Salida Scanner ................................................................................................... 74
Ilustración 115. nextDouble()...................................................................................................... 75
Ilustración 116. Salida nextDouble() ........................................................................................... 75
Ilustración 117. Salida excepción ................................................................................................ 75
Ilustración 118. String ................................................................................................................. 76
Ilustración 119. Salida String ....................................................................................................... 77
Ilustración 120. For String ........................................................................................................... 77
Ilustración 121. Salida for String ................................................................................................. 77
Ilustración 122. Salida 2 for string ............................................................................................... 77
Ilustración 123. Vector 1 ............................................................................................................. 80
Ilustración 124. Salida vector 1 ................................................................................................... 80
Ilustración 125. Vector 2 ............................................................................................................. 81
Ilustración 126. Vector 3 ............................................................................................................. 82
Ilustración 127. Salida vector 3 ................................................................................................... 82
Ilustración 128. Vector 4 ............................................................................................................. 83
Ilustración 129. Salida vector 4 ................................................................................................... 83
Ilustración 130. Random ............................................................................................................. 83
Ilustración 131. Algoritmo de la burbuja .................................................................................... 84
Ilustración 132. Burbuja 1 ........................................................................................................... 84
Ilustración 133. Salida burbuja .................................................................................................... 84
Ilustración 134. Burbuja 2 ........................................................................................................... 85
Ilustración 135. Matriz 1 ............................................................................................................. 86
Ilustración 136. Salida Matriz 1 ................................................................................................... 86
Ilustración 137. Matriz 2 ............................................................................................................. 87
Ilustración 138. Salida matriz 2 ................................................................................................... 87
Ilustración 139. Matriz 3 ............................................................................................................. 87
Ilustración 140. Salida matriz 3 ................................................................................................... 88
Ilustración 141. Ejemplo void ...................................................................................................... 92
Ilustración 142. Salida void ......................................................................................................... 92

7
José A. Navarro Java desde 0. Programación I

Ilustración 143. Return ................................................................................................................ 92


Ilustración 144. Salida Return ..................................................................................................... 93
Ilustración 145. Parámetros formales y reales............................................................................ 93
Ilustración 146. Parámetros por valor......................................................................................... 94
Ilustración 147. Salida por valor .................................................................................................. 94
Ilustración 148. Parámetros por referencia ................................................................................ 96
Ilustración 149. Salida Parámetros por referencia...................................................................... 96
Ilustración 150. Recursividad ...................................................................................................... 98
Ilustración 151. Factorial iterativo .............................................................................................. 99
Ilustración 152. Primera aproximación clases........................................................................... 102
Ilustración 153. Test Clases 1 .................................................................................................... 103
Ilustración 154. Salida Clases 1 ................................................................................................. 103
Ilustración 155. Segunda aproximación clases.......................................................................... 105
Ilustración 156. Test Clases 2 .................................................................................................... 105
Ilustración 157. Salida clases 2 .................................................................................................. 105
Ilustración 158. Tercera aproximación...................................................................................... 106
Ilustración 159. Test Clases 3 .................................................................................................... 106
Ilustración 160. Constructor sin this ......................................................................................... 107
Ilustración 161. Constructor sin this, mal ................................................................................. 107
Ilustración 162. Constructor con this ........................................................................................ 108
Ilustración 163. Cuarta aproximación ....................................................................................... 109
Ilustración 164. Acceso erróneo................................................................................................ 110
Ilustración 165. Setter's y getter's............................................................................................. 111
Ilustración 166. Propiedad static............................................................................................... 112
Ilustración 167. Modificador final ............................................................................................. 113
Ilustración 168. Diagrama herencia .......................................................................................... 113
Ilustración 169. Factor común en herencia............................................................................... 114
Ilustración 170. Clases padre e hijas ......................................................................................... 114
Ilustración 171. Ejemplo clase padre ........................................................................................ 115
Ilustración 172. Clase hija 1 ....................................................................................................... 116
Ilustración 173. Clase hija 2 ....................................................................................................... 117
Ilustración 174. Clase hija 3 ....................................................................................................... 117
Ilustración 175. Ejemplo de main con herencia ........................................................................ 117
Ilustración 176. Diagrama animales .......................................................................................... 118
Ilustración 177. Sobreescritura ................................................................................................. 119
Ilustración 178. Sobrecarga....................................................................................................... 119
Ilustración 179. Sobrecarga 2 .................................................................................................... 120
Ilustración 180. Clase abstracta ................................................................................................ 121
Ilustración 181. Clase abstracta 2 ............................................................................................. 122
Ilustración 182. Producto .......................................................................................................... 123
Ilustración 183. Trigo................................................................................................................. 123
Ilustración 184. Leche ............................................................................................................... 123
Ilustración 185. Test Polimorfismo ........................................................................................... 124
Ilustración 186. Salida Polimorfismo ......................................................................................... 124
Ilustración 187. Trigo 2 .............................................................................................................. 125
Ilustración 188. Leche 2 ............................................................................................................ 125
Ilustración 189.Error Polimorfismo ........................................................................................... 125
Ilustración 190Error Polimorfismo 2 ......................................................................................... 126

8
José A. Navarro Java desde 0. Programación I

Ilustración 191. instanceof ........................................................................................................ 126


Ilustración 192. toString ............................................................................................................ 128
Ilustración 193. Ejemplo toString .............................................................................................. 128
Ilustración 194. toString correcto ............................................................................................. 129
Ilustración 195. equals 1 ........................................................................................................... 130
Ilustración 196. equals 2 ........................................................................................................... 130
Ilustración 197. Salida equals 2 ................................................................................................. 130
Ilustración 198. Asignación a Objetos ....................................................................................... 133
Ilustración 199. Asignación a Objetos 2 .................................................................................... 133
Ilustración 200. Salida Asignación a Objetos............................................................................. 134
Ilustración 201. Constructor copia ............................................................................................ 135
Ilustración 202. Main constructor copia ................................................................................... 135
Ilustración 203. Salida constructor copia .................................................................................. 136
Ilustración 204. wrapper's ......................................................................................................... 136
Ilustración 205. interface .......................................................................................................... 137
Ilustración 206. implements...................................................................................................... 138
Ilustración 207. Herencia e implementación ............................................................................ 138
Ilustración 208. Interfaces como tipos 1 ................................................................................... 138
Ilustración 209. Interfaces como tipos 2 ................................................................................... 139
Ilustración 210. Interfaces como tipos 3 ................................................................................... 139
Ilustración 211. Interfaces como tipos 4 ................................................................................... 139
Ilustración 212. Salida Interfaces como tipos ........................................................................... 139
Ilustración 213. Métodos por defecto 1.................................................................................... 140
Ilustración 214. Métodos por defecto 2.................................................................................... 140
Ilustración 215. Métodos por defecto 3.................................................................................... 140
Ilustración 216. Salida Métodos por defecto ............................................................................ 140
Ilustración 217. Métodos por defecto 4.................................................................................... 141
Ilustración 218. Salida Métodos por defecto 4 ......................................................................... 141
Ilustración 219. Expresiones Lambda 1 ..................................................................................... 142
Ilustración 220. Expresiones Lambda 2 ..................................................................................... 142
Ilustración 221. Salida Expresiones Lambda 2 .......................................................................... 142
Ilustración 222. Expresiones Lambda 3 ..................................................................................... 142
Ilustración 223. Expresiones Lambda 4 ..................................................................................... 142
Ilustración 224. Salida Expresiones Lambda 4 .......................................................................... 143
Ilustración 225. Expresiones Lambda 5 ..................................................................................... 143
Ilustración 226. Expresiones Lambda 6 ..................................................................................... 143
Ilustración 227. Salida Expresiones Lambda 6 .......................................................................... 143
Ilustración 228. compareTo ...................................................................................................... 144
Ilustración 229. Prueba compareTo .......................................................................................... 145
Ilustración 230. Extracto de métodos Math.............................................................................. 149
Ilustración 231. Ejemplo Math .................................................................................................. 150
Ilustración 232. Salida Math...................................................................................................... 150
Ilustración 233. Ejemplo ArrayList 1.......................................................................................... 151
Ilustración 234. Ejemplo ArrayList 2.......................................................................................... 153
Ilustración 235. Salida Ejemplo ArrayList 2 ............................................................................... 153
Ilustración 236. Ejemplo ArrayList 3.......................................................................................... 153
Ilustración 237. Salida Ejemplo ArrayList 3 ............................................................................... 153
Ilustración 238. Ejemplo ArrayList 4.......................................................................................... 154

9
José A. Navarro Java desde 0. Programación I

Ilustración 239. Salida Ejemplo ArrayList 4 ............................................................................... 154


Ilustración 240. Ejemplo for each ............................................................................................. 154
Ilustración 241. Salida Ejemplo for each ................................................................................... 155
Ilustración 242. Ejemplo de iterador......................................................................................... 156
Ilustración 243. Salida Ejemplo de iterador .............................................................................. 156
Ilustración 244. Ejemplo ArraList 5 ........................................................................................... 156
Ilustración 245. Test Ejemplo ArraList 5 .................................................................................... 157
Ilustración 246. Salida Ejemplo ArraList 5 ................................................................................. 157
Ilustración 247. wrappers.......................................................................................................... 157
Ilustración 248. Ejemplo de excepción ..................................................................................... 158
Ilustración 249. Jerarquía de excepciones ................................................................................ 158
Ilustración 250. Excepciones 1 .................................................................................................. 159
Ilustración 251. Salida Excepciones 1 ........................................................................................ 159
Ilustración 252. Excepciones 2 .................................................................................................. 159
Ilustración 253. Salida excepciones 2........................................................................................ 159
Ilustración 254. Excepciones 3 .................................................................................................. 160

Índice de tablas
Tabla 1. Variables, memoria 1 ..................................................................................................... 40
Tabla 2. Variables, memoria 2 ..................................................................................................... 40
Tabla 3. Variables, memoria 3 ..................................................................................................... 40
Tabla 4. Variables, memoria 4 ..................................................................................................... 41
Tabla 5. Ejemplos de tipos letra .................................................................................................. 41
Tabla 6. Operadores aritméticos ................................................................................................. 42
Tabla 7. Operadores de asignación ............................................................................................. 45
Tabla 8. Operadores de incremento ........................................................................................... 45
Tabla 9 Prioridad de operadores ................................................................................................. 47
Tabla 10. Operadores de comparación ....................................................................................... 51
Tabla 11. Operadores lógicos ...................................................................................................... 55
Tabla 12. Tabla de verdad AND y OR........................................................................................... 55
Tabla 13.Tabla NOT ..................................................................................................................... 55
Tabla 14. Tabla XOR..................................................................................................................... 56
Tabla 15.Ejemplo parámetros por valor 1................................................................................... 94
Tabla 16. Ejemplo parámetros por valor 2 .................................................................................. 95
Tabla 17. Ejemplo parámetros por valor 3 .................................................................................. 95
Tabla 18. Ejemplo parámetros por valor 4 .................................................................................. 95
Tabla 19. Ejemplo parámetros por valor 5 .................................................................................. 95
Tabla 20. Ejemplo parámetros por valor 6 .................................................................................. 96
Tabla 21. Ejemplo parámetros por referencia 1 ......................................................................... 97
Tabla 22. Ejemplo parámetros por referencia 2 ......................................................................... 97
Tabla 23. Ejemplo parámetros por referencia 3 ......................................................................... 97
Tabla 24. Ejemplo parámetros por referencia 4 ......................................................................... 97
Tabla 25. Modificadores de acceso ........................................................................................... 109
Tabla 26. Clase Math ................................................................................................................. 149
Tabla 27. Métodos ArrayList ..................................................................................................... 152

10
José A. Navarro Java desde 0. Programación I

1. Introducción
Este manual ha sido realizado en base a la experiencia en la explicación de la asignatura
de programación en CGFS a alumnos que no han programado nunca y se encuentran con un
lenguaje orientado a objetos. No trato de que los alumnos no atiendan las explicaciones de sus
profesores, sino de darles una base aclaratoria desde 0.

El manual está basado en una serie de aproximaciones hasta llegar a comprender la POO.
Para ello está dividido en tres grandes partes:

1. Programar funcionalmente desde un punto de vista algorítmico. Viendo lo


indispensable para comenzar a resolver problemas.
2. Añadir métodos y clases, acercándonos ya a la POO.

3. Explicar la herencia, abstracción y demás conceptos de la POO.

Obviamente al explicar un lenguaje orientado a objetos nos encontramos con que hay
cosas que hay que explicar pero que no es el momento por la dificultad que comportan. Sólo
cuando se ha visto todo se cierra el círculo y tenemos una visión completa.

He usado aproximaciones hasta llegar a la solución final de forma que el alumno vea todo
lo que sucede, de ahí la cantidad de ejemplos.

Mi misión es enseñar a programar no a ser copistas de código o codificadores. En ningún


momento mi función es enseñar el uso de una API. Durante toda mi experiencia como profesor
me he encontrado gente, con titulación, que no sabe lo que es un vector, sólo conocen algo
llamado ArrayList. Me parece una aberración, antes de ir en moto hay que aprender a ir en
bicicleta, sólo así podemos comprender el funcionamiento de las cosas para sacarles el mayor
partido. Obviamente uso y explico cosas de la API, pero luego, este es un manual inicial, habrá
más de mayor dificultad.
Solo aprenderéis a programar haciendo ejercicios, primero en papel y boli. Si no lo hacéis
así se aprende por prueba y error (hasta que compile) por tanto no sabéis programar, sabéis
probar cosas hasta dar con una que funcione. Debéis de poder leer un código en papel y decir si
va a funcionar o no.

11
José A. Navarro Java desde 0. Programación I

2. Lenguajes de programación
2.1 Tipos
Un lenguaje de programación es un lenguaje que puede ser utilizado para controlar el
comportamiento de una máquina, particularmente una computadora. Permite especificar de
manera precisa sobre qué datos se tiene que operar, cómo deben ser estos almacenados,
transmitidos y qué acciones se debe tomar bajo una variada gama de circunstancias.

Según la dependencia de la máquina en la que se ejecutan los podemos caracterizar por:

 Lenguajes de bajo nivel


o Fuerte dependencia de la máquina.

o Muy alejados de nuestro modo de razonar.

o Difíciles de aprender, entender y manipular.

Lenguaje Maquina: Código binario, juego de instrucciones, modos de direccionamiento,


operandos …

Ilustración 1. Ejemplo código máquina

Lenguaje ensamblador: Usa códigos mnemotécnicos haciendo más fácil de leer los
programas. Siguen siendo difíciles y dependientes de la máquina.

Ilustración 2. Ejemplo ensamblador

Se puede ver como no son fáciles de usar.

 Lenguajes de alto nivel

o Mayor independencia de la máquina.

o Más cercanos al lenguaje humano.

o Fortran, Lisp, Algol, Cobol, Basic, Pascal, C.

12
José A. Navarro Java desde 0. Programación I

Ej. Python

Ilustración 3. Ejemplo Python

En este ejemplo, sin tener conocimientos de python igualmente podemos entender que
se pide un número y que dependiendo de si es mayor o menor de 0 se muestra un mensaje
distinto.
Dentro de los lenguajes de alto nivel también nos podemos encontrar con varios tipos
según el paradigma que usen: procedimentales, declarativos, funcionales…

Este manual se centra en Java que es un lenguaje orientado a objetos (en adelante POO).
Estos lenguajes estrechan la relación entre código y datos. Ofrecen un mayor nivel de
abstracción. Desde que comenzaron a salir lenguajes con POO se han ido añadiendo distintas
características, pero hay tres que, bajo mi punto de vista, hacen que se le pueda llamar POO o
no. Estas son:

 Herencia: Capacidad de establecer relaciones jerárquicas entre objetos.

 Polimorfismo: Una operación puede adoptar diferentes formas.

 Encapsulación: Damos a conocer solo aquellos detalles de los objetos que son
pertinentes, ocultando como se han implementado.

Independientemente del tipo de lenguaje según las características vistas, estos pueden
ser interpretados o compilados, dependiendo del proceso de traducción que se realice. La CPU
solo entiende código máquina, por lo que hay que traducir el programa fuente, programado en
uno de los lenguajes existentes, en código máquina para que pueda ser ejecutado.

 Intérpretes: traducen instrucción a instrucción conforme lo necesitan.

 Compiladores: traducen todo el programa creando un programa objeto en lenguaje


máquina.

Cada uno tiene sus pros y sus contras. Un lenguaje compilado traduce una sola vez todo
el código y son más rápidos en ejecución. Los interpretados si una instrucción se repite varias
veces la interpretan cada vez ya que va traduciendo línea a línea mientras se ejecuta. Por el
contrario son más fáciles de depurar. Hoy en día, dada la capacidad de computo de los
ordenadores, no es tan importante la velocidad de ejecución, de hecho cada vez surgen más
lenguajes interpretados o mixtos como es Java.

13
José A. Navarro Java desde 0. Programación I

Ejemplo de lenguaje compilado: C

Ilustración 4. Compilador C

Ejemplo de lenguaje interpretado: Python

Ilustración 5. Interprete Python

Java: Java es un lenguaje que compila generando un código intermedio (bytecode) que se
ejecuta en un entorno interpretado llamado Máquina Virtual Java. Un programa realizado en
Java se puede ejecutar en cualquier ordenador tenga el sistema operativo que tenga siempre
que este instalada la máquina virtual.

14
José A. Navarro Java desde 0. Programación I

Ilustración 6. Compilador Java

2.2 Programación estructurada


A lo largo de la historia de la programación ha habido distintas técnicas de programación:
convencional, modular… En este manual sólo voy a céntrame en la programación estructurada
que, independientemente de que tengamos módulos en nuestro programa, es la que debemos
de usar.
Esta técnica establece que un programa bien estructurado debe cumplir las siguientes
condiciones:

 Deberá contener en su código información suficiente para ser comprendido sin


necesidad de información adicional.

 Las distintas partes de las que consta un programa deberán ser modificadas o cambiadas
sin que esto afecte al resto del programa.

 El programa podrá ser desarrollado por partes fácilmente ensamblables.

Elementos de la programación estructurada

 Razonamiento deductivo: resolución de un problema por medio de pasos consecutivos,


donde la salida de un paso será la entrada de otro. Refinamiento. Divide y vencerás

 Recursos abstractos: transformar los recursos abstractos en recursos concretos, las


ideas en instrucciones.

 Estructuras básicas: un programa puede desarrollarse usando solamente tres


estructuras básicas:
o Estructura secuencial: secuencia de acciones que se ejecutan una detrás de
otra.

o Estructura alternativa: permite que se ejecuten una serie de instrucciones


dependiendo de si se cumple o no una determinada condición.

15
José A. Navarro Java desde 0. Programación I

o Estructura repetitiva: permite la ejecución repetida de un grupo de


instrucciones un número determinado de veces o hasta que se cumpla una
condición.
Ventajas de la programación estructurada

 Ahorro de tiempo en la labor de codificación.

 Facilidad de localización y corrección de errores.

 Programas sencillos y rápidos.

 Programas fáciles de leer y entender.

 Programas bien documentados.

16
José A. Navarro Java desde 0. Programación I

3. Lo primero que tenemos que aprender

 No hay ningún lenguaje mejor que otro: No perdáis el tiempo en guerras inútiles entre
lenguajes. Hay lenguajes más nuevos o más populares, pero no mejores. Cada lenguaje
es adecuado para un contexto o tipo de aplicación determinado. No hay ninguno que
sea mejor que todos los demás de forma absoluta. No dejéis que el marketing os engañe.

 Tú no eres tu código: Tendemos a relacionar nuestra valía personal con la calidad del
código que escribimos. Y eso es un error. Si mi autoestima dependiera de lo bueno que
es el código que yo escribo, hace tiempo que me hubiera tirado a la vía del tren. Esto se
aplica también a la inversa. No vayas tan rápido en evaluar la calidad de un programador
mirando su código. No sabes en qué condiciones tuvo que escribirlo (a lo mejor parte lo
heredó de otro, el tiempo asignado...)

 Más no es mejor: No seas una máquina de “vomitar” código. Sé una máquina de


solucionar problemas. Y si es con poco código aún mejor.

 Leerás más código del que nunca vas a programar: Pocas veces tendrás la oportunidad
de programar algo de cero. Incluso en esos casos dependerás de librerías y servicios de
terceros.

 El 99% de los tiempos estarás colaborando en un proyecto ya en marcha (o depurando


uno viejo...).

 Programar es mucho más que escribir código: Programar es una actividad social. Eso
del programador encerrado en su cubículo es un mito. Programar requiere entender
bien los requisitos de lo que vas a programar, el contexto en que se va a utilizar el
programa, el perfil del usuario, ... Para ser un buen programador tienes que desarrollar
no sólo código sino también habilidades sociales.

 Nunca escribirás un código perfecto: El código perfecto no existe. Nadie ha creado


nunca un código perfecto, no vas a ser tú el primero. Intentarlo te puede llevar al grave
problema de la optimización prematura donde, en la búsqueda de la perfección, acabas
escribiendo un montón de código inútil. Inútil porque intenta prever posibles problemas
(ej. de escalabilidad) que a día de hoy no existen y que puede que nunca lleguen. Una
cosa es definir un código bien legible y fácil de extender y la otra perder el tiempo
preparando el código en previsión de una guerra nuclear.

 Hay muchas formas de solucionar un problema e infinitas de no hacerlo.

17
José A. Navarro Java desde 0. Programación I

4. ¿Qué es Java?
Java es un lenguaje orientado a objetos de propósito general. Aunque Java comenzara a
ser conocido como un lenguaje de programación de applets que se ejecutan en el entorno de
un navegador web, hoy en día se puede utilizar para construir cualquier tipo de proyecto.

Su sintaxis es muy parecida a la de C y C++ pero hasta ahí llega el parecido. Java no es una
evolución ni de C++ ni un C++ mejorado.

Los padres de Java son James Gosling (emacs) y Bill Joy (Sun). Java desciende de un
lenguaje llamado Oak.

Los criterios de diseño de Java fueron:

 Independiente de la máquina.

 Seguro para trabajar en red.

 Potente para sustituir código nativo.

En el diseño de Java se prestó especial atención a la seguridad. Existen varios niveles de


seguridad en Java, desde el ámbito del programador, hasta el ámbito de la ejecución en la
máquina virtual.

Java realiza comprobación estricta de tipos durante la compilación (fuertemente tipado),


evitando con ello problemas tales como el desbordamiento de la pila. Pero, es durante la
ejecución donde se encuentra el método adecuado según el tipo de la clase receptora del
mensaje.
Todas las instancias de una clase se crean con el operador new, de manera que un
recolector de basura se encarga de liberar la memoria ocupada por los objetos que ya no están
referenciados. La máquina virtual de Java gestiona la memoria dinámicamente.

Java también posee mecanismos para garantizar la seguridad durante la ejecución


comprobando, antes de ejecutar código, que este no viola ninguna restricción de seguridad del
sistema donde se va a ejecutar.

Otra característica de Java es que está preparado para la programación concurrente sin
necesidad de utilizar ningún tipo de biblioteca.

Finalmente, Java posee un gestor de seguridad con el que poder restringir el acceso a los
recursos del sistema.

18
José A. Navarro Java desde 0. Programación I

5. Preparación de nuestro entorno de desarrollo


Hoy en día los programadores usan entornos de desarrollo (en adelante IDE) que les
ayudan en su tarea. Entre las características de estos entornos podemos encontrar:

 Editor de texto con colores.

 Compilador.

 Intérprete.

 Herramientas de automatización.

 Depurador.

 Posibilidad de ofrecer un sistema de control de versiones.

 Factibilidad para ayudar en la construcción de interfaces gráficas de usuario.

 Refactorización.

 Autocomplementado de código.

Entre los IDE más usados para programar con Java están: Netbeans, Eclipse, IntelliJ…
El problema de usar uno de estos IDE para aprender y dar los primeros pasos es que hacen
muchas cosas solos, nosotros conseguimos que nuestros programas funcionen pero no sabemos
cómo ni porqué ya que ha sido el IDE el que nos ha corregido errores o nos ha dicho como
escribirlo. Por ello nosotros vamos a usar otro IDE más liviano pero muy conocido, compatible
con Java, C, C++, PHP, Python… que es Geany. A Geany se le pueden añadir plugins para
ayudarnos en todo lo comentado anteriormente, cosa que no haremos.

5.1 Instalando Java


5.1.1 JDK
Para poder programar en java debemos de instalar el JDK (Java Development Kit). El JDK
contiene herramientas de consola y herramientas de compilación que pueden ser usadas por un
IDE. El JDK incluye también el JRE (Java Runtime Environment) que contienen las librerías de
clase y la MVJ. Entre los comandos que contiene el JDK podemos citar:

 java: La máquina virtual.

 javac: El compilador.

 javadoc: generador de documentación.

Para instalar el JDK lo primero es bajárnoslo de la web de Oracle:


https://www.oracle.com/java/technologies/downloads/

19
José A. Navarro Java desde 0. Programación I

Con Java 9, Oracle se comprometió a lanzar una nueva versión de Java cada 6 meses, y de
momento lo está cumpliendo. Con el lanzamiento de Java 11 hay cambio de licencia y el
soporte a largo plazo (LTS) asegurado para el JDK. Por tanto, los JDK no son gratuitos. El JDK
11 inicia una nueva era en la licencia de uso. Hasta ahora podías descargar y programar con
el Kit de Desarrollo de Java oficial de Oracle y luego poner tu aplicación en producción o
distribuirla sin tener que pagar nada al gigante del software. Sin embargo, a partir de Java
11 y del JDK 11, aunque puedes seguir desarrollando con él, tendrás que pagar una licencia
a Oracle si quieres utilizarlo para poner las aplicaciones en producción. El coste es de 2,5
dólares al mes por cada usuario de escritorio, y de 25 dólares por procesador en el caso de
aplicaciones de servidor. Esto no afecta a versiones anteriores del JDK, por lo que, si usas
Java 8, 9 o 10 sigue siendo gratuito.

Sin embargo, sabiendo los cambios de licencias que estaban preparando, Oracle ha
trabajado para hacer que el OpenJDK se haya equiparado en todos los aspectos al JDK, hasta
el punto de que se puede decir que el OpenJDK y el JDK son idénticos desde un punto de
vista técnico, desde la versión 11. Por tanto podemos usar OpenJDK.

Nosotros vamos a usar el JDK 8 que es más que suficiente para aprender a programar y
para nuestros intereses, Es una versión LTS y que además sigue siendo gratuita.
La podéis descargar en este enlace:

https://www.oracle.com/es/java/technologies/javase/javase8-archive-downloads.html
Es importante descargar la adecuada para nuestro sistema operativo (32 o 64 bits). Se nos
pedirá que nos registremos, no hay problema es gratuito y podemos desactivar las
notificaciones.

Una vez descargado el JDK procedamos a su instalación. Lo ejecutamos y seguimos las


instrucciones que nos van saliendo en pantalla:

Ilustración 7. Instalador JDK

20
José A. Navarro Java desde 0. Programación I

Ilustración 8.Instalación JDK

Ilustración 9.Instalación JDK 2

Ilustración 10. Fin instalación JDK

21
José A. Navarro Java desde 0. Programación I

Una vez instalado debemos de modificar dos variables de entorno para que Geany
encuentre la MVJ y el compilador, así como la carpeta de clases.
1. Copiamos la ruta hasta la carpeta bin del JDK:

Ilustración 11. Carpeta BIN

2. Entramos en las variables de entorno de Windows y la añadimos al path:

Para acceder pulsamos el botón derecho sobre propiedades del equipo.

Ilustración 12. Propiedades equipo

Seleccionamos la configuración avanzada del sistema:

22
José A. Navarro Java desde 0. Programación I

Ilustración 13. Configuración avanzada

Pulsamos en variables de entorno:

Ilustración 14. Variables de entorno

Seleccionamos la variable path y la editamos:

23
José A. Navarro Java desde 0. Programación I

Ilustración 15. Variables de entorno 2

Creamos una nueva y pegamos la ruta que habíamos copiado

Ilustración 16. Añadir variable de entorno

Ahora solo nos queda indicar la carpeta de librerías. Si la variable CLASSPATH no existe la
creamos (lo normal) si existe añadimos la carpeta lib. En este caso con poner un simple “.” es
suficiente, Geany la encontrará.

24
José A. Navarro Java desde 0. Programación I

Ilustración 17. Classpath

Ilustración 18. Classpath 2

5.1.2 Geany
Para instalar el IDE que usaremos lo primero es descargar la última versión:

https://www.geany.org/download/releases/

Aunque voy a mostrar la instalación de la versión 1.34 a fecha de la publicación de este


manual ya se encuentra disponible la 1.38, eso sí, solo con versión de 64 bits.

La ejecutamos:

25
José A. Navarro Java desde 0. Programación I

Ilustración 19. Instalación de Geany

Ilustración 20. Instalación de Geany 2

Ilustración 21. Icono de Geany

Archivo
ss
Donde escribimos el código

Resultados de compilación y mensajes

Ilustración 22. Entorno del IDE

26
José A. Navarro Java desde 0. Programación I

Para comprobar que se ha instalado correctamente vamos a comprobar los comandos de


ejecución de Geany. Creamos un fichero java nuevo y comprobamos en el menú
correspondiente:

Ilustración 23. Crear una nueva clase

Ilustración 24. Comandos de construcción

Podemos ver como en los comandos de ejecución de llama al comando javac para
compilar y java para ejecutar. Todo está correcto.

27
José A. Navarro Java desde 0. Programación I

Ilustración 25. Configuración de los comandos

28
José A. Navarro Java desde 0. Programación I

6. Comenzando
Como ya hemos visto Java es un lenguaje orientado a objetos. En este manual no voy a
comenzar a explicar directamente POO sino que vamos a realizar una serie de aproximaciones
hasta llegar a la POO pura. Primero usaremos Java como si fuera un lenguaje sin métodos o
funciones y aprenderemos las estructuras básicas de la programación estructurada
“cuadriculando” nuestra mente, pensando en soluciones a problemas desde un punto de vista
algorítmico. Luego introduciremos el concepto de métodos, clases y objetos acercándonos ya a
la POO. Una vez visto esto añadiremos los conceptos de herencia, polimorfismo, interfaces,
clases abstractas y alguna estructura dinámica de la API.
Este manual no está pensado como un texto extremadamente largo de teoría sino más
bien como un manual práctico que cualquiera desde cero puede seguir.

El hecho de que Java sea un leguaje orientado a objetos puro hace imposible no usar
objetos desde el principio como en Python o PHP y luego ver la POO, por eso voy a hacer una
introducción bastante simple del funcionamiento, que ya en la segunda parte explicaré más
detenidamente. También me gustaría aclarar que NO todo lo que voy a explicar es la verdad y
voy a omitir ciertos aspectos hasta su momento. ¿Por qué? Muy simple, para aquella gente que
no ha programado nunca y comienza con la POO les resultan confusos algunos términos, estos
los voy explicando poco a poco formando un circulo virtual que sólo cuando se cierra se tiene
una comprensión completa.

Como ya he dicho sólo hay una forma de aprender a programar: haciendo muchos
ejercicios y enfrentándote a ellos sin copiar la solución. Debéis de tener en cuenta que a la hora
de aprender a programar tenéis dos problemas: el primero es conseguir la idea feliz que resuelve
el problema (cuadricular la mente) y el segundo es aprender la sintaxis del lenguaje que vais a
usar, en este caso Java. En cada capítulo os dejaré ejercicios para practicar. ¿Cómo afrontar un
problema? Con lápiz y papel. Primero debéis de haceros un esquema en papel, usando
diagramas, pseudocódigo o Java de cómo pensáis resolver el ejercicio. Después repasad la hoja,
encontrareis errores, corregidlos. Solo cuando hayáis pasado estas dos fases podéis codificar el
problema en el ordenador. Es imposible codificar la solución a un problema si no sabéis como
abordarlo.

Todos mis exámenes, de programación I, son escritos, en papel. Un programador debe de


saber lo que puede o no funcionar sin probarlo, por lo menos lo más importante, si realizamos
todos los ejercicios con el ordenador pueden funcionar por prueba y error. Debemos de ser
programadores no codificadores de códigos que vamos encontrando por internet formando algo
totalmente ilegible.

Bien, como suele ser habitual comencemos por hacer el famoso “hola mundo” y a partir
de ahí iré explicando las cosas que debemos de saber desde el principio.

La forma más rápida para crear un programa en java es partir de la pestaña nuevo
seleccionando main.java:

29
José A. Navarro Java desde 0. Programación I

Ilustración 26. Creación de un nuevo programa

Ilustración 27. Código predefinido

30
José A. Navarro Java desde 0. Programación I

En el panel de la izquierda podemos ver las clases que tenemos abiertas junto con la línea
en la que se declara y donde se encuentra el main.

En java todo el código se crea en unas “plantillas” llamadas clases1. Estas clases se tienen
que corresponder con un fichero. El fichero y la clase se deben de llamar igual. El main es un
método especial de Java, de momento le llamaremos “programa principal”. Todo lo que
queramos que Java ejecute debe de estar dentro del main.

En la línea 24 se declara la clase usando la siguiente sintaxis: la palabra reservada2 public,


indicando que todo el mundo lo puede ejecutar, seguida de class que indica que estamos
definiendo una clase cuyo nombre aparece justo a su derecha.

1. En el panel horizontal de abajo sale lo que ha sucedido: Se ha abierto un fichero, se ha


guardado con el nombre Holamundo…

2. En la línea 26 se declara el main o programa principal siempre comienza por public (todo
el mundo lo puede ejecutar) seguido de static final, que explicaré en próximos capítulos
(de momento se pone siempre). Después aparece en rojo la palabra void (sin retorno, lo
veremos más adelante) seguida de main. Siempre debe de llamarse main si no Java no
sabrá que ejecutar. Después del main vienen unos argumentos entre paréntesis que
entenderéis más adelante. Lo que se encuentra entre llaves en el main es lo que Java
ejecuta.

3. En la línea 28 se encuentra el código que muestra por pantalla la frase “hola mundo”.
Ese código lo veremos más adelante, pero veamos lo que sucede.

Ilustración 28. Botones de Geany

Primero pulsamos en el botón compilar para que Java compruebe si hay errores de
sintaxis y si todo está correcto.

Ilustración 29. Compilación

En la pestaña compilador nos aparece la orden javac y nos dice que ha compilado
correctamente sin encontrar ningún problema. Si pulsamos ahora en ejecutar lo ejecutará

1
Veremos esto con más detenimiento en la segunda parte del manual
2
Una palabra reservada es una palabra que tiene sentido para Java y que el compilador entiende. En
Geany suelen pintarse de azul.

31
José A. Navarro Java desde 0. Programación I

mediante el comando java mostrando el resultado en una ventana de consola y esperando hasta
pulsar intro o que la cerremos.

Ilustración 30. Resultado de ejecución

Se muestra el resultado de la ejecución que no es más que mostrar por pantalla la frase
“Hola Mundo”.

Expliquemos un poco más el código:

Lo primero que nos llama la atención son un montón de líneas rojas. Esas líneas son
comentarios que añade Geany al crear un fichero nuevo usando el método que os he
comentado, las podemos borrar. Pero, ¿Qué es un comentario? Un comentario es cualquier
código al cual el compilador no hará ni caso. Sirve para poner anotaciones que nos ayuden a
entender el código más adelante o a que lo entienda otra persona. Los comentarios en Java se
escriben de la siguiente forma:

 Usando // lo que hace que toda la línea sea un comentario

 Usando /* y */ lo que hace que lo que se encuentra entre esos caracteres se tome
como un comentario.

Veamos un ejemplo:

Ilustración 31. Comentarios

El compilador no va a ejecutar la línea 1, 2, 8 ni 10. Fijaros que la línea 10 pese a que tiene
código valido el compilador no la ejecuta al ser un comentario.

Ilustración 32. Salida comentarios

32
José A. Navarro Java desde 0. Programación I

De esto podemos deducir que si estamos intentando buscar un error podemos comentar
líneas para que no se ejecuten en vez de borrarlas y tenerlas que volver a escribir. Cuando en
Geany usamos la forma multilínea y pulsamos intro en cada una suele añadir un * para resaltarla.

Ilustración 33. Comentarios 2

Hay autores/profesores que dicen que el uso de comentarios está mal


porque el código debe de ser lo suficientemente comprensible sin la
necesidad de apuntes externos ni comentarios. Yo no voy a entrar en
discusión, cada cual que haga lo que quiera, pero sí os voy a decir que el
uso de comentarios os sacará de más de un apuro cuando después de tres
años de haber hecho un módulo tengáis que cambiar algo o cuando
tengáis que modificar código que no es vuestro. Obviamente todo tiene
su punto, no me parece bien el no usarlos pero tampoco llenar el código
de comentarios inútiles. “aquí declaro una variable entera” a ver, hasta
ahí llega cualquier programador.

Otro símbolo que podemos ver en el código son las llaves {}. Todo lo que se encuentra
entre llaves es un bloque de código. De momento nos sobra con saber que después de declarar
una clase se abren llaves al igual que con el main, al finalizar se cierran.

Ilustración 34. Bloque de código

La llave de la línea 9 cierra la de la 5 y la de la 10 cierra la de la clase, 3.

En Java todas las líneas, excepto declaraciones y otras especiales que veremos, terminan
con ;

33
José A. Navarro Java desde 0. Programación I

Ilustración 35. Punto y coma

Pese que no forma parte de la sintaxis de Java es de buena praxis y denota


conocimiento del lenguaje que las clases comiencen por mayúsculas.

Java es sensible a las mayúsculas, por tanto no es lo mismo A que a, tanto


en el código como en el nombre de los ficheros y clases, diga lo que diga
Windows.

34
José A. Navarro Java desde 0. Programación I

7. Conceptos iniciales
Una de las primeras cosas que podemos realizar en un programa son operaciones.
Veamos un ejemplo de una suma:

Ilustración 36. Primer ejemplo

Estamos mostrando por pantalla el resultado de sumar 2 y 3, se mostrará 5.

Los números aparecen en verde porque son literales: el número 2 y el número 3, y siempre
serán esos dos números. En Java los literales pueden ser tipos de datos primitivos, cadenas de
texto o el valor null3.

Los tipos primitivos son tipos de datos que forman parte del propio lenguaje, están
definidos en él y no necesitan de importar ninguna librería. Los tipos primitivos de Java son:

Ilustración 37. Tipos de datos

Tenemos cuatro tipos de enteros y dos tipos de números reales o decimales. Cuando más
bits más grandes pueden ser.

Como podemos ver un carácter no es más que un entero de tipo short, de ahí que sea
muy fácil pasar de carácter a entero y viceversa. Un carácter no es más que un símbolo asociado
a un número entero. En Java se usa Unicode no obstante voy a mostrar el ejemplo con la tabla
ASCII ya que es más fácil de entender y es totalmente compatible:

3
Lo veremos más adelante

35
José A. Navarro Java desde 0. Programación I

Ilustración 38. Tabla ASCII

Como podéis ver al carácter ‘A’ le corresponde el número 65, a la ‘a’ el 97 y luego hay una
serie de caracteres “extraños” y no imprimibles que también tienen su equivalencia en entero.
En Java un carácter siempre va entre comillas simples: ‘a’

Existe un tipo especial y muy importante en programación llamado booleano y que solo
puede contener dos posibles valores: verdadero o falso. No puede haber otra opción. En Java se
escriben en inglés: true o false.

En Java existe un tipo de datos NO primitivo, realmente es una clase pero se usa tanto
que quiero introducirlo aquí y es el String (la S en mayúscula). Esta clase es tan usada que Java
permite crear String’s de una forma similar a un tipo primitivo. Un String no es más que una
cadena de texto (uno o más caracteres) y se ponen entre comillas dobles, por ejemplo “hola
mundo”.

Caracteres de escape: Java al igual que otros lenguajes tiene una serie de caracteres
especiales que se pueden usar anteponiendo el carácter de escape \ (contrabarra):

Secuencia de escape Descripción


\t Un tabulador
\b Un retroceso
\n Un carácter de nueva línea
\r Un retorno de carro
\f Un salto de línea
\' Una comilla simple
\" Una comilla doble
\\ Un carácter de barra invertida
Tabla 1. Caracteres de escape

Veamos un ejemplo con el más usado que es nueva línea y de paso comprenderemos
mejor la línea que uso para imprimir por pantalla.

36
José A. Navarro Java desde 0. Programación I

Pensemos que en Java existe “algo” llamado System que nos permite hacer algunas cosas.
Una de ellas es la comunicación con el exterior existiendo tres subapartados de ese System:

 in: Entrada estándar. De forma predefinida el teclado.

 out: Salida estándar. De forma predefinida la pantalla.

 err: Salida estándar para errores. De forma predefinida la pantalla.

Por tanto, cuando usamos System.out lo que estamos diciendo es que dirija la información
a la pantalla. Dentro de ese System.out existen una serie de métodos4 que nos permiten imprimir
por pantalla, uno de ellos el println. Veamos:

Ilustración 39. Nueva línea

Ilustración 40. Ejemplo nueva línea

 Línea 7: Muestra “hola” y luego introduce una nueva línea al usar println.

 Línea 9: Muestra “Pepe” y luego no introduce una nueva línea al usar print.

 Línea 10: Muestra “Pedro” y luego no introduce una nueva línea al usar print. Como
antes no hemos introducido una línea nueva se escribe en la misma sin separación.

 Línea 13: Muestra “Eva” y luego introduce una nueva línea al usar “\n”. Como antes no
hemos introducido una línea nueva se escribe en la misma sin separación.

 Línea 14: Muestra “Pablo” y luego introduce una nueva línea al usar “\n”. Como antes
hemos introducido una línea nueva se escribe debajo.

Cuando Java ve la contrabarra sabe que viene un carácter especial y lo interpreta. Los
caracteres especiales como son texto también se pueden concatenar como luego veremos.

4
Un programita que ya viene hecho en Java y que podemos usar.

37
José A. Navarro Java desde 0. Programación I

Cuidado:

Ilustración 41. Ejemplo rango de datos

Esto funcionará sin ningún problema, pero lo siguiente no compilará pues un byte no tiene
suficiente precisión como para guardar el número 300:

Ilustración 42. Ejemplo rango de datos 2

Como hemos visto en la tabla de tipos el byte sólo llega hasta 127.

7.1 Variables
Antes hemos hablado de literales, pero obviamente no tiene sentido hacer un programa
que sólo sepa sumar 2+3, para ello existen las variables. Las variables no son más que porciones
de memoria a las que Java da un nombre y que guardan un dato.

Para declarar una variable primero se pone el tipo al que pertenece y luego su nombre.
<tipo> nombre;

Reglas a tener en cuenta antes de elegir el nombre de una variable:

 Una variable, siempre debe iniciar con una letra (mayúscula o minúscula) o un
guión bajo (_).

 Una variable puede contener números siempre que no comience por uno.

 El nombre de una variable no puede contener espacios en blanco.

 No puedes utilizar palabras reservadas5 para la declaración de una variable.

 Una variable no puede cambiar de nombre.

 No pongáis acentos.

Regla de oro: No te compliques la vida.

5
Palabras que tienen un significado para Java

38
José A. Navarro Java desde 0. Programación I

 Las variables deben de tener nombres representativos.

 En Java las variables comienzan en minúsculas y si son nombres


compuestos no se usa el _ para separarlos, cada comienzo de la
nueva palabra se pone en mayúsculas.

 En Java las variables primitivas no se inicializan automáticamente


a ningún valor.

Ejemplo de nombres validos:

 nombrePaterno

 IdCliente

 numero8

 _conteoCiclos
Ejemplo de nombres no validos:

 3puesto

 numero Telefono

 int

Aclaremos esto con ejemplos:

1. Error de compilación ya que las variables no han sido inicializadas

Ilustración 43. Variables no inicializadas Ilustración 44. Variables no inicializadas 2

Dos posibles soluciones: darles valor después de declararlas o en la propia declaración:

39
José A. Navarro Java desde 0. Programación I

Ilustración 46. Variables inicializadas Ilustración 45. Variables inicializadas 2

El símbolo = se llama asignación y lo que hace es darle el valor que se encuentra a la


derecha del mismo a la variable que se encuentra a la izquierda.

Si hacemos una traza mirando lo que ocurre en memoria de la solución de la derecha


entenderemos como funciona:

Dirección
Nombre de la Línea de
de Contenido
variable código
memoria
0x00F2 x 6
0x00F4 y 7
0x00F6
0x00F8
Tabla 1. Variables, memoria 1

Dirección
Nombre de la Línea de
de Contenido
variable código
memoria
0x00F2 x 2 6
0x00F4 y 3 7
0x00F6
0x00F8

Tabla 2. Variables, memoria 2

Dirección
Nombre de la Línea de
de Contenido
variable código
memoria
0x00F2 x 2 6
0x00F4 y 3 7
0x00F6 suma 10
0x00F8

Tabla 3. Variables, memoria 3

40
José A. Navarro Java desde 0. Programación I

Dirección
Nombre de la Línea de
de Contenido
variable código
memoria
0x00F2 x 2 6
0x00F4 y 3 7
0x00F6 suma 5 10
0x00F8
Tabla 4. Variables, memoria 4

Varias variables también se pueden declarar en una misma línea: int x,y,z; o int x=2, y=3;

1. Declaración de los distintos tipos de variable:

Ilustración 47. Tipos de variable 2

Ilustración 48. Tipos de variable

En Java no hay ‘,’ decimal sino ‘.’ decimal


El String no aparece en rojo ya que no es
un tipo primitivo.

2. Ejemplos de tipos de variable:

char letra=’aa’; Esto dará un error de compilación ya que un char sólo puede
contener un carácter.
String Aunque solo contenga una letra sigue siendo un String, una
letra=”a”; cadena de texto.
String Esto es el símbolo 5 no el número 5, por tanto “5”+2 no es 7
letra=”5”;
Tabla 5. Ejemplos de tipos letra

41
José A. Navarro Java desde 0. Programación I

Las variables solo son visibles dentro del bloque


en el que se han declarado, una vez termina este
mueren. Un bloque es el código encerrado entre
llaves.

7.2 Constantes
Java no tiene constantes como tal, pero se pueden simular usando unos modificadores
que veremos más adelante, pero de momento debéis de saber que podéis declarar una variable
cuyo contenido una vez asignado no pueda ser cambiado nunca, por tanto, se vuelve constante.
La sintaxis es:

final <tipo> nombre=valor;

Ilustración 49. Constantes

Si después de la declaración de intenta modificar PI dará un error de compilación.

Las constantes en Java se escriben en mayúsculas

Suele ser habitual declarar las variables y constantes


al principio del programa para una mejor claridad. No
obstante no es obligatorio.

7.3 Operaciones
Entre las operaciones aritméticas que podemos realizar con datos primitivos están:

+ Operador de Suma
- Operador de Resta
* Operador de Multiplicación
/ Operador de División
% Operador de Resto
Tabla 6. Operadores aritméticos

42
José A. Navarro Java desde 0. Programación I

Ilustración 50. Operadores aritméticos

Ilustración 51. Salida operadores

Veamos cómo se han ejecutado:

 La suma la ha realizado bien 7+5=12.

 La resta también: 7-5=2.

 La multiplicación no hay problema: 7x5=35 (fijaros que el signo es *).

 La división: 7/5=1 ¿? 7/5=1,4 no uno. ¿Qué ha pasado? Muy simple, la división en


Java es entera si ambos operandos son enteros por tanto se queda solo con la
parte entera del resultado: 1.

 El % ¿Qué es eso? El % no tiene nada que ver con porcentajes, ese símbolo
representa el módulo o lo que es lo mismo, el resto de una división.

7 5
5 1 Resto
2
Ahora mismo no le encontrareis sentido a lo del módulo. Tiempo al tiempo, posiblemente
es uno de los operadores más usados en programación.
Pero ¿Y la división? ¿Cómo lo solucionamos? La solución pasa por que uno de los
operandos sea decimal, solo con que uno sea decimal Java ya actúa como división decimal. Una
posible solución, de ir por casa, podría ser esta: (luego veremos una mejor)

43
José A. Navarro Java desde 0. Programación I

Ilustración 52. División decimal

Fijaros como lo único que he hecho es cambiar uno de los números de int a double.

Ilustración 53. Resultado división decimal

Ya funciona correctamente pero claro ahora todos los demás cálculos añaden el 0
decimal. Luego lo solucionamos.

Hay otro operador que se suele usar mucho y es el + ¿el +? A ver José, ¿Qué te has
fumado? Me has dicho que el + es suma. Sí, pero es un operador sobrecargado lo que significa
que puede hacer distintas operaciones dependiendo de los tipos con los que se encuentre y si
esos tipos son cadenas de texto el + significar concatenar o lo que es lo mismo unir dos textos:
String texto1=”hola “;
String texto2=”Mundo”;
texto1+texto2 es igual a “Hola Mundo”

Veamos cómo actúa este operador con varios ejemplos:

Ilustración 54. Concatenación

Ilustración 55. Ejemplo concatenado

44
José A. Navarro Java desde 0. Programación I

 En la línea 12 está concatenando dos String, los une. Pero claro el operador + solo
une con lo que queda un poco feo todo junto.

 En la línea 13 lo que hacemos es concatenar un espacio entre texto1 y texto2 lo que


hace que la frase ya quede mejor.

 El operador + se encuentra en la línea 14 con dos enteros por tanto actúa como suma.

 En cambio, en la línea 15 se encuentra a un lado un texto y al otro un entero, dado


que en el método println tiene más prioridad el texto transforma automáticamente
el entero en texto y los concatena.

7.4 Operadores de asignación


A parte de le operador de asignación = existen otros operadores que no son más que una
forma recortada de los anteriores cuando se utilizan en asignaciones. Estos son:

+= Para sumar el operando izquierdo con el operando derecho y luego asignarlo a la


variable de la izquierda.
–= Para restar el operando izquierdo con el operando derecho y luego asignarlo a la
variable de la izquierda.
*= Para multiplicar el operando izquierdo con el operando derecho y luego asignándolo
a la variable de la izquierda.
/= Para dividir el operando izquierdo con el operando derecho y luego asignarlo a la
variable de la izquierda.
%= Para asignar el módulo del operando izquierdo con el operando derecho y luego
asignarlo a la variable de la izquierda.
Tabla 7. Operadores de asignación

Ilustración 57. Suma sin asignación Ilustración 56. Suma con asignación

Ambos códigos hacen exactamente lo mismo. Al principio, hasta que cojáis práctica podéis
usar el modo de la izquierda. El de la derecha no se ejecuta más rápido.

7.5 Operadores unarios aritméticos

++ incremento
-- decremento
Tabla 8. Operadores de incremento

45
José A. Navarro Java desde 0. Programación I

Los operadores unarios de incremento y decremento aumentan o disminuyen el valor de


una variable en una unidad, pero actúan de forma distinta dependiendo del orden:

Ilustración 58. Post incremento Ilustración 59.Pre incremento

Ilustración 61. Resultado Post incremento Ilustración 60. Resultado Pre incremento

Analicemos los dos casos:

 Izquierda: Al hacer x++ primero muestra la x y luego la incrementa. Al mostrarla


de nuevo vale 2.

 Derecha: Al hacer ++x primero incrementa y luego muestra. Al mostrarla la


segunda vez el valor es el mismo.

Habrá muchos casos en los que da igual que forma uséis, por ejemplo, yo suelo usar
mucho x++, pero debéis de ir con cuidado porque en ocasiones no será lo mismo.

El operador -- es igual, pero restando 1.

7.6 Prioridad de operadores


Todos los operadores no tienen la misma prioridad. Veamos el siguiente ejemplo:

x=5+8*2; ¿Cuánto vale x? Si habéis contestado 21 es correcto. La multiplicación tiene más


prioridad que la suma por lo que primero se ejecuta 8*2=16 y luego 16+5=21.

Está claro que era un ejemplo fácil, pero ¿a qué si hubiera escrito x=5+(8*2) nadie hubiera
dudado?

Con esto pasa como los comentarios, tan malo es pasarse como no llegar. Los paréntesis
ayudan a que el código sea más legible. Está claro que si yo hubiera querido que el resultado
fuera 26 tendría que haber escrito x=(5+8)*2 ya que el operador con más prioridad es el
paréntesis.

Huelga decir que si vais a hacer algo como esto uséis paréntesis: x=4+5*6/3.7-
5.9/9%67+23.

46
José A. Navarro Java desde 0. Programación I

La prioridad de la mayoría de operadores en Java es la siguiente (cuanto más rojo más


prioridad)

() [] .
! ++ --
new (cast)
*/%
+-
< <= > >= instanceof
== !=
&&
||
?:
= *= /= %= += -=
Tabla 9 Prioridad de operadores

7.7 Casting
El casting son conversiones que se realizan entre tipos distintos. Existen dos tipos de
conversiones:

 Conversiones implícitas: las realiza Java de forma automática. La variable


destino debe de tener más precisión que la de origen.

Ilustración 62. Casting implícito

Java sin decirle nada a convertido el byte a int

 Conversiones explicitas: Es el programador el que fuerza la conversión. Se pone


el tipo destino entre paréntesis antes de la variable a convertir.

Ilustración 63. Casting explícito

Hemos forzado a Java a que convierta un double a int. De esta forma podríamos solucionar
el ejemplo de la división: (double)x/y. Con transformas uno es suficiente.

47
José A. Navarro Java desde 0. Programación I

Hay que ir con mucho cuidado con los casting’s. En el primero si estuviera
al revés nos daría un error de compilación como vimos en el apartado de
los tipos. En el segundo no dará ningún error pero la y no valdrá 5.6 sino
solo 5 ya que en un int no se pueden representar decimales.

7.8 Ejercicios

1. Indica si funciona o no y porqué. ¿qué se mostraría?:

int a=’a’;

System.out.println(a);

2. int pi=3.14;
System.out.println(pi);

3. Realiza un programa que dadas dos variables a y b intercambien sus valores.

4. Realiza un programa que calcule la longitud de una circunferencia de radio 3


metros.

5. Realiza un programa que calcule el área de una circunferencia de radio 5 metros.

6. Realizar un programa que dada una cantidad de dinero lo divida en billetes de 50,
20, 10, 5 y monedas de un euro (no hay céntimos)

48
José A. Navarro Java desde 0. Programación I

8. Estructuras de control

Como hemos visto, los programas contienen instrucciones que se ejecutan una a
continuación de la otra según la secuencia en la que hayamos escrito el código. Sin embargo,
hay ocasiones en las que es necesario romper esta secuencia de ejecución para hacer que una
serie de instrucciones se ejecuten o no dependiendo de una determinada condición o hacer que
una serie de instrucciones se repitan un número determinado de veces.
Las estructuras de control permiten modificar el orden natural de ejecución de un
programa. Mediante ellas podemos conseguir que el flujo de ejecución de las instrucciones sea
el natural o varíe según se cumpla o no una condición o que un bloque de instrucciones se repita
dependiendo de que una condición se cumpla o no.

Las estructuras de control tienen las siguientes características:

 Tienen un único punto de entrada y un único punto de salida.

 Están compuestas por instrucciones o por otras estructuras de control.


Las estructuras de control se dividen en las siguientes categorías:

 Estructura Secuencial

 Estructura Condicional o alternativa

 Estructura Repetitiva.

 Instrucciones de salto

Las primeras son las que hemos visto hasta ahora, después de la línea 1 se ejecuta la 2 y
luego la 3 y así todas.

8.1 Estructuras condicionales


8.1.1 if
El if es una estructura que nos va a permitir ejecutar un código u otro dependiendo de
una condición. Si la condición es verdadera entra en el bloque de la estructura, si no, no.

Ilustración 64.Estructura del if

49
José A. Navarro Java desde 0. Programación I

Ejemplo en Java:

Ilustración 65.Primer if

Ilustración 66. Ejecución primer if

En Java la palabra reservada para esta estructura es if. El if va seguido de la condición


entre paréntesis, en este caso estamos comprobando si la x es igual a 5. Como es verdad se
ejecuta lo que hay dentro del if y luego continúa con la siguiente instrucción del programa.

Imaginemos que x es igual a 10. El resultado sería este:

Ilustración 67Ejecución del primer if 2

Dado que la condición es falsa no entra en el if y se ejecuta la siguiente sentencia del


programa.

Todas las estructuras de Java solo permiten una única sentencia, para poder poner más
es necesario encerrarlas en un bloque entre llaves:

Ilustración 68. Segundo if

50
José A. Navarro Java desde 0. Programación I

Ilustración 69. Ejecución segundo if

8.1.1.1 Operadores de comparación


Los operadores que podemos usar dentro de los paréntesis de un if para comprobar una
condición son:

== igual a

!= no igual a o distinto

> mayor que

>= mayor o igual que

< menor que

<= menor o igual que

Tabla 10. Operadores de comparación

Fijaros que a diferencia de otros lenguajes el igual no es “=” sino “==” y distinto o no igual
es “!=”.

Si la x es mayor o igual a 5 entonces entra, si no, no.

Ilustración 70. Tercer if

51
José A. Navarro Java desde 0. Programación I

Ilustración 71. Ejecución tercer if

Si la x no es 5 o mayor que 5 no ejecutará el if.

El if tiene otro compañero de viaje para cuando queramos que se haga algo si la condición
es falsa:

Ilustración 72. Estructura completa del if

En Java se utiliza la palabra reservada else:

Ilustración 73. Cuarto if

Si la condición es verdadera mostrará el primer mensaje, si no, el segundo. Siempre


ejecutará el último (12) ya que se encuentra fuera del if. Un if puede tener o no else pero un else
no puede existir sin un if. Si tenemos la necesidad de poner sólo un else es porque no hemos
pensado bien la condición, hay que cambiarla para usarla con un if. Un else no lleva ninguna
condición pues significa “si no”, la condición siempre va en el if.

Cuando usamos un if-else siempre se ejecutará uno de los dos, siempre, pero jamás los
dos a la vez, o uno u otro.

Realmente en la condición de un if podemos poner cualquier cosa que como resultado


pueda evaluarse a true o false:

52
José A. Navarro Java desde 0. Programación I

Ilustración 74. Quinto if

Cuando Java llega a la línea 8 primero hace la multiplicación y luego compara el resultado
con z. En este caso como es verdad mostrará el mensaje.

Hay lenguajes como C en los que cualquier cosa distinta de 0 es verdad.


Como ejemplo esta condición será válida if(x+y), de forma que siempre
que la suma no sea 0 es verdad. En Java esto no se puede hacer y verdad
es true y mentira false. Son tipos incompatibles con un entero.

8.1.1.2 If’s anidados


Como he comentado antes dentro de un if-else puede ir cualquier sentencia o sentencias
compuestas por tanto dentro de un if pueden ir más if. A esto se le llama if anidados.

Ilustración 75. If anidados

Veamos el resultado tal cual está:

Ilustración 76. Resultado if anidados 1

Cambiemos y=2, z=0

53
José A. Navarro Java desde 0. Programación I

Ilustración 77. Resultado if anidados 2

Cambiemos x=3, y=5, z=0

Ilustración 78. Resultado if anidados 3

Podéis usar llaves si lo veis más claro

Java sabe a qué if le corresponde un else por proximidad, se busca el if hacia arriba más
próximo que no esté ya asociado.

Importante: Fijaros como el código no lo he escrito todo alineado en vertical. Cada vez
que escribimos código que se encuentra dentro de un bloque hay que tabular hacia la derecha,
dejar unos espacios, a esto se le llama identación. Su usáis llaves al pulsar intro, Geany
automáticamente identa, si no lo tenemos que hacer nosotros. Hay lenguajes, como Python,
que si el código no está bien identado no compilan. A java le da igual que este identado o no,
como si queremos escribirlo todo en una línea, pero esto tiene un problema muy grande de
legibilidad, el código no se puede entender.

Veamos el código anterior sin identar:

Ilustración 79. Ejemplo sin identación

Esto no lo entiende nadie. A mis alumnos les suelo decir: “no hay identación, no hay
corrección”. Por favor, IDENTAD.

54
José A. Navarro Java desde 0. Programación I

8.1.1.3 Operadores lógicos


Para no tener que anidar muchos if’s podemos usar ciertos operadores que me permiten
unir distintas comparaciones en la condición del if. Dado que en el manual no vamos a realizar
operaciones a nivel de bit voy a omitir estos y a ver los más usados.

Operador Descripción Sintaxis


&& And lógico (y) a && b
|| Or lógico (o) a || b
! Negación lógica (no) !a
Tabla 11. Operadores lógicos

La mejor forma de ver el funcionamiento de estos operadores es mediante lo que se


conoce como tablas de verdad6. Una tabla de verdad muestra la salida del operador ante las
distintas posibilidades de entrada. Las tablas de verdad se suelen hacer solo con dos entradas,
sabiendo ya como funcionan para dos se puede extrapolar para cualquier número de entradas.

Estos operadores los podéis encontrar en la bibliografía de algunos


autores como “.”, multiplicación que se corresponde con el and y como
“+”, suma que se corresponde con el or.

La V representa verdad y la F falso. Veamos las tablas de verdad, con todas las
posibilidades de los operadores && y ||:

a b && ||
V V V V
V F F V
F V F V
F F F F
Tabla 12. Tabla de verdad AND y OR

a y b representan dos variables cuyo contenido puede ser verdadero o falso. Si analizamos
la tabla de verdad de ambos podemos llegar a las siguientes conclusiones. && (and) solo es
verdad cuando ambas variables lo son. || (or) sólo es falso cuando ambas variables lo son. Con
esto podemos concluir que al and da verdadero sí y solo sí todos sus operados son verdaderos.
Mientras que el or da verdadero sí y solo sí un operando sea verdadero, solo con uno verdadero
es suficiente, o lo que es lo mismo sólo puede dar falso sí y solo sí todos son falsos. Esto se
cumple para cualquier número de operandos.

La negación en un operando muy simple: Niega lo que hay:

a !a
V F
F V
Tabla 13.Tabla NOT

6
Las tablas de verdad se usan mucho en electrónica digital donde también existen estos operadores
llamándose puertas lógicas.

55
José A. Navarro Java desde 0. Programación I

Si a es verdadero !a (no a) es falso. Aunque en principio puede parecer una tontería es un


operando muy usado ya que nos permite hacer condiciones de una forma más simples y más
cercanas a nuestra forma de razonar.

Existe un cuarto operador, no excesivamente usado que es el ^. Este operador es el XOR


y su tabla de verdad es la siguiente:

a b a^b
V V V
V F F
F V F
F F V
Tabla 14. Tabla XOR

Es verdad solo cuando uno de los operandos es verdad, solo uno.

No confundáis ^ con exponente. En otros lenguajes es así pero Java no


tiene un operador para ello. Veremos más adelante como se hace.

Veamos un ejemplo de estos operandos:

Ilustración 80. Operadores lógicos

Ilustración 81. Salida operadores lógicos

56
José A. Navarro Java desde 0. Programación I

Veamos lo sucedido:

1. Se ejecuta la línea 8: x==0 es verdad, y>2 es verdad, por tanto, V && V verdad.
Entra en el if y muestra “primero”.

2. Se ejecuta la línea 10: x==8 es mentira, y>2 es verdad, por tanto, F || V verdad.
Entra en el if y muestra “segundo”.

3. Se ejecuta la línea 12: x==8 es mentira, y>10 es mentira, por tanto, F && F falso.
No entra en el if.

4. Se ejecuta la línea 14: x==0 es verdad, y>10 es mentira, por tanto, V && F falso.
No entra en el if.

5. Se ejecuta la línea 16: x==0 es verdad, y>10 es mentira, por tanto, (x==0 && y>10)
es falso. z <10 es verdad, falso (del anterior) || verdad es verdad. Entra en el if y
muestra “quinto”.
Ver anexo III

Fijaros en la prueba 3. F && F. Ante este tipo de condiciones Java actúa de


esta forma: x==8 es falso ¿existe alguna posibilidad de que siendo la
primera comparación falsa un and de verdadero? No. Un and (&&) sólo
puede dar verdad si todos lo son, por tanto, Java, viendo que el primero ya
no es verdadero y está en un and no sigue evaluando el resto, por muchos
operadores que hayan, da directamente falso. A esto se le llama evaluar en
cortocircuito. Ahorra tiempo y nos proporciona una potente herramienta
para hacer condicionales como veremos en próximos capítulos.

Veamos estas expresiones:

Ilustración 82. Condiciones cortas

Las líneas 9 y 10 hacen exactamente lo mismo. Es lo mismo comparar con true que poner
la variable sola, ya que si es verdadera es cuando entra.

57
José A. Navarro Java desde 0. Programación I

Las líneas 12 y 13 hacen lo mismo. Es lo mismo comparar la variable con false que negarla
ya que al escribir !temp le estamos diciendo no temp o sea falso, no entrará.

Existe un operador ternario que simula un if de forma corta y que personalmente no le


tengo mucho aprecio pero por si lo veis que sepáis que es lo que hace:
condición ? si verdad : si falso

Ejemplo:

Ilustración 83. Operador ternario

La línea 7 comprueba la condición entre paréntesis si es verdad realiza la primera


operación antes del ‘:’ si no la segunda. En ambos casos guarda el resultado en la otra variable.

Hemos visto como los operadores de comparación son para tipos primitivos, entonces
¿Por qué funciona el == con String si este tipo no es primitivo sino una clase? Como
hemos visto los String (texto) son tan usados que Java permite un uso “cómodo” de
los mismos de forma que se declaran y se utilizan como un tipo primitivo. Por otro
lado, Java es muy listo y cuando ve que creamos dos variables con el mismo texto no
crea dos espacios de memoria distintos para cada una, sino que ambas variables
apuntan a la misma dirección de memoria.
Este modo de actuar puede causar algunos inconvenientes, como os explicaré en
capítulos posteriores. Por ello para ver si dos objetos son iguales existe otra forma que
nunca falla y es usar el método equals. equals (lo estudiaremos también) nos dice si
dos String son iguales, por tanto, la forma correcta de ver si dos textos son iguales no
es usando == sino equals y se usa de la siguiente forma: variable1.equals(varable2);

String texto1=”hola”;
String texto2=”pepe”;
if(texto1.equals(texto2))
…….
Como podéis observar una de las dos variables, da igual cuál, llama a equals y entre
paréntesis se pone la otra. Antes del equals siempre va un “.” que indica que queremos
usar ese método7.

Sé que esto es un poco complejo de entender ahora pero cuando veamos las clases lo
entenderéis del todo. Vamos a hacer lo que yo llamo un salto de fe.

7
Un pequeño programa para solucionar un problema que, en este caso, alguien ha hecho por nosotros.

58
José A. Navarro Java desde 0. Programación I

8.1.2 switch
Cuando queremos hacer cosas distintas dependiendo del valor que tenga una variable
podemos usar varios if comprobando el valor de la misma o usar la estructura switch.

Ilustración 84. Estructura switch

Veamos como seria en Java mediante aproximaciones:

Ilustración 85. switch aprox1

1. En la línea 5 declaramos la variable numero y le damos el valor 3. Dependiendo


del valor de numero queremos que imprima por pantalla su equivalente en texto.

2. En la línea 7 mediante la palabra reservada switch le indicamos entre paréntesis


la variable a inspeccionar y entre llaves ponemos los casos.

3. Los distintos casos se ponen usando la palabra case y el valor que se espera
seguido de “:”.

4. Después de los “:” vienen las instrucciones que queremos que se ejecuten.

Ilustración 86. Salida switch aprox1

59
José A. Navarro Java desde 0. Programación I

Bien, perfecto. Cambiemos el valor de numero:

Ilustración 87. switch aprox2

Ilustración 88. Salida switch aprox2

¿Qué ha pasado? Muy simple, el switch se ejecuta todo seguido entrando en todos los
casos, para que esto no ocurra usamos la sentencia break que lo que hace es terminar el switch
y seguir con la ejecución del programa. De esta forma poniendo un break en cada caso solo
entrará en el correcto. El último break no es necesario pues después no hay más casos, yo
personalmente siempre lo pongo.

Ilustración 89.switch aprox3

Ilustración 90. Salida switch aprox3

60
José A. Navarro Java desde 0. Programación I

Ahora podemos ver como ya funciona correctamente. Dentro de un case podemos poner
tantas sentencias como queramos entre sus “:” y el break. Existe una opción que se puede añadir
en un switch para que se ejecute en caso de que ninguna de las opciones se la correcta, default:

Ilustración 91. switch aprox4

Ilustración 92. Salida switch aprox4

Como podéis ver al no existir el 8 entre los casos se ejecuta el por defecto.

Ejemplo con un tipo char:

Ilustración 93. switch aprox5

En este caso como el tipo es char en los case se usan comillas simples.

Actualmente Java y el JDK 8 permite usar el String en un switch aunque


no sea un dato de tipo primitivo.

61
José A. Navarro Java desde 0. Programación I

8.2 Estructuras de repetición


Las estructuras de repetición o bucles se utilizan cuando queremos ejecutar sentencias
cero o más veces. Tienen una condición de salida que nos indica cuando se deja de ejecutar el
bucle y se continua con el programa.

8.2.1 while
El while es el primer bucle que tenemos y su sintaxis es la siguiente:
while(condición)
<sentencias>
El while se repite mientras se cumpla la condición (sea verdadera). Lo que podemos poner
entre paréntesis es exactamente lo mismo que lo visto en el if (operadores de comparación,
lógicos y expresiones que den como resultado true o false) y al igual que este si hay más de una
sentencia se pueden usar llaves.

Ilustración 94. Estructura while

Veamos un ejemplo en el que vamos a mostrar los números del 0 al 9 por pantalla:

Ilustración 95. while aprox 1

En la línea 8 podemos ver como la condición del while es “mientras numero <10” de forma
que hasta que numero no sea 10 no saldrá del bucle.
Veamos que sucede:

62
José A. Navarro Java desde 0. Programación I

Ilustración 96. Salida while aprox 1

Solo hacen que salir ceros sin parar ¿Por qué? Porque no hay nada dentro del while que
cambie el valor de la variable numero y por tanto la condición siempre es verdad.

Ilustración 97. while aprox 2

Ahora después de mostrar el número se incrementa su valor en uno. Fijaros que lo


podemos hacer como esta en la línea 10 o usando el operador incremento.

Ilustración 98. Salida while aprox 2

Ahora se va incrementando la variable y mostrándose hasta que llega un momento en


que vale 10, no cumple la condición y el while termina.

Lo que ha sucedido en la primera aproximación se llama bucle infinito.


Nunca salimos del while y el programa no funciona pudiendo llegar a
consumir la memoria disponible. Para evitar esto debemos de
asegurarnos que dentro del while hay alguna instrucción que en algún
momento hará que la condición sea falsa.

63
José A. Navarro Java desde 0. Programación I

8.2.2 do
La estructura do es la prima hermana del while, la única diferencia es que la condición se
comprueba al final y no al principio.

Ilustración 99. Estructura do

Fijaros que en la condición no es mientras se cumpla la condición sino hasta que se


cumpla la condición, por tanto, se ejecuta el bucle si es falsa. La sintaxis es:
do{
<sentencias>
}while(condición);

En este caso son necesarias las llaves siempre y como excepción a la regla después de la
condición del while sí se pone “;”.
Hagamos el mismo ejemplo que con el while pero usando el do:

Ilustración 100. do

La salida es exactamente la misma.

64
José A. Navarro Java desde 0. Programación I

8.2.3 for
El for es un bucle un poco más complejo, veamos:

Ilustración 101. Estructura for

La sintaxis es la siguiente:
for(valor inicial;condición;incremento)
<sentencias>
Las partes del for se separan por “;”.

1. Valor inicial: es el valor que tiene la variable que controla el for. Normalmente se
suele declarar en el propio for y por algún motivo que desconozco suelen usarse
las letras i, j , t.

2. Condición: nos indica cuantas veces se va a ejecutar el for. Para elegir una
condición podemos pensar en “mientras…” como si fuera un while.

3. Incremento: es como va evolucionando la variable. A diferencia del while y el do


la evolución de la variable la controla el propio for, por ello se suele llamar variable
de control.

Veamos el mismo ejemplo de antes, pero hecho con un for:

Ilustración 102. for

1. El resultado es exactamente el mismo. Veamos que ha sucedido:

2. En la línea 6 declaro la variable de control i y la inicializo a 0.


3. En la segunda parte digo que se ejecute el bucle mientras la i sea menor a 10.

65
José A. Navarro Java desde 0. Programación I

4. En la última le digo que la i se tiene que incrementar de uno en uno. Es muy


habitual usar los operadores unarios.

Al llegar a la línea 6 Java crea la variable y la inicializa, comprueba la condición y si es


verdad entra. Después de una iteración8 se produce el incremento y si se sigue cumpliendo la
ejecución sigue iterando.

El for tiene muchas variaciones, por ejemplo, imaginad que quiero imprimir del 9 al 0, de
mayor a menor:

Ilustración 103. for inverso

En este ejemplo se imprime por pantalla los números del 9 al 0. Fijaros en la inicialización
de la variable, la condición y que se ha sustituido el incremento por un decremento.

Cada parte del for puede tener más de una expresión. Un for puede
tener más de una variable, una condición con operadores lógicos y
más de un incremento o decremento. Este for sería correcto for(int
i=0,j=5;i<10 && j>0;i++,j--) si bien no es lo habitual.

En un bucle for la evolución de la variable la controla el mismo for.


Nunca modifiquéis la variable de control dentro del bucle.
Obtendréis resultados inesperados aparte de ser una muy mala
praxis.

8.2.4 ¿Cuál debo de usar?


A la pregunta cuál de las tres estructuras de repetición debo de usar la respuesta es fácil,
pero con matices. En principio la que queráis, con la que vosotros os expreséis mejor o la
condición la entendáis mejor. Pero hay que tener en cuenta una serie de cosas:

Diferencias entre while y do:

 En la estructura while primero se comprueba la condición y luego se ejecuta el


bucle. Pudiera pasar que la condición sea falsa desde el principio y nunca se
ejecuten las sentencias del bucle. El while se puede ejecutar 0 o muchas veces.

8
Ejecución de las sentencias de un bucle

66
José A. Navarro Java desde 0. Programación I

 En la estructura do la condición se comprueba al final, por tanto, aunque la


condición sea falsa, la primera vez se va a ejecutar. El do siempre se ejecuta como
mínimo una vez. Por tanto, se va a ejecutar 1 o muchas veces.

Un while se puede transformar en do y viceversa cambiando la condición y la posición


del código.

Cuando usar while/do o for:


En un for siempre vamos a saber las veces que se va a ejecutar mientras que un while/do
no. Siempre que no sepáis de antemano las veces que se va a repetir algo usad un while o do
por ejemplo hasta que el usuario pulse una tecla (no sabemos cuándo lo va a hacer). Cuando
sepamos las veces que se va a ejecutar (desde i hasta n) un for es más simple.

Un for también se puede cambiar por un while o do, siempre.

Cualquier combinación entre if, switch, while, do y for es posible.


Podemos hacer que dentro de un for haya un while dentro dos if
otro for…

Uso de char: Un char no es más que un entero que como ya hemos visto están codificados
mediante la tabla ascii o Unicode por tanto puedo hacer esto sin tener que recurrir a métodos
de transformación ni casting’s

Ilustración 104. Condición con char

Ilustración 105. Salida condición char

No, la Ñ no está codificada después de la N. Si miráis en la tabla del capítulo anterior veréis
que es el número 165.

67
José A. Navarro Java desde 0. Programación I

8.2.5 Break y continue


Estas son dos instrucciones que las comento porque aparecen en todas las bibliografías y
debéis de saber lo que hacen. Bajo mi punto de vista estas instrucciones las carga el diablo y
hacen más mal que bien.

 Break: el break es una instrucción que rompe la secuencia de ejecución natural


del programa. Si ponéis un break dentro de un bucle, cuando se ejecute, Java
saldrá automáticamente del mismo.

 Continue: hace exactamente lo mismo, pero en vez de salir del bucle fuerza la
siguiente iteración.

Ilustración 106. Break

Estas dos sentencias van en contra de la programación estructurada, rompen la


continuidad del código y lo hacen ilegible. El ejemplo que os he puesto es muy simple, pero
pensad en un programa con 500 líneas y 58 break, eso no lo entiende ni el que lo ha hecho.

Si usáis el break, lo más probable es que no habéis pensado bien la condición. Cualquier
break se puede sustituir por una variable booleana para poder salir y cualquier for se puede
transformar en un while.

Ya sé lo que va a pasar ahora, seguro que tenéis algún amigo que os dice que esto es una
tontería y que no sé de lo que hablo, que con el break los programas van más rápidos… Me
parece perfecto, para él todos, arrieros somos y en el camino nos encontraremos. Yo enseño
programación no a codificar espaguetis.

¿Significa esto que jamás debemos de usar un break? NO. Obviamente como ya hemos
visto el break es necesario en un switch. Pero no solo eso, cuando programéis de forma
concurrente con threads y sockets pues sí, uno o dos break serán necesarios9.

No comencemos con malos hábitos, si queréis aprender bien no


uséis el break ni el continue.

9
Véase el servidor Apache

68
José A. Navarro Java desde 0. Programación I

8.3 Ejercicios
1. Realiza un programa que realiza la siguiente figura por pantalla

*
***
*****
2. Realiza un programa que muestre por pantalla los 5 primeros números naturales.
3. Realizar un programa que muestre los 100 primeros números primos.
4. Realizar un programa que muestre las tablas de multiplicar.
5. Realizar un programa que muestre por pantalla los números del 1 al 100 sin
mostrar los múltiplos de 5.
6. Realiza un programa que realiza la siguiente figura por pantalla.

*
***
*****
*******
*****
***
*

69
José A. Navarro Java desde 0. Programación I

9. API
Como ya vimos Java es un lenguaje orientado a objetos puro. Nosotros estamos evitando
el uso de la POO, pues la iremos viendo mediante aproximaciones, pero no podemos evitar tener
que usar clases, objetos o métodos que ya están hechos. Java cuenta con una extensa librería,
estructurada en paquetes, con un sinfín de clases y métodos que ya están hechos y podemos
usar. Lo único que debemos de saber es cómo se usan.

Lo primero es acceder a esta API, para ello basta con buscar API Java 8 en google y es el
primer resultado. No obstante os dejo el enlace a la API del JDK 8:
https://docs.oracle.com/javase/8/docs/api/

Nos encontramos con lo siguiente:

Paquetes Pantalla de
información
Clases, interfaces y
excepciones

Ilustración 107. API 1

Veamos el ejemplo de la clase String que ya conocemos:

Ilustración 108. API 2

Podemos ver como la clase String se encuentra en el paquete java.lang y tiene un método
para comprobar si dos String son iguales que devuelve un booleano. Si pulsamos sobre el
método nos da más información:

70
José A. Navarro Java desde 0. Programación I

Ilustración 109. API 3

Todo lo que hay en el paquete java.lang no es necesario importarlo


a mano pues Java ya lo hace.

En el próximo tema vamos a tratar el tema de la entrada estándar, veamos donde se


encuentran los métodos que vamos a estudiar:

Ilustración 110. API 4

Ilustración 111. API 5

71
José A. Navarro Java desde 0. Programación I

Ilustración 112. API 6

Scanner la veremos en el próximo capítulo y como podéis ver está en java.util. En


definitiva, existen miles de “pequeños programitas” ya hechos para que los usemos.

Pese a la gran cantidad de librerías y soluciones que nos ofrece la


API nosotros no vamos a usar todo su potencial ya que de lo que se
trata en este manual es de aprender a programar no a usar una API.
En próximos manuales veremos utilidades que nos facilitarán la
vida.

72
José A. Navarro Java desde 0. Programación I

10. Entrada por teclado


Hasta ahora hemos visto ejemplos en los que se les da un valor a unas variables y se
resuelve un problema, pero esto dista mucho de la realidad. Como he comentado antes, tener
una calculadora que solo pueda hacer operaciones sobre el número 5 y el 2 es totalmente inútil.
Por tanto, debe de haber un mecanismo para que los programas sean más generales y
reutilizables, ese mecanismo va a ser pedirle al usuario los valores con los que quiere operar.

La entrada por teclado se realiza mediante flujos de entrada llamados streams pero
gracias a la API podemos poner una capa de abstracción y usar una clase que nos va a facilitar
esta entrada. Esta clase es Scanner. Scanner se encuentra en el paquete java.util, por tanto lo
primero que debemos de hacer antes de poder usarla es importarla. Podéis ver en la API los
métodos que tiene, de todos ellos los que más vamos a usar son:

 nextLine(): Lee un texto.

 nextInt(): Lee un entero.

 nextDouble(): Lee un double.

(Obviamente hay muchos más, pero para los fines de este manual con estos nos sobran)

Lo primero que debemos de saber es que todo lo que se introduce por teclado es texto.
Por tanto, si lo que se necesita es leer un entero lo que se hace es una conversión. Por ejemplo:
si uso nextLine() como es texto no hace ninguna conversión ni nada, pero si lo que quiero es leer
un entero al usar nextInt() lo que hace es leer como texto y luego transformarlo a entero.

Como he dicho antes para poder usar Scanner lo primero que debemos de hacer es
importar la clase:
import java.util.Scanner;
Esta línea se pone al principio de todo, antes de crear la clase principal. Con ella le decimos
que importe la clase Scanner que se encuentra en el paquete útil dentro de las librerías de java.
El camino hasta la clase en concreto se separa con puntos.

Una vez importada y ya dentro del programa debemos de crear un objeto (variable) que
represente a Scanner y podamos usarlo por el nombre que le demos. Scanner necesita para
poder crearse que le digamos de donde va a leer, si la salida estándar para imprimir es
System.out la entrada estándar es System.in:
Scanner sc=new Scanner(System.in);

Con esta línea lo que creamos es una “variable” llamada sc del tipo Scanner y luego con
el operador new le decimos que tiene que leer de la entrada estándar. “sc” es el nombre que le
damos, podríamos llamarle entrada lo que sucede es que es común ponerle sc de esta forma al
leerlo todos entienden que viene de un Scanner. En este manual y para la entrada estándar esta
línea siempre será la misma. Una vez creada la “variable” ya podemos usar sus métodos.

73
José A. Navarro Java desde 0. Programación I

Veamos un ejemplo:

Ilustración 113. Prueba Scanner

1. En la línea 1 importamos Scanner.

2. Línea 6, dentro ya de donde estamos escribiendo el código lo primero que


hacemos es crearnos una variable de tipo Scanner.

3. En las líneas 8 y 9 creo dos variables para recibir lo que el usuario va a introducir.

4. En la línea 11 muestro un texto para que el usuario sepa que debe de hacer, fijaros
como uso print para que el cursor se quede esperando en la misma línea.

5. Después en la 12 llamo al método nextLine() del Scanner, para ello pongo el


nombre de la variable (objeto), un punto y el método que quiero usar. El método
es bloqueante, esto significa que Java se va a quedar esperando hasta que el
usuario introduzca algo y pulse intro. Cuando el usuario pulsa intro coge lo que ha
introducido y lo guarda en la variable texto.

6. Con las líneas 13 y 14 pasa lo mismo solo que nextInt() lee el texto lo transforma
en un int y lo guarda en la variable número.

7. Las siguientes líneas muestran el contenido de las variables.

Ilustración 114. Salida Scanner

74
José A. Navarro Java desde 0. Programación I

Ejemplo con un double:

Ilustración 115. nextDouble()

Ilustración 116. Salida nextDouble()

Fijaros en la salida. Para que Java entienda que es un decimal hay que usar la “,” no él “.”
Mientras que cuando lo muestra lo hace con “.”. Esto sucede porque Java usa el punto decimal
pero como estás viendo estoy usando un entorno Windows y para este el decimal es la coma,
por ello en la entrada debemos de teclear “,” ya que depende de Windows, no de Java.
¿Qué sucede si usamos el punto o peor todavía, si el usuario teclea algo que no es
correcto?

Ilustración 117. Salida excepción

Lo que se ha producido es una excepción, nextDouble() no ha podido transformar a double


lo que hemos introducido ya que no es un número. Cuando salta una excepción es porque el
programa no puede continuar. En otro capítulo explicaré, brevemente, lo que son las
excepciones, no obstante con lo que hemos aprendido hasta ahora debemos de ser capaces de
evitar este tipo de excepciones, tan solo hay que comprobar, antes de guardarlo como double,
que es un número, y para eso podemos usar las estructuras de control y repetición.

75
José A. Navarro Java desde 0. Programación I

Cualquier next con conversión (nextInt, nextDouble…) lo que hacen es coger lo que
hay que transformar, el número por ejemplo, y devolverlo en una variable pero
dejan el intro que ha pulsado el usuario en el flujo de entrada. Cuando esto sucede
si intentamos leer otra vez del teclado nos da la sensación de que Java pasa de
nosotros y no pausa la ejecución para dejarnos escribir. Esto sucederá siempre que
usemos un next con conversión y después uno sin. Por ejemplo: nextInt() y después
un nextLine(). Solo sucede en este caso, no si primero hay nextLine() o si hay muchos
nextInt() y nextDouble() pero ningún nextLine(). Cuando esto suceda lo que hay que
hacer es antes de realizar el nextLine() limpiar el flujo de entrada y eliminar ese
retorno de carro y lo más rápido es usar un nextLine() sin guardar su resultado. Por
ejemplo:

La línea 12 lee el retorno de carro que ha dejado la 11 y lo tira a la basura ya que no


lo guarda. Cuando se ejecuta la 14 esta funciona bien.

Probad en casa lo que pasa cuando no ponéis la 12 y la solución.

Métodos de la clase String que nos pueden ser de utilidad y sí podemos usar:

 charAt(int i): devuelve el carácter cuya posición es i dentro de un texto.

 length(): me dice la longitud de un texto.

 substring(int inicio, int fin): extrae una subcadena de un texto.

Todos los caracteres de un String tienen un índice que comienza por 0. Por ejemplo: “hola”
tiene una longitud de 4 y sus índices son:

0 1 2 3
h o l a

Por tanto, para recorrer un String solo podemos llegar hasta longitud-1.

Esto lo entenderemos mejor en el capítulo de String y de vectores. Veamos un ejemplo


de estos métodos:

Ilustración 118. String

76
José A. Navarro Java desde 0. Programación I

Ilustración 119. Salida String

1. En la línea 9 preguntamos cuál es la longitud del String. (acordaros que los


métodos siempre van entre paréntesis aunque no necesiten nada). El resultado
es 4.

2. En la línea 10 mostramos el carácter que se encuentra en la posición 3. Teniendo


en cuenta que se comienza a contar por 0 el carácter es la ‘a’.

3. En la línea 11 sacamos una subcadena que va desde el carácter 0 al 2. Substring


saca desde el índice inicial hasta uno menos del que pongamos como final (3). En
este caso desde el 0 al 2 “hol”.

¿Cómo sacar letra a letra de un texto?

Ilustración 120. For String

Ilustración 121. Salida for String

En la línea 9 creamos un for que parta de 0 sin llegar hasta el final y que se incremente en
uno. Con charAt(i) vamos sacando el char de cada índice que se corresponde con la i. Si la palabra
es hola la i tomará los valores desde 0 hasta 3. ¿Qué sucede si en vez de <texto.length() pongo
<=texto.length(). Estaré intentando acceder al índice 4, que no existe y me dará una excepción:

Ilustración 122. Salida 2 for string

77
José A. Navarro Java desde 0. Programación I

Al intentar acceder al 4 no puede y me dice que me he salido del rango permitido.

Cuidado, hemos visto nextLine() y


sí, existe un next() pero no hace lo
mismo. Leed bien la API.

10.1 Ejercicios
1. Realizar una calculadora básica de 4 operaciones (+, -, *, /) con menú. Los
resultados deben de ser congruentes.
2. Realizar los cambios pertinentes a la calculadora para que controle los números
de opciones válidos y que se ejecute preguntando una opción hasta seleccionar
5-salir.

3. Mostrar un texto introducido por teclado del revés

4. Decir si un texto introducido esta en mayúsculas o minúsculas


5. La conjetura de Collatz afirma que, al partir desde cualquier número, la secuencia
siempre llegará a 1. A pesar de ser una afirmación a simple vista muy simple, no
se ha podido demostrar si es cierta o no.

6. Realizar un programa que dado un número entero introducido por teclado


muestre su secuencia de Collatz. Siempre empieza en n y termina en 1

78
José A. Navarro Java desde 0. Programación I

11. Vectores
Hasta ahora hemos usado variables para guardar nuestros datos, pero imaginaros que
necesito guardar 100 enteros, crear una variable por cada uno no es inviable. Para esto existen
los vectores (arrays, matrices, arreglos…). Un vector es una estructura a la que se le da un
tamaño y un tipo y puede guardar tantos datos de ese tipo como su tamaño.

Los vectores son muy útiles en programación y todo el mundo debe de


saber usarlos. Sí, sé que en Java existe algo llamado ArrayList y muchas
cosas más, pero como siempre digo mi misión es enseñar a programar,
no a codificar copiando una API. Una vez sepamos caminar iremos en
bicicleta. PD: Mucha gente usa la clase ArrayList provocando un coste
mayor que el uso de vectores.

Los vectores son estructuras estáticas, una vez


definido su tamaño no se puede cambiar. Todos
los datos guardados en un vector deben de ser
del mismo tipo, no se pueden mezclar. (Más
adelante veremos cómo esto es modulable).

La mejor forma gráfica de representar un vector es mediante un rectángulo dividido en


casillas. Por ejemplo, un vector de 10 elementos con los números del 1 al 10 sería así:

índices 0 1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9 10
valores

Cada casilla del vector tiene un índice que es un entero y que comienza por 0 (similar a
los String). Podemos acceder a una casilla mediante su índice. Dado que los índices comienzan
por 0 si el vector es de 10 solo podemos llegar hasta el 9, si no nos salimos del vector y da una
excepción. Para saber la longitud de un vector podemos usar el nombre del vector seguido de
.length.

Este length NO lleva paréntesis ya que no es un


método

Para declarar un vector y acceder usamos los corchetes. Veamos varios ejemplos y lo
entenderemos mejor.

79
José A. Navarro Java desde 0. Programación I

Ilustración 123. Vector 1

1. En la línea 6 declaramos el vector, para ello ponemos primero el tipo del que va a
ser (todo el vector será de tipo int), luego para indicar que lo que estamos
declarando es un vector lo indicamos con corchetes, después viene el nombre del
vector. Una vez declarado le indicamos el tamaño usando el operador new
seguido del tipo y entre corchetes el tamaño. Hemos declarado un vector de
enteros de tamaño 5.
2. Para guardar un número en una casilla ponemos el nombre del vector y entre
corchetes el índice de la casilla donde queremos guardar el número y le
asignamos el valor (líneas de la 8 a la 11).

3. Para mostrar el contenido de la casilla de un vector podemos poner el nombre y


el índice de la casilla en un println.

4. También podemos sacar el contenido y guardarlo en una variable (num).

5. El hecho de guardar en una variable o mostrar el contenido de un vector NO


elimina lo que se encuentra en la casilla. El vector solo se ve afectado si está a la
izquierda de una asignación.

Ilustración 124. Salida vector 1

Cuidado: Java trata a los vectores como objetos si hacemos


vector1=vector2 no estamos haciendo una copia de
vector2 en vector1, vector1 apunta a la misma dirección de
memoria que vector2, son lo mismo. Esto lo explicaré más
detalladamente en el capítulo de objetos.

80
José A. Navarro Java desde 0. Programación I

Muchas veces nos va a suceder que a la hora de declarar un vector no sabemos su tamaño
porque depende de un cálculo o la entrada del usuario. Podemos declararlo arriba junto con las
demás variables y darle el tamaño cuando lo sepamos:

Ilustración 125. Vector 2

Fijaros como lo he declarado, le he pedido al usuario que introduzca el tamaño y luego lo


he inicializado.
Otra forma de inicializar un vector es cuando sabemos de antemano los valores que va a
tener:
int [] vec={2,5,3,7,8,4};

Se ponen los valores entre llaves separados por “,” sin usar el new. Java automáticamente
crea el vector con el tamaño necesario y asigna a cada índice su valor.

A diferencia de las variables “normales” los vectores sí se inicializan de


forma predeterminada. Si no les damos valor los enteros y decimales se
inicializan a 0, los boolean a false, los char a nada y los vectores de
objetos a null.

Obviamente rellenar un vector o mostrarlo casilla a casilla como en el ejemplo 1 es algo


arduo y tedioso. Para solucionar esto usamos las estructuras de repetición que hemos visto en
capítulos anteriores. ¿Cuál creéis que es la más usada con vectores? Si habéis pensado en el for
habéis acertado. Como vimos el for se usa cuando sabemos las veces que se va a repetir el bucle
y en un vector lo sabemos. Además, la variable de control de un for se suele usar para conseguir
el dato a guardar o algún resultado dado el vector.
Imaginad que queremos rellenar un vector con los 10 primeros números naturales, luego
multiplicar cada uno por 3 y terminar mostrando el resultado.

Para declarar un vector se puede usar la sintaxis C: int vec []. Donde el
nombre va antes de los corchetes. Yo os recomiendo usar la propia de
Java.

81
José A. Navarro Java desde 0. Programación I

Ilustración 126. Vector 3

1. En la línea 8 declaro y le doy el tamaño al vector.

2. En el primer for recorro el vector. El primer índice de un vector es 0 y el último


length, pero como yo quiero los números del 1 al 10 usando la propia i le sumo 1.
Cuando la i sea 0 pondrá un 1, cuando sea 1 un 2 …

3. Con el segundo for recorro el vector multiplicando lo que hay en cada casilla y
guardándolo en la misma.
4. El último for imprime por pantalla en horizontal y separados por un espacio los
números.

Ilustración 127. Salida vector 3

A la hora de aprender a usar vectores y poder rellenarlos con número


nos puede ser de gran utilidad la clase Random que se encuentra en
java.util. Esta clase tiene un método llamado nextInt(int x) que nos
devuelve un valor aleatorio entre 0 y x-1.

Rellenemos y mostremos un vector de 10 elementos con número aleatorios entre 0 y 9:

82
José A. Navarro Java desde 0. Programación I

Ilustración 128. Vector 4

Como veis al igual que el Scanner hay que importarla, una vez importada la forma más
fácil de crear un objeto “variable” para poder usarla es usar la sintaxis de la línea 7. Dentro del
primer for para generar un número aleatorio entre 0 y 9 llamo a nextInt(10) ya que el número
generado estará entre 0 y 10-1.

En esta ejecución podéis ver como se generan números distintos:

Ilustración 129. Salida vector 4

Cada fila se corresponde con una ejecución distinta.

¿Y si quiero números entre 15 y 36 por ejemplo?: 36-15=21 dado que saca un aleatorio
menos 21+1=22. Me explico:

Ilustración 130. Random

Veamos los valores máximos y mínimos: Cuando se genere un 0 le sumamos 15, ya


tenemos el valor mínimo. Como hemos puesto 22 el máximo que puede generar es 21, cuando
salga 21 si le sumamos 15 es igual a 36 ya tenemos el máximo. Números entre 15 y 36.

11.1 Ordenación
Una de las cosas más importantes que tienen que ver con vectores son los algoritmos de
búsqueda y ordenación. Dado que este manual no pretende enseñar estructuras de datos y que
Java ya tiene soluciones para esto no voy a explicarlas aquí, lo veré en el siguiente manual. No
obstante, si es importante probar, como mínimo, un algoritmo de ordenación y fijaros que he
dicho probar ya que este tipo de algoritmos ya están hechos y probados, simplemente hay que
conocerlos, pero no es necesario sabérselos de memoria.
Veamos el algoritmo de ordenación más simple que podemos encontrar, el de la burbuja.
El algoritmo de la burbuja sirve para ordenar cualquier tipo de vectores, si bien nosotros

83
José A. Navarro Java desde 0. Programación I

veremos el ejemplo con enteros. Este algoritmo lo que hace es ir desplazando los números
mayores hacia la derecha dejando los menores en la izquierda, como si fueran burbujas que van
subiendo. De ahí su nombre.

Ilustración 131. Algoritmo de la burbuja

Este sería un ejemplo de la primera iteración del algoritmo. El algoritmo seguirá


recorriendo el vector hasta su tamaño total.

Ejemplo en Java:

Si es mayor se
intercambian con
la ayuda de aux

Ilustración 132. Burbuja 1

Ilustración 133. Salida burbuja

Como podéis ver el algoritmo funciona pero se puede mejorar. El problema de este código
es que, aunque llegue un momento en que el vector ya este ordenado el sigue iterando hasta
que el primer for lo recorra todo. Para evitar esto podríamos hacer este cambio:

84
José A. Navarro Java desde 0. Programación I

Ilustración 134. Burbuja 2

Añadimos una variable booleana que nos indica cuando hay un cambio, en el momento
que sea false se sale de while sin terminar de recorrer lo que queda del vector.

11.2 Matrices
Los vectores pueden tener más de una dimensión, una matriz es un vector de dos
dimensiones. Imaginad que dentro de una casilla de un vector creamos otro vector y lo
representamos en columnas. Una matriz de 5x5 se vería así:

Filas

Columnas

Para posicionarnos en una casilla no es suficiente con una coordenada, necesitamos dos
(fila, columna). Para declarar una matriz usamos dos corchetes, el primero indica las filas y el
segundo las columnas. Para acceder a ella lo hacemos igual:
matriz[1][3]=7;
x=matriz[5][3];

Para recorrerlas necesitamos un for por cada dimensión:

85
José A. Navarro Java desde 0. Programación I

Ilustración 135. Matriz 1

1. En la fila 8 podéis ver como se declara usando dos corchetes

2. En la 10 necesitamos dos for (¡¡OJO!! Las variables de control no pueden llamarse


igual). Cuando el primer for tenga la i=0 el segundo pasará por todas sus j (j=0,
j=1…) y así sucesivamente de forma que por cada fila recorre todas las columnas.

3. Para mostrarla igual necesito los dos for, lo que hago es que para que salga por
pantalla de forma “bonita” cada vez que termina el for de las columnas imprimo
un retorno de carro.

Ilustración 136. Salida Matriz 1

Cuando necesitamos importar más de una clase de un paquete podemos


usar el * como comodín, que importa todas las clases de un paquete:
java.util.*

Las matrices no tienen por qué ser cuadradas (filas=columnas) por ejemplo creemos una
de 10x4:

86
José A. Navarro Java desde 0. Programación I

Ilustración 137. Matriz 2

Ilustración 138. Salida matriz 2

¿What? Algo ha ido mal. Si nos fijamos en el error la línea 12 está intentando acceder a al
índice 4 pero ese índice no existe, el máximo es 3. Lo que está sucediendo es que en el segundo
for hemos puesto j<matriz.length y length devuelve 10, siempre devuelve el tamaño de la
primera dimensión. Como antes era cuadrada no ha pasado nada, pero ahora j no puede llegar
a 10 solo a 3. Para especificar la longitud de la segunda dimensión lo que debemos es fijarnos
en una fila de la primera, realmente cualquiera vale, pero lo más fácil es usar la 0. Para ello
llamaremos a length pero de una fila en la primera dimensión:

Ilustración 139. Matriz 3

87
José A. Navarro Java desde 0. Programación I

Ilustración 140. Salida matriz 3

Las matrices pueden tener las dimensiones que queramos, 3 sería un cubo. Cada
dimensión que queramos añadir es un corchete más y un for más para recorrerla.

Aunque declaréis un vector o matriz y sepáis de antemano su tamaño


no lo pongáis a piño en los for, usad siempre length, de esta forma no os
equivocareis sin querer y cambiando solo las dimensiones de la
declaración todo seguirá funcionando.

11.3 Ejercicios
1. Rellenar un vector con números del 0 al 9 y mostrarlo por pantalla.

2. Rellenar un vector con números del 1 al 10 y mostrarlo por pantalla.

3. Realizar un programa que dado un vector de 50 números aleatorios de 1 a 100


calcule la suma de todos y la media aritmética.

4. Hacer un programa que cree un vector de n elementos y lo rellene con números


aleatorios del 1 al 100. Una vez lleno, mostrarlo por pantalla. Luego mostrar los
números repetidos del vector junto a su número de apariciones. El número n lo
pedirá por pantalla. Hay que controlar que el usuario solo pueda introducir
números enteros, si no introduce un numero entero lo seguirá pidiendo.

5. Realizar un programa que mantenga una pequeña base de datos básica usando
vectores sobre los alumnos matriculados y sus notas. El programa pedirá cuantos
alumnos van a haber y luego pedirá el nombre y la nota de alumnos hasta
introducir la letra ‘s’. Luego me permitirá consultar sus datos mediante el número
de referencia asignado a los alumnos (índice) hasta introducir -1, con lo que
terminará. Si se intentan matricular más alumnos de los permitidos el programa
avisará de que el cupo ya está lleno. Hay que controlar que los índices para
consultar sean válidos.
6. Crear y cargar dos matrices de tamaño 3x3 con números aleatorios. Mostrarlas.
Sumarlas y mostrar su suma.

7. Generar una matriz cuadrada simétrica de 10x10 usando números aleatorios


entre el 10 y el 99 y mostrarla por pantalla.

8. Una matriz cuadrada es simétrica si∀i,j ∈M⇒M(i,j)=M(j,i)

88
José A. Navarro Java desde 0. Programación I

12. Métodos
Hasta ahora hemos usado métodos ya definidos en alguna clase de la API de Java
(nextLine, println…). Ahora vamos a aprender a crear nuestros propios métodos en la clase
principal, junto al main para luego ya poder crearlos en las clases que queramos.

Los métodos se distinguen por un nombre, pueden tener uno, varios o ningún parámetro
de entrada y devolver o no un resultado. También tienen un ámbito y siempre van entre llaves.
public [static] void sumar (int x, double z){

}
Parámetros de entrada

Tipo de dato que Nombre


devuelve

Sin instancia

Modificador de ámbito. Página 109

Ejemplos:
1. Método que muestra por pantalla “hola”
public static void mostrar(){

System.out.println(“hola”);

2. Método que muestra por pantalla “hola” dato tu nombre


public static void mostrar(String nombre){

System.out.println(“hola ”+ nombre);

3. Método que muestra por pantalla la suma de dos enteros


public static void sumar(int x, int y){

System.out.println(“la suma es:”(x+y));

4. Método que calcula la suma de dos enteros y devuelve el resultado al programa


principal
public static int sumar(int x, int y){

return x+y;

89
José A. Navarro Java desde 0. Programación I

Cuando se llama a un método el programa se apunta la línea donde estaba y salta hasta
la dirección de memoria donde está el método. Cuando termina de ejecutar el método se vuelve
a la línea almacenada que es la siguiente a la de la llamada.

Imaginemos el ejemplo 1: Para llamar al método desde el programa principal (main)


haríamos esto:
mostrar();

El programa salta hasta la dirección del método y lo ejecuta. Luego vuelve al main. Saldrá
por pantalla: “hola”.

Los métodos pueden devolver un resultado al main después de ejecutarse. Ese resultado
se puede guardar en el main en una variable.

Imaginemos el ejemplo 2: Para llamar al método desde el programa principal (main)


haríamos algo así:
mostrar(“pepe”);

Se llama por su nombre y entre paréntesis se le pasa lo que necesita para realizar su tarea,
en este caso un String. Fijaros como el siguiente código no tendría sentido:
int x;
x=mostrar(“pepe”);

El método está declarado como void, por lo que no devuelve ningún resultado, lo que
hace lo hace desde dentro sin devolver ningún dato al main. Mostraría por pantalla: “Hola pepe”.
Sigamos y lo entenderéis.

12.1 Static
Cuando declaramos un método como static en una clase significa que ese método va a
ser el mismo para todos los objetos que se creen. Esto es un poco complejo de explicar antes de
ver como declarar nuestras propias clases, de momento como vamos a crear todos los métodos
en la misma clase donde se encuentra el main, los declararemos como static. Cuando lleguemos
al capítulo de las clases lo entenderéis fácilmente. Se podría decir que se encuentra en un
entorno estático, no instanciable (no se necesita crear un objeto para usarlo).

12.2 Modificador de ámbito


Los modificadores de ámbito me permiten definir desde donde puede ser o no accedido
un método. Nos podemos encontrar con public (cualquier sitio), es el que usaremos nosotros de
momento, protected y private. Estos modificadores se verán con más detalle en próximos
capítulos10. Todos los métodos que usemos en este capítulo serán public static ya que se
encuentran en la misma clase que el main.

10
Página 109

90
José A. Navarro Java desde 0. Programación I

12.3 Return
Veamos ahora el ejemplo 4: En el main el código, por ejemplo, sería este:
int x;
x=sumar(5,2);

La variable x acaba teniendo un 7. Veamos los pasos:

 Declaro la variable x.

 Java ve que la segunda línea es una asignación, con lo que primero tiene que
resolver la parte de la derecha, se da cuenta que es un método y lo llama
pasándole los valores 5 y 2, ya que son los parámetros que necesita el método
para funcionar (dos parámetros de tipo int).

 Java se va al código donde se encuentra el método sumar y lo ejecuta. Se


encuentra con un return de una suma. Calcula la suma y sobre el resultado ejecuta
el return. El return podríamos decir que asigna al nombre del método el resultado
(7) y devuelve la ejecución al main.

 El main ya sabe que la parte de la derecha de la asignación vale 7 y lo guarda en


la x.

Al final la x vale 7.

Como este método va a devolver un entero, va a tener un return


por lo que no ponemos void sino el tipo que va a devolver: int
public static int … El void se usa cuando un método no devuelve
nada, no hay return.

Un return dentro de un método siempre para la ejecución del mismo y devuelve la


ejecución al método que lo llamó, por ejemplo, el main. El uso del return de forma
indiscriminada provoca los mismos problemas que un break ¿eso significa que no puedo poner
más de uno?, no, si el código es simple y se entiende enseguida no pasa nada por poner más de
uno, por ejemplo:
if(x>0)
return true;
else
return false;

En este código solo se ejecutará un return, dependiendo de si entra en el if o en el else y


está muy claro, pero no abuséis de esto, usad variables temporales y poned un solo return al
final del método.

91
José A. Navarro Java desde 0. Programación I

Ejemplos:

En el primer ejemplo el método está declarado como void, no devuelve nada, cuando
termina sigue con la siguiente línea donde se ha quedado en el main. Se le llama por su nombre
y no necesita nada:

Ilustración 141. Ejemplo void

Ilustración 142. Salida void

En el segundo ejemplo vamos a realizar un método que calcule la media de dos números
enteros. Devuelve un double que lo recoge el main y lo imprime. El método ya no es void y tiene
un return indicando lo que va a devolver. También cuenta con dos parámetros que indican los
números de los que se quiera sacar la media. Divido por 2.0 para que haga la división decimal:

Ilustración 143. Return

92
José A. Navarro Java desde 0. Programación I

Ilustración 144. Salida Return

12.4 Paso de parámetros


Cuando hablamos de parámetros nos referimos a los datos que se le hacen llegar a un
método para que pueda realizar su cometido.

Nos encontramos con dos tipos, los parámetros formales y los parámetros reales:

 Parámetros formales: Son las variables que recibe el método, se crean al definir
el mismo, son los que se ponen entre paréntesis y se usan como variables locales
dentro del método. Su contenido lo recibe al realizar la llamada al método de los
parámetros reales. Cuando el método termina su ejecución, mueren.

 Parámetros reales: Son las expresiones que se utilizan en la llamada al método,


sus valores se copiarán en los parámetros formales.

Ejemplo:

Formales

Reales

Ilustración 145. Parámetros formales y reales

El nombre de los parámetros formales y reales no tienen por qué


ser distintos. En el caso anterior a los formales les podríamos haber
llamado numero1 y numero2 haciendo r=numero1+numero2 y
hubiera funcionado igual. Una cosa es el nombre dentro del método
y otra fuera. Si los ponemos igual Java no se va a liar. Si sois noveles
os recomiendo ponerlos distintos hasta que os hagáis a la
programación.

Los parámetros en java se pueden pasar de dos formas:

93
José A. Navarro Java desde 0. Programación I

 Por valor: se le pasa al método una copia del valor de la variable, de esta forma si
el parámetro sufre algún cambio dentro del método no se ve reflejado en la
variable del llamante.

Ilustración 146. Parámetros por valor

El resultado es:

Ilustración 147. Salida por valor

Veamos que ha ocurrido en la memoria principal: Primero se ejecuta el main, crea la


variable x guardando un 5 en ella, luego crea la variable y guardando un 1 en ella.

Dirección Nombre que le da Contenido Línea de


java código
0x00F2 x (main) 5 12
0x00F4 y (main) 1 13
0x00F6
0x00F8
0x00FA
0x00FC
0x00FE
Tabla 15.Ejemplo parámetros por valor 1

Crea la variable suma sin inicializarla.

94
José A. Navarro Java desde 0. Programación I

Dirección Nombre que le da Contenido Línea de


java código
0x00F2 x (main) 5 12
0x00F4 y (main) 1 13
0x00F6
0x00F8
0x00FA suma null 14
0x00FC
0x00FE
Tabla 16. Ejemplo parámetros por valor 2

Llama al método sumar pasándole una copia de los valores de x e y.

Dirección Nombre que le da Contenido Línea de


java código
0x00F2 x (main) 5 12
0x00F4 y (main) 1 13
0x00F6
0x00F8
0x00FA suma null 14
0x00FC x de sumar 5 6
0x00FE y de sumar 1 6
Tabla 17. Ejemplo parámetros por valor 3

Se crea z con el resultado de la suma.

Dirección Nombre que le da Contenido Línea de


java código
0x00F2 x (main) 5 12
0x00F4 y (main) 1 13
0x00F6
0x00F8 z 6 7
0x00FA suma null 14
0x00FC x de sumar 5 6
0x00FE y de sumar 1 6
Tabla 18. Ejemplo parámetros por valor 4

Guarda un 100 en la x del método.

Dirección Nombre que le da Contenido Línea de


java código
0x00F2 x (main) 5 12
0x00F4 y (main) 1 13
0x00F6
0x00F8 z 6 7
0x00FA suma Null 14
0x00FC x de sumar 100 8
0x00FE y de sumar 1 6
Tabla 19. Ejemplo parámetros por valor 5

95
José A. Navarro Java desde 0. Programación I

El método devuelve z. Al terminar el método su x, z e y mueren. La y del main no se ha


modificado porque se había pasado una copia de su valor, sigue valiendo 1. Al final suma vale 6.

Dirección Nombre que le da Contenido Línea de


java código
0x00F2 x (main) 5 12
0x00F4 y (main) 1 13
0x00F6
0x00F8
0x00FA suma 6 15
0x00FC
0x00FE
Tabla 20. Ejemplo parámetros por valor 6

 Por referencia: al método se le pasa un puntero a la memoria donde se guarda la


variable, vamos, la dirección de memoria de la variable original. Veamos: En el
siguiente ejemplo creo un vector de tres posiciones con los números 1, 2 y 3. Lo
muestro y luego llamo al método para intentar cambiar el número de la posición
1.

Ilustración 148. Parámetros por referencia

Salida por pantalla:

Ilustración 149. Salida Parámetros por referencia

Veamos que ha ocurrido en la memoria principal: Se crea el vector vec

96
José A. Navarro Java desde 0. Programación I

Dirección Nombre que le da Contenido Línea de


java código
0x00F2 vec[0](main) 1 11
0x00F4 vec[1](main) 2 11
0x00F6 vec[2](main) 3 11
0x00F8
0x00FA
0x00FC
0x00FE
Tabla 21. Ejemplo parámetros por referencia 1

Como Java ha pasado la variable vec por referencia, vec y vector son lo mismo, no es una
copia, sino que apuntan a la misma dirección de memoria.

Dirección Nombre que le da Contenido Línea de


java código
0x00F2 vec[0](main) 1 11
0x00F4 vec[1](main) 2 11
0x00F6 vec[2](main) 3 11
0x00F8
0x00FA vector en cambiar 0x00F2 6
0x00FC
0x00FE
Tabla 22. Ejemplo parámetros por referencia 2

Cambio el contenido de la posición 1 del vector, pero como son el mismo se cambia en el
original.

Dirección Nombre que le da Contenido Línea de


java código
0x00F2 vec[0](main) 1 8
0x00F4 vec[1](main) 87 11
0x00F6 vec[2](main) 3 11
0x00F8
0x00FA vector en cambiar 0x00F2 6
0x00FC
0x00FE
Tabla 23. Ejemplo parámetros por referencia 3

Cuando termina el método y muestra el vector lo hace con los cambios.

Dirección Nombre que le da Contenido Línea de


java código
0x00F2 vec[0](main) 1 8
0x00F4 vec[1](main) 87 11
0x00F6 vec[2](main) 3 11
0x00F8
0x00FA
0x00FC
0x00FE
Tabla 24. Ejemplo parámetros por referencia 4

97
José A. Navarro Java desde 0. Programación I

El acceso a una casilla del vector se hace sumando lo que ocupa


cada casilla a la dirección de la primera que se guarda en memoria.

12.5 Recursividad
La recursividad es una propiedad que tienen los métodos (funciones en otros lenguajes)
de llamarse a sí mismas para resolver un problema. En el cuerpo del método se encuentra una
sentencia que es una llamada al propio método. Veamos un ejemplo y su funcionamiento:

El factorial de un número es un problema por sí mismo recursivo:

n!=n*(n-1)!
El factorial de 4 es: 4!=4*3*2*1 (no pongo el 0 cuyo factorial es 1). De forma que el
factorial es el producto del número por todos los anteriores hasta uno, por tanto podríamos
pensar que para calcular el factorial de n llamamos al método y desde el cuerpo de este se va
llamando a si mismo tantas veces como necesita con n-1. Obviamente esto tiene un peligro y es
crear un bucle infinito que produzca que no se salga nunca del método, incluso que acabemos
con la memoria disponible, para que esto no suceda debemos de asegurarnos de que en un
momento las llamadas terminarán, en este caso cuando n sea 1.

Las consecutivas llamadas al método se van apilando en la memoria, pues el método no


sabe el factorial de 4, 3 o 2, pero llega un momento en que se pide el factorial de 1 y ese sí sabe
resolverlo: return 1. Cuando esto sucede ya puede ir calculando el factorial de 2, 3 y 4
desapilando de la memoria y liberándola.

Ilustración 150. Recursividad

Hagamos una traza, imaginemos n=4

1. Cuando entra en la función ve que n es distinto de


1 y ejecuta el else llamando al propio método, Pila
posponiendo la decisión de calcular el factorial de 1
4 y apilando la llamada a factorial de (n-1).
2. La segunda vez que entra n=3, tampoco puede 2*factorial(1) 2
resolverlo, apila factorial de (n-1).
3. La tercera vez n=2, tampoco puede resolverlo, apila 3*factorial(2) 6
factorial de (n-1). 4*factorial(3) 24
4. La cuarta vez n=1 y esto sí sabe resolverlo ya que si
if(n==1) return 1, en otras palabras le hemos dado

98
José A. Navarro Java desde 0. Programación I

una salida y es que cuando n es igual a 1 debe de


devolver 1.
5. Ahora comienza a desapilar y calcular
factorial(2)=2*1.
6. factorial(3)=3*2
7. factorial(4)=4*6=24. En este punto termina y el
método nos puede dar el resultado: 24

Cosas a tener en cuenta de la recursividad:


 Tiene un mayor coste, tanto en tiempo de ejecución como en memoria.
 Es más limpia y legible.
 Hay problemas que tienen una solución propiamente recursiva
(factorial, torres de Hanoi…).
 Siempre será más rápido y tendrá un menor coste una solución
iterativa.

Recordemos con lo aprendido en capítulos anteriores como sería el ejemplo del factorial
de forma iterativa y por ende menos costosa.

Ilustración 151. Factorial iterativo

Cosas a tener en cuenta sobre los métodos:

 A la línea que define el método se le llama cabecera. El código entre llaves es el


cuerpo.

 En la cabecera ponemos static cuando se encuentran en una clase que no se va a


instanciar (de momento siempre).

 Ponemos void cuando no queremos que devuelvan ningún resultado.

 Si devuelven algo siempre ponemos el tipo que devuelven en la cabecera y se usa


la palabra reservada return en el cuerpo.

 Las nombramos con nombres significativos.

 Si el nombre está compuesto por más de una palabra escribimos todo en


minúscula excepto la primera letra a partir de la segunda palabra
(sumarNumerosPares).

 Después del nombre siempre van paréntesis, aunque no se necesiten parámetros.

 Los parámetros son los valores que el método necesita para hacer su cometido.

99
José A. Navarro Java desde 0. Programación I

 Se llaman parámetros formales a las variables declaradas entre paréntesis, se


crean al definir la función. Su contenido lo recibe al realizar la llamada al método
de los parámetros reales. Los parámetros formales son variables locales dentro
de la función.

 Se llaman parámetros reales a las expresiones que se utilizan en la llamada al


método, sus valores se copiarán en los parámetros formales.

 Los métodos deben de realizar cosas simples, no muchas cosas en uno solo.

 Por norma general, los métodos no deben de comunicarse con el exterior


(teclado, pantalla), eso es problema del programa principal.

12.6 Ejercicios
1. Realizar un programa usando métodos que me diga si una frase introducida por
teclado es un palíndromo.
2. Realizar un programa usando métodos que me diga la letra de un DNI.

3. Un programa con un método que reciba dos vectores de 10 elementos y devuelva


uno de 20 ordenado ascendentemente. Se generarán con números aleatorios de
1 a 100. hay que mostrarlos todos.

4. Crear un programa para jugar al tres en raya. Dividir el juego en métodos por
ejemplo: comprobarDiagonal, comprobarColumnas, tirada, etc.

100
José A. Navarro Java desde 0. Programación I

13. Clases
En este capítulo vamos a “pegar” todas las piezas que hemos ido viendo y utilizar la
orientación a objetos. Como comentaba al principio del manual, el mundo lo podemos ver como
objetos, todo son objetos (coches, personas, lápices, …), la programación orientada a objetos lo
que trata es de subir un nivel más la abstracción de forma que programar se aproxime más a
nuestra forma de interactuar en la vida real, dado que en la vida real tenemos una serie de
objetos y los usamos, en Java también. Por ejemplo, en la vida real existe un objeto llamado
coche que tiene unas propiedades (color, matricula…) y una serie de acciones que se pueden
realizar sobre él (conducir, repostar…), en programación orientada a objetos crearemos esos
objetos y los usaremos.

Un objeto tiene una serie de características:

 Identidad: Cada objeto es único y diferente de otro. Yo puedo tener dos coches,
pero no son el mismo, son dos coches distintos.

 Estado: Son las propiedades o atributos que tiene ese objeto (color, peso,
matricula…)

 Comportamiento: Las cosas que puede hacer, los métodos que tiene (repostar,
conducir, aparcar…).

 Mensajes: Los objetos pueden interactuar entre ellos usando los métodos.

 Métodos: Los métodos propiamente dichos y que pueden realizar cálculos,


acciones, cambiar las propiedades, etc.

String, Scanner, Random son clases que ya hemos usado, aunque no sepamos
muy bien el funcionamiento. Aparte de entenderlas vamos a aprender a crear
las nuestras propias. Haciendo las nuestras entenderemos la API.

Para explicar la orientación a objetos, como en otros apartados lo haré a través


de ejemplos sucesivos de más simples a más complejos hasta llegar a verlo tal
como debe de ser.

101
José A. Navarro Java desde 0. Programación I

13.1 Clases vs objetos


Esta es una diferencia importante y que debemos tener clara. Vamos a ver primero un
ejemplo y luego lo explicamos. Imaginemos un objeto coche, un coche tiene una serie de
propiedades y de métodos, por ejemplo:

Coche
Matricula
Bastidor
Color
Marca
Modelo

conducir(double km) //conduce unos Km
repostar(double litros) //pone gasolina
imprimir() //muestra los datos

En una clase definimos el nombre, las propiedades y los métodos (comportamiento) que
van a tener todos los objetos de tipo coche. Podríamos ver una clase como una plantilla de la
que se van a crear los objetos. Cuando nosotros creamos un coche concreto (instanciamos), por
ejemplo, un Ford Fiesta con matricula 1234CFV, bastidor: 1243gj4589839, de color rojo; eso es
un objeto. Realmente se dice que hemos instanciado un coche creando uno en concreto.

Lo mismo pasaría con la clase Persona, la clase definiría lo que es una persona, pero
cuando la instanciamos creando una persona en concreto, distinta de las demás, eso es un
objeto.

Veamos un ejemplo simple:

Ilustración 152. Primera aproximación clases

102
José A. Navarro Java desde 0. Programación I

Ilustración 153. Test Clases 1

Ilustración 154. Salida Clases 1

En el primer código podemos ver la declaración de la clase. Defino la clase llamada


Persona con sus propiedades y dos métodos, uno muestra los datos y otro calcula la retención
dependiendo de la edad y si está jubilado. El segundo código es el programa principal (main),
podemos observar como en la línea 6 instanciamos la clase persona creando un objeto llamado
pepe, para ello usamos el operador new. Su sintaxis es: <clase> nombreObjeto=new <clase>().
Tras declararlo le damos valores a las propiedades y para ello usamos el “.”, el punto se usa para
separar el nombre de la clase del elemento al cual queremos acceder, sea propiedad o método.
De esta forma poniendo el nombre del objeto y después un punto podemos ir accediendo a sus
propiedades tanto para verlas como para modificarlas y a sus métodos para usarlos. En la salida
podemos ver como se muestran los datos del objeto y la retención con 67 años y su modificación
tras aumentar los mismos.

Si en ese código creamos otra persona por ejemplo Pedro, las propiedades y métodos de
Pepe y Pedro están guardados en posiciones distintas de memoria, el cambiar algo o actuar
sobre uno de ellos no repercute sobre el otro, sólo usan la misma clase (plantilla) para crearse.

 Java permite declarar más de una clase en un único fichero, pero ese es
tema del siguiente manual, de momento cada clase debe de guardarse en
un fichero con “exactamente” el mismo nombre. Si la clase se llama “Pepe”
se tiene que guardar en el fichero Pepe.java.
 Es una buena práctica y denota conocimiento, que las clases comiencen
con la primera letra en mayúsculas.
 Dado que estamos usando Geany en modo súper simple, para que cuando
instanciamos una clase la encuentre la guardaremos en la misma carpeta.
En próximos manuales veremos el uso de paquetes con otros IDE.
 Todos los objetos se instancian con el operador new

103
José A. Navarro Java desde 0. Programación I

13.2 ¿Qué pasos sigue java para crear un objeto?


A la hora de crear un objeto Java sigue una serie de pasos:

1. Carga el fichero en memoria.

2. Ejecuta los inicializadores static.


3. Crea el objeto

a. Asigna la memoria necesaria para el objeto mediante el operador new.

b. Inicializa propiedades.

c. Inicializadores del objeto.

d. Ejecuta el constructor.

Los inicializadores static son un bloque de código que se ejecutará una sola vez al usar la
clase, a diferencia del constructor que luego veremos.

Este tipo de inicializadores no devuelven ningún valor, son métodos sin nombre y entre
otras cosas se suelen usar para inicializar objetos complejos, inicializan propiedades static, y
permiten gestionar las excepciones.

13.3 Constructores
En la primera aproximación de la clase Persona hemos visto como se crea el objeto y luego
le damos valores a sus propiedades, pero sería interesante poder crear un objeto ya con los
datos que queremos.

Un constructor sirve para que Java reserve la memoria que necesita para el objeto e
inicializar este. Nos podemos encontrar con dos casos:

 Constructor por defecto (primera aproximación): No especificamos nosotros el


constructor, de manera automática Java ejecuta el constructor por defecto para
reservar memoria e inicializar el objeto.

 Constructor definido: Nosotros especificamos un constructor en la clase que se


ejecutará cada vez que se cree un objeto, Java primero reservará la memoria lo
inicializará todo y luego lo ejecutará de forma automática. El constructor debe de
tener el mismo nombre que la clase, puede recibir parámetros y siempre tiene
que ser public, hay muchos programadores que omiten el modificador de acceso.

Veamos como cambiaria sabiendo esto nuestro ejemplo:

104
José A. Navarro Java desde 0. Programación I

Ilustración 155. Segunda aproximación clases

Ilustración 156. Test Clases 2

Ilustración 157. Salida clases 2

Como podéis observar el constructor funciona como un método normal en el sentido de


que recibe unos parámetros de un tipo y en un orden y lo que hace es asignar esos valores a las
propiedades, evitando tener que hacerlo luego. Un constructor también puede realizar
operaciones. Esta forma de crear los objetos es la más usada, de hecho, es recomendable poner
un constructor vacío si no se necesita inicializar nada, pues en aplicaciones más complejas y de
Java EE son necesarios.

En Java pueden existir, en una clase, más de un constructor con el mismo nombre siempre
y cuando el tipo y número de parámetros que recibe no sea el mismo, esto es muy útil pues nos

105
José A. Navarro Java desde 0. Programación I

permite crear objetos de distinta forma dependiendo de los datos que usemos como
parámetros.

Veamos un ejemplo:

Ilustración 158. Tercera aproximación

Ilustración 159. Test Clases 3

Como se puede observar existen tres constructores, el primero necesita todos los datos,
el segundo solo el nombre y apellidos, el último nada. De esta forma pepe tiene todos sus datos,
luis solo el nombre y apellidos, no sabemos su edad ni si está jubilado, de pedro no sabemos
nada.

106
José A. Navarro Java desde 0. Programación I

Algunos lenguajes como C++ tienen destructores para liberar memoria, cerrar
conexiones, … antes de terminar el programa. Java NO tiene destructores, existe
un método llamado finalize con el fin de liberar memoria llamando al garbage
collector (recolector de basura), pero en Java no se puede predecir cuándo se va a
ejecutar ese proceso, podríamos decir que pasa cuando “le da la gana”, por todo
esto lo mejor es dejarlo en manos de la máquina virtual java.

13.4 La referencia this


Para hacer referencia al objeto que se está ejecutando usamos this. Esta referencia se
suele usar cuando puede haber una confusión entre propiedades y métodos, por ejemplo, si
vemos el código de la 3ª aproximación visto antes en el constructor no hay posibilidad de que
java confunda los parámetros con las propiedades:

Ilustración 160. Constructor sin this

A los parámetros formales les hemos puesto nombres distintos a las propiedades, pero la
mayoría de veces esto no es una buena práctica pues los nombres no son representativos y por
tanto no ayudamos a la legibilidad del código. Una mejor opción hubiera sido la siguiente:

Ilustración 161. Constructor sin this, mal

Como podéis ver esto es más legible, pero tiene un pequeño problema: cuando hacemos
dentro del constructor nombre=nombre Java no sabe distinguir a que nos referimos en cada
parte de la asignación, de hecho, saberlo lo sabe, se cree que nos referimos a los parámetros.
Para resolver este problema usamos el this.

107
José A. Navarro Java desde 0. Programación I

Ilustración 162. Constructor con this

Al anteponer al nombre de la propiedad el this (separándolo con un punto) le estamos


indicando “yo mismo”, en otras palabras, hace referencia al propio objeto que se creará en el
main, de esta forma siempre que pongamos el this delante sabe que nos referimos a las
propiedades ya que esos nombres referidos al propio objeto solo pueden ser estas. De esta
forma evitamos confusiones y hacemos el código legible.

Cuando java busca el nombre de una “variable” lo hace de fuera hacia dentro de los
métodos. Primero mira si el nombre es una variable local en el método, si existe
entiende que nos referimos a la variable, si no la encuentra busca en los parámetros,
si lo encuentra nos estamos refiriendo a ese parámetro, si no lo busca en las
propiedades. Si no lo encuentra es cuando ya da error. Con el this hacemos que
siempre sepa que nos referimos a alguna propiedad.

Cuidado: si llamamos a una variable local igual


que a un parámetro estaremos ocultando el
acceso al parámetro y no podremos usarlo.

13.5 Modificadores de acceso


En la programación orientada a objetos las clases nos permiten abstraer el problema a
resolver ocultando los datos y como solucionamos el problema. Una clase o un método de una
clase no tiene por qué saber cómo se ha solucionado un problema, por ejemplo: durante el
manual hemos usado la clase Scanner y sus métodos, pero yo no sé cómo están hechos. Otra
cosa muy importante de la POO es que no se debe de poder acceder directamente a las
propiedades de un objeto desde otro. Por todo esto existen unos modificadores de acceso que
nos indican quien puede acceder a que método o propiedad:

 Público (public): Un método o propiedad pública puede ser accedida desde


cualquier otra clase o subclase que se necesite.

 Privado (private): Solo se puede acceder desde dentro de la propia clase.

 Protegido (protected): Se pueden acceder desde clases o subclases que están en


el mismo paquete o carpeta.

108
José A. Navarro Java desde 0. Programación I

Modificador de acceso public protected private Sin especificar


¿El método o propiedad es accesible
SÍ SÍ SÍ SÍ
desde su propia clase?
¿El método o propiedad es accesible
desde otras clases en el mismo paquete SÍ SÍ NO SÍ
(carpeta)?
¿El método o propiedad es accesible
desde una subclase en el mismo paquete SÍ SÍ NO SÍ
(carpeta)?
¿El método o propiedad es accesible
SÍ * NO NO
desde subclases en otros paquetes?
¿El método o propiedad es accesible
SÍ NO NO NO
desde otras clases en otros paquetes?
(*) No se suele dar. Se podría acceder a los miembros desde objetos de las subclases, pero no de la superclase
(veremos qué es esto más adelante)
Tabla 25. Modificadores de acceso

Veamos cómo aplicar esto a nuestro ejemplo:

Ilustración 163. Cuarta aproximación

109
José A. Navarro Java desde 0. Programación I

Ilustración 164. Acceso erróneo

Como podemos ver en la clase Persona hemos añadido los modificadores de acceso. Las
propiedades son de tipo private, el modificador se pone a la izquierda del tipo. Al ser private no
puede ser accedido por ninguna otra clase. Los constructores son public de forma que pueden
ser accedidos desde cualquier clase, pensad que es lógico ya que se tienen que poder ejecutar
al construir un objeto. (en este caso no es necesario ponerlo ya que al no poner nada actúan de
igual forma. Es importante recalcar que, aunque es una práctica común no ponerlo en los
constructores, en los demás métodos es conveniente especificar siempre el modificador de
manera explícita).

Para ver un ejemplo de un método he dividido el cálculo de la retención en dos métodos,


uno realiza el cálculo y el otro devuelve el valor. Este método es llamado desde
mostrarRetencion(). Este último es public ya que tiene que poder ser llamado desde otras clases,
pero calcularRetencion() solo va a ser llamado por mostrarRetencion() por lo que es private,
nadie desde fuera de la clase tiene acceso a él.

Veamos ahora a la clase Prueba: las líneas de la 6 a la 8 se ejecutarán sin problemas, pero
la línea 10 está intentando acceder a una propiedad que es privada, el compilador se da cuenta
y nos avisa de que no puede hacerse, no dejando compilar la clase. Esto sucedería tanto para
guardar algo en una propiedad, como es el caso, como para leerla.

Por norma no se debe de tener acceso a la estructura interna de las clases, esto implica
que las propiedades serán privadas y aquellos métodos que no sea necesario usar desde fuera
de la clase también. Pero, si las propiedades de un objeto tienen que ser privadas ¿Cómo puedo
modificarlas o consultarlas?, muy simple, con los llamados getter’s y setter’s. Un getter es un
método, publico que me devuelve el valor de una propiedad y un setter es un método, también
publico, que me permite cambiar el valor de una propiedad. El nombre de estos métodos se
forma de la siguiente forma:

El prefijo set o get seguido del nombre de la propiedad teniendo en cuenta que el primer
carácter de esta se escribe en mayúsculas. Nosotros podríamos crear los métodos con los
nombres que quisiéramos, pero si hacemos eso el código será menos legible y opciones más

110
José A. Navarro Java desde 0. Programación I

avanzadas de Java SE o Java EE no funcionarán correctamente. Por tanto, sigamos las buenas
prácticas de Java, veamos un ejemplo:

Ilustración 165. Setter's y getter's

Para solucionar el error de compilación del ejemplo anterior usaríamos:


pedro.setNombre(“Pedro”);

13.6 Static
En Java no existen variables globales, esto significa que para que todos los objetos de una
clase compartan una única propiedad debe de ser declarada como static.

En el ejemplo anterior vemos como la propiedad numPajaros está declarada como static
(se pone después del modificador de acceso), esto hace que todos los objetos de tipo Pajaro

111
José A. Navarro Java desde 0. Programación I

compartan la misma propiedad, en la misma posición de memoria, lo que significa que si un


objeto pájaro la modifica lo hace para todos los pájaros. En el ejemplo podemos ver como el
constructor tiene un incremento de esa propiedad, numPajaros++, esto hace que cada vez que
se ejecute, se cree un pájaro e incremente el número en 1, por tanto, por el simple hecho de
crear un pájaro se incrementa el número de pájaros. Consultando esa propiedad en cualquier
pájaro obtendremos el número de pájaros que tenemos.

El siguiente código crea tres pájaros y consulta el número de pájaros usando uno de ellos,
el resultado será 3:

Ilustración 166. Propiedad static

Da igual quien llame al método getNumPajaros, el resultado será el mismo.

Los métodos con static son llamados de clase y los métodos “normales” se llaman de
instancia.

Reglas:
 Los métodos static no tienen referencia this.
 Un método static no puede acceder a miembros que no sean static
 Un método no static puede acceder a miembros static y no static

La clase Math del paquete java.lang donde se encuentran los métodos para
realizar operaciones matemáticas, se conoce como una clase estática, pues todos
sus métodos son static. Para calcular una raíz cuadrada no instanciamos un objeto
simplemente usamos el nombre de la clase y el método a usar: Math.sqrt(25).
Veremos esto en los anexos.

13.7 Final
Java no tiene constantes como tal, pero tenemos una forma de hacer que una propiedad
de un objeto no pueda cambiar. Para ello usamos el modificador final.

112
José A. Navarro Java desde 0. Programación I

Ilustración 167. Modificador final

Cuando usamos final después del modificador de acceso le estamos diciendo que esa
propiedad no puede ser cambiada. Cuando se declara no es necesario darle un valor siempre
pero sólo se puede hacer una única vez. Lo habitual es inicializarla en la misma declaración.
PATAS vale 2 para siempre. Es habitual usar static junto con final para que todos los objetos
compartan la misma dirección de memoria de esa propiedad ya que esta no va a cambiar. Es
habitual y de buena praxis escribir las propiedades final en mayúsculas.

14. Herencia
La Herencia es uno de los 4 pilares de la programación orientada a objetos (POO) junto
con la Abstracción, Encapsulación y Polimorfismo. La herencia es un mecanismo que permite la
definición de una clase a partir de la definición de otra ya existente. La herencia permite
compartir automáticamente métodos y datos entre clases, subclases y objetos. Otra forma de
ver la herencia es la de “sacar factor común” al código que escribimos.

El ejemplo que proponemos es un caso en el que vamos a simular el comportamiento que


tendrían los diferentes integrantes de la selección española de futbol; tanto los Futbolistas como
el cuerpo técnico (Entrenadores, Masajistas, etc…). Para simular este comportamiento vamos a
definir tres clases que van a representaran a los objetos Futbolista, Entrenador y Masajista. De
cada uno de ellos vamos a necesitar algunos datos que reflejaremos en las propiedades y una
serie de acciones que reflejaremos en sus métodos. Estos atributos y métodos los mostramos
en el siguiente diagrama de clases:

Ilustración 168. Diagrama herencia

113
José A. Navarro Java desde 0. Programación I

Como se puede observar, vemos que en las tres clases tenemos propiedades y métodos
que son iguales:

Ilustración 169. Factor común en herencia

Lo que podemos ver en este punto es que estamos escribiendo mucho código repetido ya
que las tres clases tienen métodos y propiedades comunes, de ahí que decimos "sacar factor
común" para no escribir código repetido, por tanto lo que haremos será crearnos una clase con
el "código que es común a las tres clases" (a esta clase se le denomina en la herencia como
"Clase Padre o SuperClase") y el código que es especifico de cada clase, lo dejaremos en ella,
siendo denominadas estas clases como "Clases Hijas", las cuales heredan de la clase padre sus
propiedades y métodos.

Ilustración 170. Clases padre e hijas

Como podéis observar ahora queda un código mucho más limpio, estructurado, con
menos líneas de código, lo que lo hace más legible y reutilizable.

114
José A. Navarro Java desde 0. Programación I

Veamos cómo quedaría el código:

En la primera clase, la padre, podemos ver que no hay nada nuevo simplemente tiene la
sintaxis de una clase normal y corriente. Para facilitar el código y centrarnos en lo que nos ocupa
he imprimido por pantalla desde dentro de las clases pero como ya sabéis esto no debe de
hacerse y es una muy mala praxis que va en contra del encapsulamiento y la reutilización. Lo
usamos sólo a modo de laboratorio.

En esta clase hemos puesto las propiedades y métodos que son comunes a todas. Tanto
un Futbolista como un Entrenador o Masajista deben de poder viajar y concentrarse. De todos
ellos queremos saber su id, nombre, apellidos y edad.

Ilustración 171. Ejemplo clase padre

115
José A. Navarro Java desde 0. Programación I

Ilustración 172. Clase hija 1

En la clase Masajista ya podemos ver cambios:

 Usamos la palabra reservada extends para indicar que hereda de SeleccionFutbol.

 Sólo declara las propiedades y métodos que necesita por ser Masajista, las demás
ya las ha declarado el padre.

 El constructor recibe todas las propiedades que necesita sólo que unas las tiene
Masajista y otras su padre. Para indicar que las que no son del hijo se deben de
enviar al padre se usa la palabra reservada super y entre paréntesis las
propiedades de las que se encarga el padre. Esto ejecuta el constructor del padre
con esas propiedades. Fijaros como coinciden el número de parámetros y tipo con
el constructor del padre. El super debe de ser la primera línea del constructor.

Las demás clases hacen exactamente lo mismo. Envían al padre lo que es del padre y se
quedan con lo que es suyo.

116
José A. Navarro Java desde 0. Programación I

Ilustración 173. Clase hija 2

Ilustración 174. Clase hija 3

Ilustración 175. Ejemplo de main con herencia

117
José A. Navarro Java desde 0. Programación I

En el main podemos ver como se crea un objeto de cada hijo. En la línea 10 imprimimos
el nombre del entrenador, en la 11 llamamos a que un jugador se concentre (dicho método no
está declarado en el jugador sino en su padre), en la línea 12 llamamos a entrenar.

¿Cómo encuentra Java los métodos donde corresponde? ¿Cómo podemos hacer que
actúen de forma distinta?

Cuando en el main se llama a un método Java lo busca en la clase que estamos buscando,
si está lo llama y si no lo busca en el padre, abuelo… hasta llegar a Object si entonces no lo
encuentra es cuando da error.

Ejemplo:

Ilustración 176. Diagrama animales

En este ejemplo podemos ver como tenemos tres tipos de animales que tienen en común
que son animales y por tanto tienen un nombre, una edad y un tiempo de vida. Cuando en el
main cree un Mamifero y llame a tiempoVida() Java no lo encontrará, por lo que buscará en su
padre Animal, lo encuentra y lo ejecuta.

14.1 Sobreescritura
Imaginemos que las aves tienen un tiempo de vida que se calcula de forma distinta al
resto de animales. Podemos sobreescribir el método en animales con su código:

118
José A. Navarro Java desde 0. Programación I

Ilustración 177. Sobreescritura

Hemos añadido un método en Ave. Cuando Java lo llame desde Ave lo encontrará y no
recurrirá al padre.

Para poder sobreescribir un método:

 Tiene que tener el mismo nombre.

 El return debe de ser del mismo tipo.

 Debe de conservar los mismos parámetros.

14.2 Sobrecarga
La sobrecarga es cuando podemos tener más de un método con el mismo nombre,
como vimos en los constructores.

Ilustración 178. Sobrecarga

Dependiendo de si le paso un int como parámetro se ejecutará uno u otro. No tienen por
qué estar en la misma clase:

119
José A. Navarro Java desde 0. Programación I

Ilustración 179. Sobrecarga 2

Reglas:

 Lo métodos sobrecargados deben de cambiar la lista de argumentos


obligatoriamente. No pueden coincidir en número y tipo.

 Se pueden sobrecargar en una misma clase o en subclases.

 Pueden cambiar el tipo de retorno o el modificador de acceso.

14.3 toString
El toString es un método especial que devuelve una representación como String del
objeto. Se suele usar para mostrar sus propiedades o como queremos representarlo como texto.
Lo veremos en más profundidad en el siguiente capítulo.

Pero, ¿Tiene sentido declarar un objeto del padre?

14.4 Clases abstractas


Las clases abstractas son aquellas que por sí mismas no se pueden identificar con algo
“concreto” (no existen como tal en el mundo real), pero sí poseen determinadas características
que son comunes en otras clases que pueden ser creadas a partir de ellas.

Las clases abstractas tienen dos grandes características:

 No se pueden instanciar.

 Pueden contener métodos abstractos. Un método abstracto define la cabecera


de un método y que debe de hacer, pero no como. Toda clase que hereda de una
clase abstracta está obligada a dar solución a esos métodos.

Veamos el ejemplo anterior del equipo de futbol:

120
José A. Navarro Java desde 0. Programación I

¿Tiene sentido crear objetos de la clase SeleccionFutbol? Nuestro programa va a trabajar


con futbolistas, entrenadores y masajistas, por tanto, no tiene sentido crear un objeto del padre.
Para encapsular el código y que el programador que realiza el programa principal no cree un
objeto de ese tipo, bien por error o por desconocimiento, declaramos la clase padre como
abstracta, de esta forma le dará un error de compilación si trata de instanciarla. Para declarar
una clase como abstracta se usa la palabra reservada abstract antes de class.

Por otro lado imaginemos lo siguiente: Todos los hijos deben de declarar un método
nivelCansancio() que dado las horas trabajadas me devuelva un entero que indique su nivel de
cansancio. Las clases abstractas también pueden declarar métodos abstractos, estos métodos
no se solucionan en ella, sino que obligan a los hijos a darle solución. Veamos el ejemplo
descrito:

Ilustración 180. Clase abstracta

Como se puede observar la clase se declara como abstract, sólo por eso ya no podemos
crear objetos de esta clase, no es instanciable. Independientemente de ello una clase abstracta
puede declarar métodos como abstractos. La sintaxis de los métodos abstractos sigue las
siguientes reglas:

 No tiene cuerpo (llaves): sólo consta de signatura con paréntesis. Entre paréntesis
pueden tener parámetros como un método normal.

 Terminan con un punto y coma.

121
José A. Navarro Java desde 0. Programación I

 Sólo puede existir dentro de una clase abstracta. Si una clase incluye un método
abstracto, forzosamente la clase será una clase abstracta.

 Los métodos abstractos forzosamente habrán de estar sobreescritos en las clases


hijas. Si una subclase no implementa un método abstracto de la superclase a la
fuerza tiene que ser abstracta también.

 Las clases que lo solucionan usan la sintaxis normal de los métodos siendo la
cabecera la misma.

Veamos cómo se implementaría la clase futbolista, por ejemplo:

Ilustración 181. Clase abstracta 2

Obviamente todos los métodos que había en este ejemplo siguen estando, no los he puesto por
acortar las imágenes.

Una clase abstracta puede tener métodos no abstractos.

Si un padre es abstracto y hay clases intermedias abstractas y clases


finales que solucionan los métodos abstractos, las intermedias no es
necesario que declaren los métodos abstractos.

14.5 Polimorfismo
En programación orientada a objetos, polimorfismo es la capacidad que tienen los objetos
de una clase en ofrecer respuesta distinta e independiente en función de los parámetros
(diferentes implementaciones) utilizados durante su invocación. Dicho de otro modo, el objeto
como entidad puede contener valores de diferentes tipos durante la ejecución del programa.

Como siempre veamos un ejemplo que se entenderá mejor. Imaginemos que tenemos
productos, por ejemplo trigo y leche. Ambos tienen cosas en común y tienen que solucionar un
método para calcular su precio. En el trigo a ese precio se le suma un tanto por cien, en la leche
dependiendo del tipo una cantidad fija. Veamos el código y luego lo explico.

122
José A. Navarro Java desde 0. Programación I

Ilustración 182. Producto

Ilustración 183. Trigo

Ilustración 184. Leche

123
José A. Navarro Java desde 0. Programación I

Ilustración 185. Test Polimorfismo

 Producto: Las propiedades de esta clase son las comunes a todos los productos.
Tienen un método abstracto para calcular el precio que deben de solucionar sus
hijas. También cuenta con un toString() para devolver una representación como
texto del objeto que se instancie.
 Trigo: Es una clase que hereda de Producto. Añade el tanto por cien que hay que
sumarle al precio. Soluciona el método de calcular el precio y también tiene un
toString. Fijaros como el toString llama al del padre primero para poder mostrar
todos los datos.
 Leche: Hereda de Producto, calcula el precio dependiendo del tipo de leche y
tiene un toString.
 TestPoli: En esta clase se crean dos objetos, uno de trigo y otro de leche pero el
tipo de objeto es el del padre, Producto. Un padre quiere a todos sus hijos por
igual, en una variable de tipo Producto caben productos de tipo Trigo y Leche. Al
revés no se puede hacer pues perderíamos precisión. Dado que ambos tienen el
toString y calcular precio podemos llamarlos.

Ilustración 186. Salida Polimorfismo

Para una única variable no tiene mucha utilidad, pero ¿y si nos piden guardar 50 productos
distintos en un vector? Puedo declarar el vector de tipo Producto e ir guardando productos ya
que todos caben.

Veamos un ejemplo de un vector pero un poco más complicado. Añadimos un método a


cada producto:

124
José A. Navarro Java desde 0. Programación I

Ilustración 187. Trigo 2

He añadido a Trigo un método que me dice si la ganancia es excesiva. Para realizarlo he


usado una forma muy común en programación, supongo una cosa y demuestro si es verdad. En
este caso supongo que es falso y si entra en el if lo cambia.

Ilustración 188. Leche 2

A Leche le he añadido un método que me devuelve el nombre del tipo de leche.

Escribamos el test para devolver el nombre del tipo de leche:

Ilustración 189.Error Polimorfismo

125
José A. Navarro Java desde 0. Programación I

Ilustración 190Error Polimorfismo 2

¿Qué está sucediendo? Pese a que en la variable hay un producto de tipo Leche el tipo de
la variable es Producto y la clase Producto no tiene ningún método tipoLeche.

Esto tiene dos soluciones:

1. Crear el método, aunque sea abstracto en la clase Producto. Esto no es buena


opción ya que si tenemos muchos tipos de productos deberíamos añadir todos
los métodos en el padre cuando solo lo usa un hijo.

2. Usar la palabra reservada instanceof: instanceof me dice si un objeto pertenece a


una clase (se puede hacer de otras formas pero está es la más fácil bajo mi punto
de vista). Una vez sabemos que sí pertenece a una clase hacemos un casting de
los vistos el principio del manual y ya podemos usar el método pues tendremos
un objeto tipo Leche. Veamos un ejemplo:

Ilustración 191. instanceof

14.6 Ejercicios
1. Realiza una clase Minumero que proporcione el doble, triple y cuádruple de un
número proporcionado en su constructor (realiza un método para doble, otro
para triple y otro para cuádruple). Haz que la clase tenga un método main y
comprueba los distintos métodos.

2. Crear una clase que represente una tarjeta de crédito. La clase tendrá el atributo
saldo y tres métodos: pagar, ingresar y verSaldo. Pagar disminuye el saldo en la
cantidad que se le pase, ingresar lo aumenta y verSaldo lo muestra. Si al crear el
objeto no se le pasa nada como parámetro el saldo inicial será 0, sino el pasado
como parámetro. Realizar también una clase que muestre el funcionamiento de
la clase anterior.

126
José A. Navarro Java desde 0. Programación I

3. Crear una clase que implemente una pila de números enteros positivos. El
constructor pedirá el tamaño de la pila. La clase implementara un método put
para añadir un número a la pila, el método get para sacarlo, el método mostrar
para mostrarla y el método size para ver el tamaño actual de la pila. Uusar un
vector para implementar la pila).

4. Crea una clase “punto3d” que extienda la clase Point para trabajar con puntos en
tres dimensiones, implementar el método move, translate y printPoint para
mover el punto, trasladarlo e imprimir las coordenadas en pantalla
respectivamente.(java.awt.Point).

127
José A. Navarro Java desde 0. Programación I

15. Object
En Java cualquier clase que hagamos es una subclase de la clase Object, es como si las
clases se crearan a partir de una “plantilla maestra”. Todos los objetos creados heredan de
Object. De todos los métodos que tiene Object hay dos que son importantes para el fin de este
manual.

 toString(): Devuelve una representación de un objeto como String.

 equals(): Compara dos objetos para ver si son iguales.

Veamos el primero, imaginemos el siguiente código:

15.1 toString()

Ilustración 192. toString

Si quisiéramos imprimir las propiedades de Persona, tendríamos que crear un String


concatenando las llamadas a todos los getters para obtenerlas, para evitar ese trabajo existe el
método toString(), pero ¿qué sucede si uso el método toString en el código anterior? Veámoslo:

Ilustración 193. Ejemplo toString

128
José A. Navarro Java desde 0. Programación I

¿Por qué imprime eso?, muy simple. En el main hemos llamado al toString pero en Pepe
no hay ningún toString por lo que ha ejecutado el por defecto de la clase Object (ya que es su
padre), dado que Object no sabe quién o qué es Pepe nos muestra los datos del Objeto, su
nombre y su código hash. Para que esto no suceda, en nuestras clases debemos de sobreescribir
el método toString() para que muestre los datos como nosotros queramos.

Ilustración 194. toString correcto

En la línea 47 podemos ver el método, ahora Java lo encontrará y ejecutará mostrando


los datos en el formato que prefiramos:

No es buena práctica no llamarle toString() al método que muestra todas


las propiedades, primero por buena praxis y segundo porque puede que
luego hayan métodos de Java que queramos utilizar y no funcionen bien
dado que no encuentran el método.

129
José A. Navarro Java desde 0. Programación I

toString() es el método predefinido para imprimir un objeto con print y


println, por lo que podemos hacer perfectamente lo siguiente y
obtendremos el mismo resultado: System.out.println(pepe).

15.2 equals()
El equals nos va a decir si dos objetos son iguales. Veamos un ejemplo:

Definimos la clase rectángulo de esta forma

Ilustración 195. equals 1

Ilustración 196. equals 2

Veamos la salida de la ejecución

Ilustración 197. Salida equals 2

Tenemos cuatro objetos de tipo Rectangulo (r1, r2, r3 y r4). Como podemos comprobar
del primer if r1 y r2 son distintos, no son el mismo objeto, aunque tengan los mismos valores.
Obviamente el tercer if (22) también son distintos, pues no tienen ni los mismos valores, pero
fijémonos en el segundo (17), los objetos son iguales, de hecho, son el mismo objeto ya que en

130
José A. Navarro Java desde 0. Programación I

la línea 10 hemos hecho r3=r1 y esto no hace una copia del objeto, sino que hace que r3 apunte
a la misma dirección de memoria donde se encuentra r1. Si cambio r3, cambio r1.

Con esto podemos ver que el equals se está comportando como un ==, entonces ¿Cómo
puedo hacer para que compare rectángulos por sus propiedades? Dos rectángulos son iguales
si sus propiedades lo son. Bien, pues aquí entra lo visto con el toString, sobreescribimos el
método equals en la clase Rectangulo añadiendo el siguiente método:

Veamos cómo funciona:

 En la línea 14 aparece una cosa “extraña” que antes no habíamos visto pero que
suele añadirse a todos los métodos sobrescritos. El @Override indica que es un
método sobrescrito que ya existe en una clase superior, esto a parte de ayudarnos
a identificarlos enseguida hace que los IDE puedan generar documentación de
forma automática de nuestro código.

 La siguiente línea tiene la cabecera del método donde se define que va a devolver
un booleano y que recibe un Object. Esto se hace para hacerla lo más general
posible.

 En la línea 16 lo primero que se hace es comprobar si el objeto que le llega por


parámetro es de tipo rectángulo, pues si no lo es no hay nada más que hacer, no
son iguales. Para comprobar si un objeto es del tipo de una clase usamos
instanceof.

 Si el objeto es un rectángulo comprobamos que su altura es la misma que la del


nuestro y que su anchura también, si ambas son iguales el objeto es igual.

De esta forma nosotros decidimos cuando dos objetos son iguales, si por una propiedad,
por varias, …

Si ejecutamos el código anterior obtenemos ahora la siguiente salida:

Podemos comprobar como ahora r1 y r2 sí son iguales, y r4 sigue siendo distinto,


obviamente r3 sigue siendo el mismo objeto que r1.

131
José A. Navarro Java desde 0. Programación I

Reglas que sigue el método equals

 Reflexivo: Para cualquier referencia al valor x, x.equals(x) debe regresar true.

 Simétrico: Para cualquier referencia a los valores x y z, x.equals(z) debe regresar


true sí y solo sí z.equals(x) es true.

 Transitivo: Para cualquier referencia a los valores w, x y z, si w.equals(x) regresa


true y x.equals(z) regresa true, entonces w.equals(z) debe regresar true.

 Consistente: Para cualquier referencia a los valores x y z, múltiples invocaciones


a x.equals(z) consistentemente regresaran true o false, si es que los valores
utilizados para la comparación de los objetos no ha sido modificada.

 Para cualquier referencia no nula del valor x, x.equals(null), debe regresar false.

Asegúrate de sobrescribir el método equals. Las siguientes son implementaciones del


método equals que son válidas para el compilador, pero no válidas para sobrescribir el método:

1. boolean equals(Object o). Esta implementación no sobrescribe el método equals


de la clase Object, ya que el método debe ser declarado como public.

2. public boolean equals(Demo o). Esta implementación no sobrescribe el método


equals de la clase Object, ya que el parámetro que necesita el método equals debe
ser explícitamente un objeto de la clase Object, y no uno que extienda de éste.
Esta implementación, al igual que la anterior es una sobrecarga del método
equals, mas no sobrescribe este método.

La descripción correcta del método equals, es decir, la forma en cómo debe sobrescribirse
es la siguiente (podéis comprobarlo en la API):

public boolean equals(Object o);

Sobrescribiendo el método hashCode

¿Qué implica el hashcode?

Algunas colecciones usan el valor hashcode para ordenar y localizar a los objetos que
están contenidos dentro de ellas. El hashcode es un numero entero, sin signo, que sirve en
colecciones de tipo Hash* para un mejor funcionamiento en cuanto a rendimiento. Este método
debe ser sobrescrito en todas las clases que sobrescriban el método equals, si no se quiere tener
un comportamiento extraño al utilizar las colecciones de tipo Hash* y otras clases. Si dos objetos
son iguales según el método equals sobrescrito, estos deberían regresar el mismo hashcode.

Nosotros no vamos a reescribirlo ya que en los próximos manuales usaremos otros IDE
que los generan automáticamente.

132
José A. Navarro Java desde 0. Programación I

15.3 Asignación de Objetos


Cuando trabajamos con objetos estamos usando referencias, son unos punteros a
direcciones de memoria. Veamos un ejemplo, imaginemos la siguiente clase Persona:

Ilustración 198. Asignación a Objetos

Ahora la instanciamos de la siguiente forma:

Ilustración 199. Asignación a Objetos 2

Antes de ver cuál es la salida, vamos a ver qué ocurre en memoria.

133
José A. Navarro Java desde 0. Programación I

Se crean los tres objetos:

Memoria

pepe Pepe Gil 67


19893476M

eva Eva Lucas 45


78523558F

pedro Pedro Juan 33


13455455F

Cada objeto apunta a su propia dirección de memoria donde se encuentran sus


propiedades.

Al ejecutar la línea 13, pedro=pepe ocurre esto:

Memoria

pepe Pepe Gil 67


19893476M

eva Eva Lucas 45


78523558F

pedro Pedro Juan 33


13455455F

pedro apunta a la misma dirección que pepe, por lo que son lo mismo. Si pepe cambia lo
hace pedro y viceversa. ¿Qué pasa con los datos de pedro?, cuando pasa el garbage collector se
eliminan.

Veamos el resultado de ejecutar el código anterior:

Ilustración 200. Salida Asignación a Objetos

Fijaros como en la línea 13 pedro pasa a ser pepe y sus datos son los mismos. Cuando le
cambio la edad a pedro en la línea 17, también se la cambio a pepe.

134
José A. Navarro Java desde 0. Programación I

15.4 Constructor copia


Visto lo anterior no podemos usar la asignación para crear una copia de un objeto, en vez
de ello podemos construir lo que se llama “constructor copia”, que no es más que un constructor
que recibe como parámetro un objeto de su propia clase y lo inicializa. A la clase Persona le
añadimos el siguiente constructor:

Ilustración 201. Constructor copia

Al constructor le llega p y dado que es de tipo Persona podemos acceder a sus


propiedades directamente. Ahora el programa principal lo cambiamos de esta forma:

Ilustración 202. Main constructor copia

La memoria queda así:


Memoria

pepe Pepe Gil 67


19893476M

eva Eva Lucas 45


78523558F

pedro Pepe Gil 67


19893476M

Como podemos ver pepe y pedro tienen los mismos datos, pero no son lo mismo. Al
cambiar la edad de pedro no cambia la de pepe:

135
José A. Navarro Java desde 0. Programación I

Ilustración 203. Salida constructor copia

15.5 Wrappers
Un wrapper es una clase que representa a un tipo primitivo. A diferencia del uso de tipo
primitivo son objetos por lo que se comportan como tal. Entre las ventajas de su uso se
encuentra la facilidad de conversión entre tipos primitivos (suelen tener métodos static). Entre
las desventajas, usan más memoria y hay que ir con cuidado con el paso de parámetros, siempre
se pasan por referencia. (ver tipos de paso por parámetros). Los wrappers se encuentran en el
paquete java.lang, por lo que no es necesario usar import.

Ilustración 204. wrapper's

Un uso de este tipo de clases podría ser eliminar la limitación de los vectores que dice que
solo pueden ser de un solo tipo. Con esto y el polimorfismo visto anteriormente los vectores
pueden ser Object pero contener cualquier tipo de dato.

136
José A. Navarro Java desde 0. Programación I

16. Interfaces
Una interfaz es una especie de plantilla para la construcción de clases. Normalmente una
interfaz se compone de un conjunto de métodos abstractos no pudiendo tener propiedades
instánciales.

Todos los métodos de una interfaz se declaran implícitamente como abstractos y públicos.

Clases abstractas vs Interfaces:

 Una clase abstracta no puede implementar los métodos declarados como


abstractos, una interfaz no puede implementar ningún método (ya que todos son
abstractos).

 Una clase abstracta puede tener métodos “normales” y métodos abstractos.

 Una interfaz no declara variables de instancia. Puede declarar variables finales.

 Una clase puede implementar varias interfaces, pero sólo puede tener una clase
ascendiente directa.

 Una clase abstracta pertenece a una jerarquía de clases mientras que una interfaz
no pertenece a una jerarquía de clases. En consecuencia, clases sin relación de
herencia pueden implementar la misma interfaz.

16.1 Declaración de una interfaz


La declaración de una interfaz es similar a una clase, aunque emplea la palabra reservada
interface en lugar de class y no incluye ni la declaración de variables de instancia ni la
implementación del cuerpo de los métodos (sólo las cabeceras). La sintaxis de declaración de
una interfaz es la siguiente:
public interface nombre {

// Cuerpo de la interfaz ...

Una interfaz declarada como public debe ser definida en un archivo con el mismo nombre
de la interfaz y con extensión .java. Las cabeceras de los métodos declarados en el cuerpo de la
interfaz se separan entre sí por caracteres de punto y coma y todos son declarados
implícitamente como public y abstract. Por su parte, todas las constantes incluidas en una
interfaz se declaran implícitamente como constantes públicas y es necesario inicializarlas en la
misma sentencia de declaración.

Ilustración 205. interface

137
José A. Navarro Java desde 0. Programación I

16.2 Implementación de una interfaz en una clase


Para declarar una clase que implemente una interfaz es necesario utilizar la palabra
reservada implements en la cabecera de declaración de la clase.

Ilustración 206. implements

16.3 Jerarquía entre interfaces


Se pueden implementar tantas interfaces como se quieran. Si una clase hereda de otra e
implementa interfaces primero se pone la herencia y luego las implementaciones.

Otro ejemplo: pueden construirse dos interfaces: Constantes y Variaciones, y una clase,
Factura, que las implementa:

Ilustración 207. Herencia e implementación

Si una interfaz implementa otra, incluye todas sus constantes y declaraciones de métodos,
aunque puede redefinir tanto constantes como métodos.

Importante: Es peligroso modificar una interfaz ya que las clases


dependientes dejan de funcionar hasta que éstas implementen
los nuevos métodos.

16.4 Interfaces como tipos


A veces creamos métodos que tenemos que estar cambiando por requerimientos del
cliente. Por ejemplo imaginad un método que tenga que imprimir pero luego nos piden que
salga por pantalla y luego que guarde en una BBDD. La solución pasa por usar la interface como
un tipo y crear tantas clases como necesitemos usando una u otra. Veamos un ejemplo:

Ilustración 208. Interfaces como tipos 1

138
José A. Navarro Java desde 0. Programación I

Ilustración 209. Interfaces como tipos 2

Ilustración 210. Interfaces como tipos 3

Ilustración 211. Interfaces como tipos 4

Fijaros como en las líneas 5, 6 y 7 se crean las clases que saben cómo imprimir, mostrar
por pantalla y conectar con la BBDD. Luego se pasan como parámetro al mismo método que las
puede aceptar ya que todas implementan la misma interface.

Ilustración 212. Salida Interfaces como tipos

139
José A. Navarro Java desde 0. Programación I

16.5 Cambios en JDK8


A partir de la versión de Java 8 se introducen algunos cambios que han ido aumentando
poco a poco en siguientes versiones. Los más importantes son:

16.5.1 Default
Si hasta ahora en una interfaz solo podíamos tener constantes y métodos abstractos
ahora tendremos la posibilidad de declarar métodos con un comportamiento por defecto en
una interfaz. Antes de Java 8 podíamos definir que toda clase que implementa a una interfaz
debe de dar cuerpo a los distintos métodos que contenga la interfaz. En cambio, en Java 8, toda
clase que implemente una interfaz debe declarar los distintos métodos que contenga la interfaz
salvo aquellos que estén definidos como métodos por defecto. Estos métodos se caracterizan
porque son métodos que están declarados en la propia interfaz y pueden ser utilizados
directamente en la clase si nos interesa su comportamiento por defecto.

Ilustración 213. Métodos por defecto 1

Ilustración 214. Métodos por defecto 2

Ilustración 215. Métodos por defecto 3

Ilustración 216. Salida Métodos por defecto

140
José A. Navarro Java desde 0. Programación I

Como podemos observar hemos declarado en la interface el método multiplicar como


default, como este método no está sobrescrito en la clase Calculadora ejecuta el código
predefinido en la interface.

Si Calculadora soluciona el método de la interface multiplicar este actuará como se


implemente en calculadora.

Ilustración 217. Métodos por defecto 4

Ilustración 218. Salida Métodos por defecto 4

16.5.2 Interface funcional


Es una interface que tiene un único método. A partir de JDK 8 existe la anotación
@FunctionalInterface.

16.5.3 Expresiones Lambda


Usando las interfaces funcionales podemos crear expresiones lambda.

Una expresión lambda es un método anónimo (su cuerpo no se ha escrito en un método


a parte sino en el mismo momento de su uso).

Sintaxis: (parámetros)->{cuerpo lambda}

 El operador -> separa la declaración de parámetros de la declaración del cuerpo


del método

 Parámetros
o Cuando hay un único parámetro no es necesario usar paréntesis

o Cuando no hay parámetros o hay más de uno es necesario el paréntesis y


separarlos por comas

 Cuerpo lambda

o Si está formado por una única línea no son necesarias las llaves ni el
operador return, si necesita devolver algo.

141
José A. Navarro Java desde 0. Programación I

o Si está formado por más de una línea es obligatorio el uso de llaves y de


la palabra return si va a devolver algo.

Ejemplos

Ej1. Sin necesidad de parámetros

Ilustración 219. Expresiones Lambda 1

Ilustración 220. Expresiones Lambda 2

Ilustración 221. Salida Expresiones Lambda 2

Ej2. Un parámetro

Ilustración 222. Expresiones Lambda 3

Ilustración 223. Expresiones Lambda 4

142
José A. Navarro Java desde 0. Programación I

Ilustración 224. Salida Expresiones Lambda 4

Ej3. Dos parámetros, diferentes operaciones

Ilustración 225. Expresiones Lambda 5

Ilustración 226. Expresiones Lambda 6

Ilustración 227. Salida Expresiones Lambda 6

16.6 ¿Qué es Comparable?


Comparable es un interfaz de java, que está creada o desarrollada dentro del JRE de java,
por lo cual no es necesario importar nada, tan solo implementarla directamente en las clases
con implements Comparable y especificar el tipo de clase (objeto). Es parametrizada o genérica.

16.6.1 ¿Para qué sirve Comparable?


Comparable contiene un método abstracto, compareTo, el cual permite ordenar un
objeto según una propiedad o propiedades especificadas en un orden ascendente o
descendente.

16.6.2 ¿Cómo funciona compareTo?


CompareTo es un método abstracto que retorna un int para todos los casos, n<0 si el
objeto es menor, n>0 si el objeto es mayor, o n=0 si son iguales, dependiendo del objeto

143
José A. Navarro Java desde 0. Programación I

existente que comparemos con el objeto de entrada, que va ser del tipo especificado en la
implementación, lo sobrescribimos para cada caso.

Para implementar comparable la sintaxis es:


implements Comparable<T>
Siendo T la clase a comparar. Normalmente coincide con la clase que lo implementa.

16.6.3 ¿Cómo comparar dos objetos?

if(Obj1.compareTo(Obj2)>0)

La clase Obj1 es la que llama a compareTo. Esa clase sobreescribe el método devolviendo
un número positivo, negativo o 0 (no os compliquéis la vida: 1, -1 o 0).

Si usáis un compareTo de alguna clase de la API veréis que devuelve un número a veces
grande, el número no importa sólo si es positivo, negativo o 0.

¡Ojo, no funciona como equals! Si cambiamos el orden hay que cambiar la condición

Ilustración 228. compareTo

16.6.4 ¿Cómo llamar a compareTo?


Para invocar el método compareTo y lograr su correcto funcionamiento se necesitan dos
objetos a comparar.

144
José A. Navarro Java desde 0. Programación I

Ilustración 229. Prueba compareTo

El compareTo usa toda su potencia cuando se comparan colecciones11.

16.6.5 Ejercicio
 Realizar un programa que cree un vector de 10 manzanas. Las manzanas tienen
un color, variedad y peso. El color puede ser “verde”, “rojo” o “amarillo”. Las
manzanas se introducirán una a una, mezclando colores, pesos y variedades, en
el vector. Una vez creado el vector mostrar las propiedades de cada manzana por
pantalla. Ordenar el vector usando el método de la burbuja y luego volver a
mostrar por pantalla la información. Para ordenar el vector se tendrá en cuenta
que primero van las manzanas verdes de menor a mayor peso, luego las rojas de
menor a mayor peso y al final las amarillas de menor a mayor peso.

Crear las clases necesarias. Pensad donde va el vector.

11
Estructuras con más de un objeto. Vectores.

145
José A. Navarro Java desde 0. Programación I

17. La clase String


Llevamos usando desde el principio el tipo String que sirve para tratar con cadenas de
caracteres. Al principio os comenté que dábamos un salto de fe y nos creíamos que no es un
tipo de dato primitivo pero que, dado que es tan usado, Java lo trata muchas veces como tal.
Bien, ahora podemos entender lo que es, un String no es más que una clase, que se encuentra
en java.lang, por eso no hace falta importarla, y que nos permite crear objetos para trabajar con
texto. Como toda clase tiene unos constructores, pero como hemos visto Java nos permite
declarar un objeto de tipo String sin usar el operador new asignándole un valor.

Veamos un ejemplo de los métodos más usados. Podéis consultarlos todos en la API de
Java.

 Constructores:
o String cadena1=”Hola”;
o String cadena2= new String(“Hola”);
o String cadena3=new String(cadena2);

 int length()

Devuelve la longitud de la cadena


String cadena=”hola”;
System.out.println(cadena.length());

Muestra 4

 String concat(String s)

Concatena dos String. Como el operador +

 String toString()

Devuelve la propia cadena

 String trim()

Devuelve una cadena eliminando los espacios por delante y por detrás
String cadena=” hola como estás “;
System.out.println(cadena.trim());

Mostrará “hola como estás”

 String toLowerCase() y String toUpperCase()


Devuelven la cadena en minúsculas o mayúsculas respectivamente
String cadena=”Hola como estás“;
System.out.println(cadena.toUpperCase());
Mostrará “HOLA COMO ESTÁS”

 String replace(char c, char newc);

146
José A. Navarro Java desde 0. Programación I

Reemplaza cada ocurrencia del carácter c por newc


String cadena=”hola como estás”;
String cadena2=cadena.replace(‘o’,’a’);

En cadena2 hay ”hala cama estás”

 String substring(int i, int f)

Devuelve una subcadena que comienza por el carácter i y termina en el f-1. Si no se


especifica f devuelve hasta el final
String cadena=”Juan Carlos Moreno”;
System.out.println(cadena.substring(5,11));
System.out.println(cadena.substring(12));

La primera devuelve “Carlos” y la segunda “Moreno”

 boolean startsWith(String s) y boolean startsWith(String s)

Devuelven true o false si la cadena comienza por s o termina por s respectivamente.

 char charAt(i)

Devuelve el carácter que se encuentra en la posición i


System.out.println(“hola”.charAt(1));
Muestra ‘o’

 int indexOf(String s)

Devuelve el índice donde se encuentra la primera subcadena de s o -1 si no se encuentra.

 String valueOf(int n)

Convierte un número entero a String

 int compareTo(String s)
Este es un método que se usa en muchos tipos de objetos (ya veremos cómo). Sirve para
comparar dos objetos, en nuestro caso String’s, devuelve:

o Un número <0 si el String llamente es menor que el pasado por parámetro.

o Un número >0 sie el String llamante es mayor que el pasado por parámetro.

o 0 Si son iguales.
Para saber si es mayor o menor el método compara los String carácter a carácter de
izquierda a derecha según el alfabeto. Por ejemplo: la a es menor que la d.
String cadena1=”casa”;
String cadena2=”casi”;
System.out.println(cadena1.compareTo(cadena2));

El llamante es cadena1, son iguales hasta la última ‘a’<’i’---->menor que 0.

147
José A. Navarro Java desde 0. Programación I

 El método compareTo() distingue entre mayúsculas y


minúsculas, las mayúsculas se encuentran antes que las
minúsculas por lo que ‘A’ es menor que ‘a’
 No importa el número en sí que devuelve, solo si es mayor
o menor que 0, salvo si es justamente 0 que significa que
son iguales

 boolean equals(String s)

Como ya hemos visto con anterioridad, este método sirve para comprobar si dos objetos
son iguales, en este caso dos String. En caso de ser iguales el llamante que el parámetro
devuelve true, si no false.
String cadena1=”casa”;
String cadena2=”casi”;
System.out.println(cadena1.equals(cadena2));

Devuelve false.

Los String debemos de compararlos siempre usando el método equals() y no ==.

Scanner sc=new Scanner(System.in);


String cadena1=”casa”;
String cadena2=sc.nextLine();
System.out.print(cadena1.equals(cadena2));
System.out.print(cadena1==cadena2);

Si introducimos por teclado la palabra “casa”, la salida de este código será: true false
Esto es debido a que el operador == está comparando le referencia de los objetos,
no su contenido. Hay una excepción, que no voy a mencionar para no liaros. Como
regla los String SIEMPRE se comparan con equals()

148
José A. Navarro Java desde 0. Programación I

18. La clase Math


La clase Math es una clase para realizar operaciones matemáticas que se encuentra en
java.lang por lo que no hace falta importarla. Esta clase es estática lo que significa que todos sus
métodos son estáticos y no se necesita instanciar, para usar un método simplemente
anteponemos el nombre de la clase. Entre los métodos más importantes que podemos
encontrar están:

double random() Número aleatorio de 0 a 1

tipo abs(tipo x) Devuelve el valor absoluto de x.

double sqrt(double x) Calcula la raíz cuadrada de x

double pow(double x,double y) Calcula x elevado a y

double exp(double x) Calcula ex


Tabla 26. Clase Math

Si miramos la API podemos ver como hay muchos más:

Ilustración 230. Extracto de métodos Math

Como podéis observar todas son static. Además, también se declaran dos constantes: PI y E.

149
José A. Navarro Java desde 0. Programación I

Veamos un ejemplo de uso de Math:

Ilustración 231. Ejemplo Math

Ilustración 232. Salida Math

150
José A. Navarro Java desde 0. Programación I

19. Anexo I. ArrayList


La clase ArrayList, es una clase que implementa la interface List y que permite almacenar
datos en memoria de forma similar a los vectores, con la ventaja de que el número de elementos
que almacena es dinámico (en tiempo de ejecución), es decir, que no es necesario declarar su
tamaño como pasa con los vectores. Además, permite cambiar su tamaño dinámicamente
conforme se insertan o eliminan elementos.
ArrayList se encuentra en el paquete java.util, por tanto hay que importarla para poder usarla.

Si nos fijamos en su definición podemos ver lo siguiente:

La declaración <E> nos indica que es una clase genérica o parametrizada, este tipo de
clases permiten realizar operaciones sea cual sea el tipo que reciban. En este caso la E significa
elemento de una colección.

Las clases genéricas tienes algunas restricciones:

 No se pueden instanciar tipos genéricos con tipos primitivos.


 No se pueden crear instancias de los parámetros de tipo.
 No se pueden declarar campos static cuyos tipos son parámetros de tipo.
 No se pueden usar castings o instanceof con tipos parametrizados.
 No se pueden crear arrays de tipos parametrizados.
 No se pueden crear, capturar o lanzar tipos parametrizados que extiendan de
Throwable.

Veamos el uso de ArrayList a través de distintas aproximaciones

Ilustración 233. Ejemplo ArrayList 1

Como podemos ver, lo primero que debemos de hacer es importarlo.

Para declararlo usamos la siguiente sintaxis:

151
José A. Navarro Java desde 0. Programación I

ArrayList<Tipo> listado = new ArrayList<Tipo>();

Donde tipo es la clase a la cual pertenecen los objetos que se van a guardar. Termina con
() ya que estamos llamando al constructor por defecto.

A partir de la versión 7 del JDK no es necesario declarar el tipo en la parte


de la derecha.
ArrayList<Tipo> listado = new ArrayList<>();

Dado que no es un vector no podemos usar [], debemos de usar el método add para añadir
objetos. Los ArrayList, al igual que los vectores, comienzan por el índice 0.

Podemos ver un resumen de los métodos en el siguiente cuadro:

Tabla 27. Métodos ArrayList

También podemos usar el constructor con el que le damos un tamaño inicial:

ArrayList<Tipo> listado = new ArrayList<Tipo>(int n);

Pero, ¿Por qué usar este constructor si el ArrayList puede crecer dinámicamente? Muy
simple. Cuando se crea un ArrayList sin especificar el tamaño, este se crea de forma
predeterminada para diez elementos, cuando insertamos uno más, internamente, Java lo que

152
José A. Navarro Java desde 0. Programación I

hace es realizar una copia del ArrayList en otro de tamaño once y añadir el siguiente elemento
y así sucesivamente, pero esto tiene un coste. Si desde el principio le indicamos el tamaño que
creemos más acertado para el uso que le vamos a dar, el coste es menor.

Para obtener o cambiar un elemento usamos el método set y get:

Ilustración 234. Ejemplo ArrayList 2

Ilustración 235. Salida Ejemplo ArrayList 2

También podemos insertar elementos en una posición dada sin borrar el que hay en ella
y eliminar el de una posición dada, en ambos casos el ArrayList se redimensiona sin perder la
información.

Ilustración 236. Ejemplo ArrayList 3

Ilustración 237. Salida Ejemplo ArrayList 3

153
José A. Navarro Java desde 0. Programación I

Ejemplo de otros métodos de ArrayList (Ver API):

Ilustración 238. Ejemplo ArrayList 4

Ilustración 239. Salida Ejemplo ArrayList 4

19.1 Estructuras para recorrer colecciones


For Each: El ciclo for-each es una herramienta muy útil cuando tenemos que realizar
recorridos completos de colecciones. Para recorrer un ArrayList de una forma más cómoda
podemos usar el bucle for-each de Java cuya sintaxis es la siguiente:
for (String nombre:listado)

Este for recorre toda la colección (ArrayList), define una variable que va a tomar el valor
de todos los elementos de la colección:

Ilustración 240. Ejemplo for each

154
José A. Navarro Java desde 0. Programación I

Ilustración 241. Salida Ejemplo for each

La variable nombre va tomando todos los valores del ArrayList listado.

Obviamente podemos usar el for de siempre que ya conocemos.

Usando un iterador: En Java, la interface Iterator provee un mecanismo estándar para


acceder secuencialmente a los elementos de una colección, define una interface que declara
métodos para acceder secuencialmente a los objetos de una colección. Una clase accede a una
colección a través de dicha interface.

Se utiliza cuando:

 Una clase necesita acceder al contenido de una colección sin llegar a ser
dependiente de la clase que es utilizada para implementar la colección, es decir
sin tener que exponer su representación interna.

 Una clase necesita un modo uniforme de acceder al contenido de varias


colecciones.

 Cuando se necesita soportar múltiples recorridos de una colección.


public interface Iterator<E>

La clase ArrayList tiene un método iterator() que me devuelve un iterador sobre dicha
clase y que tiene una serie de métodos:

Los tres principales métodos de esta interface son:

 hasNext(): me dice si hay más elementos que recorrer.

 next(): devuelve el siguiente elemento.

 remove(): borrar el elemento de la colección.

155
José A. Navarro Java desde 0. Programación I

Ejemplo de uso:

Ilustración 242. Ejemplo de iterador

Ilustración 243. Salida Ejemplo de iterador

Veamos un ejemplo en el que tenemos una serie de personas que tienen una edad y
queremos mostrar aquellas que están jubiladas:

Ilustración 244. Ejemplo ArraList 5

156
José A. Navarro Java desde 0. Programación I

Ilustración 245. Test Ejemplo ArraList 5

Ilustración 246. Salida Ejemplo ArraList 5

Dado que un ArrayList no permite el uso de tipos primitivos, debemos de usar sus
correspondientes clases o wrappers:

Ilustración 247. wrappers

157
José A. Navarro Java desde 0. Programación I

20. Anexo II. Excepciones


Una excepción es un evento que ocurre durante la ejecución del programa que
interrumpe el flujo normal de las sentencias. Muchas clases de errores pueden generar
excepciones, desde problemas de hardware, como la avería de un disco duro, a los simples
errores de programación, como tratar de acceder a un elemento de un vector fuera de sus
límites.

Como vimos en su momento, se puede generar una excepción si el usuario escribe algo
que no es un numero cuando Java espera un número:

Ilustración 248. Ejemplo de excepción

Las excepciones hay que tratarlas para que el programa no termine bruscamente y pueda
continuar. Java tiene la siguiente jerarquía en cuanto a las clases que tratan las excepciones:

Ilustración 249. Jerarquía de excepciones

Aquellas que están en rojo estamos obligadas a tratarlas o simplemente ni siquiera


compilará. Las azules no estamos obligados a tratarlas. Fijaros como las que nos han salido en
este manual son las azules.

Java nos permite hacer un control de las excepciones para que nuestro programa no se
pare inesperadamente, aunque se produzca una excepción. Para ello tenemos la estructura "try
- catch - finally”:
try{
<instrucciones que hay que controlar>
}catch (typeException e){
<instrucciones a ejecutar cuando se produce la excepción
} finally{
<instrucciones que se ejecutan tanto si hay excepción como si no>
}

Un try puede tener más de un catch para hacer una cosa u otra dependiendo del tipo de
excepción. La cláusula finally es optativa.

158
José A. Navarro Java desde 0. Programación I

Cuando en Java se produce una excepción se crea un objeto de una determina clase
(dependiendo del tipo de error que se haya producido), que mantendrá la información sobre el
error producido y nos proporcionará los métodos necesarios para obtener dicha información.

Veamos un ejemplo:

Ilustración 250. Excepciones 1

Ilustración 251. Salida Excepciones 1

Cuando lo compilamos no da ningún error pero al ejecutarlo salta una excepción,


concretamente la ArithmeticException ya que no se puede dividir por 0.

La forma de capturar esta excepción sería:

Ilustración 252. Excepciones 2

Ilustración 253. Salida excepciones 2

Podemos usar los métodos del objeto de la excepción para obtener información:

159
José A. Navarro Java desde 0. Programación I

Ilustración 254. Excepciones 3

Capturar una excepción es más costoso que evitarla. En este ejemplo, al igual que en
todos los de este manual, las excepciones se pueden evitar. Basta comprobar la y con un if antes
de hacer la división. Obviamente hay muchas veces que son inevitables, pero aquellas que son
fácilmente evitables hagámoslo. Hay gente que programa “orientado a excepciones”, en todo
usa excepciones, personalmente no me parece la mejor forma.

Obviamente del tema de excepciones me dejo muchas cosas (que Java las ignore,
personalización de excepciones, …), eso lo dejo para futuros manuales de mayor dificultad.

160
José A. Navarro Java desde 0. Programación I

21. Anexo III. Algebra de Boole


El álgebra de Boole son una serie tiene una serie de propiedades que nos pueden ser útiles
conocer para cambiar el formato de condiciones.

Si definimos las siguientes operaciones: el . como multiplicación equivalente a un AND


(&&), el + como suma equivalente a un OR (||) y ‘ equivalente a NOT (!), junto con el conjunto
de elementos B={0,1} podemos decir que forman un algebra de Boole si se cumple que:

1. Propiedad conmutativa: A + B = B + A y A · B = B · A

2. Propiedad distributiva: A·(B+C) = A·B + A·C y A + B·C = (A+B)·(A+C)

3. Elementos neutros diferentes: A + 0 = A y A · 1 = A

4. Siempre existe el complemento de a, denominado a’: A + A’ = 1 y A · A’ = 0

Las condiciones vistas en el if, while y do cumplen estas propiedades, por tanto podemos
afirmar los siguientes teoremas:

 Teorema 1: el elemento complemento A’ es único. Dado una variable booleana a


sólo existe un !a.

 Teorema 2 (elementos nulos): para cada elemento de B se verifica:

o A+1 = 1--->una variable booleana a || 1 siempre da 1

o A·0 = 0--->una variable booleana a && 0 siempre da 0

 Teorema 3: cada elemento identidad es el complemento del otro:


o 0’=1--->dada una variable booleana a=false !a siempre da true.

o 1’=0--->dada una variable booleana a=true !a siempre da false.

 Teorema 5 (involución): para cada elemento de B, se verifica:

o (A’)’ = A--->dada una variable booleana a !(!a)=a.

 Teorema 6 (absorción): para cada par de elementos de B, se verifica:

o A+A·B=A--->dadas dos variables booleanas A y B ->A||A&&B=A

o A·(A+B)=A--->dadas dos variables booleana A y B ->A&&(A||B)=A

 Teorema 7: para cada par de elementos de B, se verifica:

o A + A’·B = A + B --->dadas dos variables booleanas A y B ->

A||!A&&B = A||B

o A · (A’ + B) = A · B --->dadas dos variables booleanas A y B ->

A&&(!A||B)=A&&B

161
José A. Navarro Java desde 0. Programación I

 Teorema 8 (asociatividad): cada uno de los operadores binarios (+) y (·) cumple la
propiedad asociativa:

o A+(B+C) = (A+B)+C --->dadas dos variables booleanas A y B ->


A||(B||C)=(A||B)||C

o A·(B·C) = (A·B)·C --->dadas dos variables booleanas A y B ->


A&&(B&&C)=(A&&B)&&C

Y quizá lo más importante para nosotros, porque nos permiten transformar condiciones
en otras sin variar el resultado: las leyes de Demorgan:

 para cada par de elementos de B, se verifica:

o (A+B)’ = A’·B’ --->dadas dos variables booleanas A y B ->


!(A||B)=!A&&!B
o (A·B)’ = A’ + B’ --->dadas dos variables booleanas A y B ->
!(A&&B)=!A||!B

162
José A. Navarro Java desde 0. Programación I

22. Bibliografía

(Moreno, Juan Carlos 2006): Programación.

(Ceballos, Fco. Javier 2006); Java 2. Lenguaje y Aplicaciones

(Ceballos, Fco. Javier 2010): Java 2. Curso de programación

(Moya, Ricardo 2013): https://jarroba.com/

(Oracle API Java 8): https://docs.oracle.com/javase/8/docs/api/

https://www.discoduroderoer.es
http://puntocomnoesunlenguaje.blogspot.com

https://ingenieriadesoftware.es/

163
José A. Navarro Java desde 0. Programación I

23. Ejercicios
 Considera el sistema que gestiona los préstamos y devoluciones de libros de una
biblioteca. Cuando un usuario quiere tomar prestado un libro y no existe ningún
ejemplar disponible en ese momento, el sistema permite realizar una reserva de ese
libro. A medida que los libros solicitados vuelvan a estar disponibles, el sistema irá
atendiendo las reservas según el orden en que se realizaron. (Solo hay que hacer el
módulo de reservas)

Para ello, el sistema dispone de la clase Reserva, en la que se definen los siguientes
atributos y métodos:

Atributos:
private Usuario usr, que almacena el usuario que realiza la reserva.

private int idLibro, que almacena un identificador numérico del libro reservado.

Métodos:
public Reserva(Usuario usr, int unIdLibro),Realiza la reserva de un libro para un usuario

public Usuario getUsr(), devuelve el usuario.

public int getIdLibro(), devuelve el atributo idLibro.

public boolean equals(Object obj), compara objetos de la clase.

La clase Usuario es la siguiente. Hay que terminarla. Los usuarios se tienen que poder
ordenar por edad. (No hay que implementar setter’s ni getter’s)

public class Usuario {

private String dni; //se da por supuesto que es único para cada usuario
private String nombre;
private int edad;

Usuario(String dni, String nombre, int edad){


this.dni=dni;
this.nombre=nombre;
this.edad=edad;
}

public String toString(){


return "DNI:"+dni+",Nombre: "+nombre+", Edad: "+edad;
}

...

Queremos implementar una clase ReservasBiblioteca para gestionar las reservas de libros
en la biblioteca. De momento, disponemos de la siguiente definición parcial:

public class ReservasBiblioteca {

private Reserva[] vectorReservas; // Almacena los datos de las reservas

164
José A. Navarro Java desde 0. Programación I

private int ocupados; // Indica las posiciones realmente ocupadas en el vector

public ReservasBiblioteca() {

ocupados = 0; // Inicialmente no hay reservas

vectorReservas = new Reserva[10]; // Crea un vector con capacidad

// para 10 reservas

Como puedes ver, la representación interna de la clase ReservasBiblioteca contiene


como atributos un vector de reservas (vectorReservas) y un valor entero (ocupados) que indica
la cantidad de reservas en la biblioteca. De esta manera, se distingue entre la longitud (o
capacidad máxima) del vector y la cantidad de reservas que realmente contiene.

ReservasBiblioteca debe de implementar la interface Ireservas que contiene los siguientes


métodos:

boolean anyadir(Usuario usr, int idLibro)

Si ya existe una reserva igual en la biblioteca, devuelve como resultado false. Si


no, el método añade una nueva reserva y devuelve como resultado true.

Para añadir la reserva, primero debes comprobar si el vector está lleno, en cuyo
caso debes duplicar su longitud. Después, debes añadir la reserva en la primera posición libre
del vector.
String servirLibro(int idLibro)

Elimina la primera reserva correspondiente al identificador de libro dado y devuelve el los


datos de la persona que había realizado esa reserva. Si no hay ninguna reserva para ese
identificador, el método debe devolver null.

Para eliminar una reserva del vector, todas las reservas posteriores a la misma deben
desplazarse una posición a la izquierda en el mismo vector, de modo que se respete su orden de
llegada.
String usuarioMasReservas()

Devuelve el usuario que tiene más reservas pendientes en la biblioteca. En caso de


empate entre varios usuarios, puedes devolver cualquiera de ellos. Si no existe ninguna
reserva en la biblioteca, el método debe devolver como resultado null.

int anularReservas(Usuario usr)

Elimina todas las reservas que existan para el usuario dado y devuelve la cantidad de
reservas anuladas. Si no hay ninguna reserva para ese usuario, el método debe devolver
cero. Al igual que en el método servirLibro, los desplazamientos necesarios se realizarán

165
José A. Navarro Java desde 0. Programación I

sobre el propio vector (es decir, sin crear vectores auxiliares de reservas).Ejemplo:

https://www.discoduroderoer.es/ejercicios-propuestos-y-resueltos-basicos-java/

http://puntocomnoesunlenguaje.blogspot.com/p/ejercicios.html

166

También podría gustarte