1 00:00:00,000 --> 00:00:01,100 Bueno, pues, venga. 2 00:00:04,799 --> 00:00:07,719 Venga, pues, ya habíamos refactorizado nuestro método 3 00:00:07,719 --> 00:00:10,519 este getVoto estupendo, ¿vale? 4 00:00:11,500 --> 00:00:18,300 Entonces, ahora ya, ahora hemos decidido diseñar nuestro 5 00:00:18,300 --> 00:00:19,199 código, ahora sí. 6 00:00:20,620 --> 00:00:25,519 Ahora, nuestro código llama a un método getVoto y ese método 7 00:00:25,519 --> 00:00:28,940 getVoto está encerrando demasiada complejidad. 8 00:00:28,940 --> 00:00:45,280 Ahí, la idea es que los métodos sean lo más atómicos posibles, ¿vale? Entonces, este método está ahí metiendo validación, a ver, que yo esto también lo estoy diciendo, pues porque me facilita el hilo de la explicación, pero en general tiene sentido. 9 00:00:45,280 --> 00:00:47,119 bueno, pues este método está haciendo 10 00:00:47,119 --> 00:00:48,380 una validación, validación 11 00:00:48,380 --> 00:00:50,600 y cuando yo llame a ese método 12 00:00:50,600 --> 00:00:51,899 cuando llame a ese método 13 00:00:51,899 --> 00:00:55,340 llamo y confío 14 00:00:55,340 --> 00:00:57,439 en que el usuario 15 00:00:57,439 --> 00:00:59,240 que va a votar vote un candidato válido 16 00:00:59,240 --> 00:01:01,340 porque como no vote un candidato 17 00:01:01,340 --> 00:01:03,200 válido, me voy a estar esperando 18 00:01:03,200 --> 00:01:05,099 años y años, porque aquí voy a tener 19 00:01:05,099 --> 00:01:06,060 un bucle infinito 20 00:01:06,060 --> 00:01:08,859 bueno, es una posibilidad de diseño 21 00:01:08,859 --> 00:01:10,900 mi código llama a este voto 22 00:01:10,900 --> 00:01:13,200 y ahí se queda horas y horas 23 00:01:13,200 --> 00:01:14,840 y horas, esperando que 24 00:01:14,840 --> 00:01:17,040 el votante emita un voto válido. 25 00:01:18,939 --> 00:01:20,680 Pero podríamos hacer otra filosofía, 26 00:01:20,799 --> 00:01:22,719 que es, no, no. Yo te doy la opción 27 00:01:22,719 --> 00:01:24,900 de votar y no me estoy ahí esperando 28 00:01:24,900 --> 00:01:26,760 delante de la urna años 29 00:01:26,760 --> 00:01:28,819 si hace falta hasta que tú decidas escribir 30 00:01:28,819 --> 00:01:30,159 en la papeleta lo que toca. 31 00:01:30,659 --> 00:01:31,379 Eso no lo voy a hacer. 32 00:01:32,280 --> 00:01:33,980 Yo te voy a 33 00:01:33,980 --> 00:01:35,879 pedir que votes 34 00:01:35,879 --> 00:01:38,480 y si votas bien, 35 00:01:38,620 --> 00:01:40,519 magnífico, pero y si votas mal, 36 00:01:40,519 --> 00:01:42,719 yo aviso, este ha votado mal y se acabó. 37 00:01:43,120 --> 00:01:44,680 Nada de estarme aquí esperando años 38 00:01:44,680 --> 00:01:46,480 y años y años a que tú votes bien 39 00:01:46,480 --> 00:01:48,260 no, tú vota 40 00:01:48,260 --> 00:01:50,620 que tu voto no es válido, el voto de este tío 41 00:01:50,620 --> 00:01:51,980 no es válido, tú verás qué haces con él 42 00:01:51,980 --> 00:01:54,780 si lo llevas a la cárcel o le das otra oportunidad 43 00:01:54,780 --> 00:01:55,980 lo que tú quieras 44 00:01:55,980 --> 00:01:58,560 esa es una mejor filosofía de diseño 45 00:01:58,560 --> 00:01:59,900 ¿vale? 46 00:02:00,239 --> 00:02:02,739 los métodos, las cosas más atómicas posibles 47 00:02:02,739 --> 00:02:04,540 y que las decisiones 48 00:02:04,540 --> 00:02:05,540 estratégicas 49 00:02:05,540 --> 00:02:08,860 como te dejo votar otra vez o te llevo a la cárcel 50 00:02:08,860 --> 00:02:09,939 las decisiones estratégicas 51 00:02:09,939 --> 00:02:11,319 se deleguen para arriba 52 00:02:11,319 --> 00:02:14,740 sería en principio 53 00:02:14,740 --> 00:02:15,800 mejor diseño 54 00:02:15,800 --> 00:02:17,319 vale, pues entonces 55 00:02:17,319 --> 00:02:20,379 eso que implicaría aquí, en esta versión B 56 00:02:20,379 --> 00:02:22,360 de votaciones, este bucle 57 00:02:22,360 --> 00:02:22,879 lo quito 58 00:02:22,879 --> 00:02:26,800 y leo el voto sin más 59 00:02:26,800 --> 00:02:28,719 si el voto 60 00:02:28,719 --> 00:02:30,419 es válido, genial, lo devuelvo 61 00:02:30,419 --> 00:02:32,340 y si no es válido 62 00:02:32,340 --> 00:02:34,659 aviso de que no ha sido válido 63 00:02:34,659 --> 00:02:36,840 vale, eso sería 64 00:02:36,840 --> 00:02:38,620 lo ideal, y ya el de arriba 65 00:02:38,620 --> 00:02:40,800 que decida que hace con ese voto no válido 66 00:02:40,800 --> 00:02:43,099 si le da otra oportunidad o no le da ninguna 67 00:02:43,099 --> 00:02:44,699 bueno, pues ese 68 00:02:44,699 --> 00:02:47,180 aviso de que el voto no ha sido 69 00:02:47,180 --> 00:02:49,039 válido, tiene que ser 70 00:02:49,039 --> 00:02:50,860 mediante una excepción, porque esa es la forma 71 00:02:50,860 --> 00:02:53,139 en la que los métodos avisan 72 00:02:53,139 --> 00:02:55,060 al de arriba de que algo raro 73 00:02:55,060 --> 00:02:56,740 ha pasado, ¿vale? 74 00:02:57,560 --> 00:02:58,900 hasta ahora esos avisos 75 00:02:58,900 --> 00:03:01,120 si hemos querido hacerlos, los hemos hecho 76 00:03:01,120 --> 00:03:02,840 usando el valor de retorno 77 00:03:02,840 --> 00:03:05,000 es decir, yo puedo 78 00:03:05,000 --> 00:03:06,659 hacer un método que me devuelva boolean 79 00:03:06,659 --> 00:03:08,680 si el boolean es falso 80 00:03:08,680 --> 00:03:11,219 ese método no funcionó 81 00:03:11,219 --> 00:03:13,180 no es válido, algo raro pasó 82 00:03:13,180 --> 00:03:15,080 y si el valor de retorno 83 00:03:15,080 --> 00:03:17,280 es true, ese método funcionó correctamente 84 00:03:17,280 --> 00:03:19,000 pero en este caso no podemos usar 85 00:03:19,000 --> 00:03:20,919 el valor de retorno, porque ya está 86 00:03:20,919 --> 00:03:23,060 usado para el voto, ya está usado 87 00:03:23,060 --> 00:03:24,259 para el nombre del candidato 88 00:03:24,259 --> 00:03:26,979 luego no puedo usar un boolean de retorno 89 00:03:26,979 --> 00:03:28,939 para avisar si las cosas han ido bien o mal 90 00:03:28,939 --> 00:03:29,439 no puedo 91 00:03:29,439 --> 00:03:32,900 aún así, tendríamos 92 00:03:32,900 --> 00:03:35,000 otra forma de avisar al de arriba que algo 93 00:03:35,000 --> 00:03:35,800 ha ido mal o no 94 00:03:35,800 --> 00:03:37,979 sin necesidad de 95 00:03:37,979 --> 00:03:39,259 mandarle una excepción 96 00:03:39,259 --> 00:03:42,099 en esta misma firma de aquí 97 00:03:42,099 --> 00:03:42,800 con un string 98 00:03:42,800 --> 00:03:49,289 la tendríamos 99 00:03:49,289 --> 00:03:51,349 devolviendo null 100 00:03:51,349 --> 00:03:57,270 espera, espera, espera 101 00:03:57,270 --> 00:03:58,289 espera, espera, sí 102 00:03:58,289 --> 00:04:00,729 sí, sí 103 00:04:00,729 --> 00:04:03,430 la respuesta sí, pero por partes 104 00:04:03,430 --> 00:04:05,210 vale, entonces tendríamos otra 105 00:04:05,210 --> 00:04:06,610 forma de avisar al de arriba 106 00:04:06,610 --> 00:04:08,330 de que este método ha ido mal 107 00:04:08,330 --> 00:04:10,210 es decir, vamos a quitarle la validad 108 00:04:10,210 --> 00:04:11,189 el bucle, repito 109 00:04:11,189 --> 00:04:12,949 vamos a quitarle el bucle 110 00:04:12,949 --> 00:04:14,830 y esto se nos queda así 111 00:04:14,830 --> 00:04:26,279 entonces, si 112 00:04:26,279 --> 00:04:28,759 el voto emitido 113 00:04:28,759 --> 00:04:32,730 está contenido en los candidatos 114 00:04:32,730 --> 00:04:34,490 pues entonces, magnífico 115 00:04:34,490 --> 00:04:35,230 retúmboto 116 00:04:35,230 --> 00:04:38,149 y si no, si no está contenido 117 00:04:38,149 --> 00:04:39,129 en los candidatos 118 00:04:39,129 --> 00:04:42,610 yo aún así tengo una manera de avisar 119 00:04:42,610 --> 00:04:45,930 de que algo ha ido mal 120 00:04:45,930 --> 00:04:47,810 podría devolver null 121 00:04:47,810 --> 00:04:49,269 y ahora aquí, por supuesto 122 00:04:49,269 --> 00:04:50,750 Primero 123 00:04:50,750 --> 00:04:53,930 Asegurarme de comentarlo bien 124 00:04:53,930 --> 00:04:57,310 Porque si no lo comento bien 125 00:04:57,310 --> 00:04:59,810 Pues ese null 126 00:04:59,810 --> 00:05:01,089 No significa nada 127 00:05:01,089 --> 00:05:02,250 ¿Qué significa null? 128 00:05:03,069 --> 00:05:05,009 Entonces tendría sentido 129 00:05:05,009 --> 00:05:09,069 El nombre del 130 00:05:09,069 --> 00:05:11,310 Candidato 131 00:05:11,310 --> 00:05:13,689 Candidato votado 132 00:05:13,689 --> 00:05:15,370 Y ahora pondría aquí 133 00:05:15,370 --> 00:05:18,189 Devuelve null 134 00:05:18,189 --> 00:05:21,370 si el voto no es 135 00:05:21,370 --> 00:05:22,149 válido 136 00:05:22,149 --> 00:05:25,569 vale, esta podría ser una opción 137 00:05:25,569 --> 00:05:27,329 yo con esto 138 00:05:27,329 --> 00:05:29,670 emito el voto 139 00:05:29,670 --> 00:05:31,430 si el voto es válido 140 00:05:31,430 --> 00:05:33,310 lo devuelvo, si no aviso 141 00:05:33,310 --> 00:05:35,430 con null, con lo cual ya he delegado arriba 142 00:05:35,430 --> 00:05:37,129 pero claro, el de arriba 143 00:05:37,129 --> 00:05:39,350 no ve el código de este método, tiene que saber 144 00:05:39,350 --> 00:05:40,350 qué significa el null 145 00:05:40,350 --> 00:05:43,490 eso para empezar, con lo cual buena idea comentarlo 146 00:05:43,490 --> 00:05:45,350 entonces el que usa 147 00:05:45,350 --> 00:05:45,889 el método 148 00:05:45,889 --> 00:05:48,769 menos mal que yo lo he comentado 149 00:05:48,769 --> 00:05:50,569 con javadoc, porque el que usa 150 00:05:50,569 --> 00:05:52,250 el método, dice 151 00:05:52,250 --> 00:05:54,769 ah, espérate, si me da null 152 00:05:54,769 --> 00:05:56,490 es porque no es válido 153 00:05:56,490 --> 00:05:58,470 cuidado, me puede dar null, no es válido 154 00:05:58,470 --> 00:05:59,569 entonces yo ahora ya decido 155 00:05:59,569 --> 00:06:02,569 si me meto en un bucle, mientras esto sea diferente 156 00:06:02,569 --> 00:06:04,310 de null, o si le digo 157 00:06:04,310 --> 00:06:06,329 voto no válido 158 00:06:06,329 --> 00:06:08,149 yo ya puedo decidir, pero hombre 159 00:06:08,149 --> 00:06:10,329 que me lo documente bien, porque un null en sí 160 00:06:10,329 --> 00:06:12,589 no significa nada, que me lo documente 161 00:06:12,589 --> 00:06:14,250 bien, ¿vale? y aquí me aparece 162 00:06:14,250 --> 00:06:15,949 lo que yo he puesto en el javadoc 163 00:06:15,949 --> 00:06:17,290 entonces vale, estupendo 164 00:06:17,290 --> 00:06:20,029 en este entorno y en cualquier otro 165 00:06:20,029 --> 00:06:20,910 porque están 166 00:06:20,910 --> 00:06:23,990 ligados al javadoc 167 00:06:23,990 --> 00:06:26,089 ¿vale? recordad que 168 00:06:26,089 --> 00:06:27,449 javadoc son los comentarios 169 00:06:27,449 --> 00:06:29,970 que empiezan así 170 00:06:29,970 --> 00:06:32,250 con dos asteriscos 171 00:06:32,829 --> 00:06:34,209 y todo lo que 172 00:06:34,209 --> 00:06:35,949 pongamos aquí, todo 173 00:06:35,949 --> 00:06:38,769 se integra 174 00:06:38,769 --> 00:06:39,370 en la ayuda 175 00:06:39,370 --> 00:06:42,189 de los métodos 176 00:06:42,189 --> 00:06:43,870 y esa ayuda 177 00:06:43,870 --> 00:06:45,910 donde aparece, aparece luego 178 00:06:45,910 --> 00:06:47,029 cuando lo escribimos 179 00:06:47,029 --> 00:06:49,870 aparece en la herramienta de ayuda 180 00:06:49,870 --> 00:06:51,269 del entorno de desarrollo que sea 181 00:06:51,269 --> 00:06:53,230 así muy en resumen 182 00:06:53,230 --> 00:06:55,490 bueno, pues esta podría ser una opción 183 00:06:55,490 --> 00:06:58,129 pero bueno, a ver 184 00:06:58,129 --> 00:07:00,009 los null tienen muy mala 185 00:07:00,009 --> 00:07:01,970 prensa, y es normal que tengan 186 00:07:01,970 --> 00:07:04,189 mala prensa, ¿no? los null tienen mala prensa 187 00:07:04,189 --> 00:07:05,910 ¿por qué? porque nos generan 188 00:07:05,910 --> 00:07:07,350 los null pointer exception 189 00:07:07,350 --> 00:07:09,910 ¿vale? tienen muy mala prensa 190 00:07:10,750 --> 00:07:11,870 entonces, si yo uso 191 00:07:11,870 --> 00:07:12,529 eso 192 00:07:12,529 --> 00:07:19,629 aquí 193 00:07:19,629 --> 00:07:24,790 voto puede ser null 194 00:07:24,790 --> 00:07:27,170 tranquilamente puede ser null 195 00:07:27,170 --> 00:07:28,110 y mi programa sigue 196 00:07:28,110 --> 00:07:30,329 y no pasa nada, voto puede ser null 197 00:07:30,329 --> 00:07:32,110 y mi programa va a seguir 198 00:07:32,110 --> 00:07:34,430 y en algún momento ese null puede petar 199 00:07:34,430 --> 00:07:36,110 aquí en particular 200 00:07:36,110 --> 00:07:39,189 voto no llama nada, con lo cual un null pointer exception 201 00:07:39,189 --> 00:07:39,829 no va a salir 202 00:07:39,829 --> 00:07:42,610 pero hay un contents key 203 00:07:42,610 --> 00:07:45,009 de voto, entonces el contents key 204 00:07:45,009 --> 00:07:47,529 cuando es null no sé qué hará 205 00:07:47,529 --> 00:07:48,170 pero vamos 206 00:07:48,170 --> 00:07:52,439 igual te da una 207 00:07:52,439 --> 00:07:54,519 excepción de que no le puedes pasar un null 208 00:07:54,519 --> 00:07:55,279 al contents key 209 00:07:55,279 --> 00:07:58,240 en resumen, es muy mala idea 210 00:07:58,240 --> 00:08:00,459 trabajar lógicamente 211 00:08:00,459 --> 00:08:02,660 con variables objeto que tengan un null dentro 212 00:08:02,660 --> 00:08:04,620 porque en cuanto yo 213 00:08:04,620 --> 00:08:06,560 llame algo dentro de ellas con el punto 214 00:08:06,560 --> 00:08:07,920 me va a salir null pointer exception 215 00:08:07,920 --> 00:08:10,779 se para el programa porque uno no se está capturando 216 00:08:10,779 --> 00:08:11,819 los null pointers de todo el rato 217 00:08:11,819 --> 00:08:14,680 ¿vale? entonces esta forma 218 00:08:14,680 --> 00:08:16,680 de avisar, pues bueno, tiene 219 00:08:16,680 --> 00:08:18,839 ese peligro, que estamos devolviendo un null 220 00:08:18,839 --> 00:08:20,779 y si el que la usa 221 00:08:20,779 --> 00:08:22,660 aquí no lo tiene en cuenta 222 00:08:22,660 --> 00:08:24,699 para si es, para meterlo 223 00:08:24,699 --> 00:08:26,319 en un bucle mientras sea diferente de null 224 00:08:26,319 --> 00:08:28,579 o si es null, pon voto 225 00:08:28,579 --> 00:08:30,720 a lo que sea, sin él no lo 226 00:08:30,720 --> 00:08:32,580 tiene en cuenta, tiene su peligro 227 00:08:32,580 --> 00:08:33,179 ¿vale? 228 00:08:34,440 --> 00:08:36,620 Bueno, pues opción B, otra 229 00:08:36,620 --> 00:08:38,600 forma de avisar, otra forma de 230 00:08:38,600 --> 00:08:41,080 avisar mucho más segura y menos peligrosa 231 00:08:41,080 --> 00:08:42,659 vamos a hacernos el 232 00:08:42,659 --> 00:08:44,539 getVoto versión 2 233 00:08:44,539 --> 00:08:47,259 el bueno y el bonito 234 00:08:47,259 --> 00:08:52,379 getVoto 235 00:08:52,379 --> 00:08:53,879 versión 2, vale 236 00:08:53,879 --> 00:08:55,299 aquí 237 00:08:55,299 --> 00:08:57,419 cuando 238 00:08:57,419 --> 00:09:00,019 resulta que el voto no es válido 239 00:09:00,019 --> 00:09:02,120 en el else del candidatos 240 00:09:02,120 --> 00:09:03,820 containsVoto, en el else 241 00:09:03,820 --> 00:09:06,039 yo aquí nada de devolver null 242 00:09:06,039 --> 00:09:08,259 nada de devolver null, lo que hago 243 00:09:08,259 --> 00:09:09,700 es, pum 244 00:09:09,700 --> 00:09:11,960 construir un objeto de excepción 245 00:09:11,960 --> 00:09:14,379 y mandarlo para arriba, y se acabó 246 00:09:14,379 --> 00:09:16,019 y se detiene la ejecución del método 247 00:09:16,019 --> 00:09:18,000 aunque hubiera cosas aquí debajo 248 00:09:18,000 --> 00:09:19,340 Eso ya ni se hace 249 00:09:19,340 --> 00:09:21,879 ¿Vale? Entonces, ¿qué es lo que queremos hacer aquí? 250 00:09:22,539 --> 00:09:23,360 Aquí queremos 251 00:09:23,360 --> 00:09:25,419 Lanzar una excepción 252 00:09:25,419 --> 00:09:29,940 ¿Y cómo se lanza una excepción? 253 00:09:30,779 --> 00:09:31,840 Pues una excepción 254 00:09:31,840 --> 00:09:33,639 Se lanza poniendo throw 255 00:09:33,639 --> 00:09:34,559 Como la de esperar 256 00:09:34,559 --> 00:09:37,720 Y aquí el objeto 257 00:09:37,720 --> 00:09:39,620 Instanciamos el objeto excepción 258 00:09:39,620 --> 00:09:40,639 Que queremos lanzar 259 00:09:40,639 --> 00:09:42,580 ¿Cómo se instancia un objeto? Con new 260 00:09:42,580 --> 00:09:45,440 ¿Qué tipo de excepción lanzamos? 261 00:09:46,580 --> 00:09:46,879 Pues 262 00:09:46,879 --> 00:09:49,580 Si nos ponemos a buscar entre las 300-500 263 00:09:49,580 --> 00:09:51,960 clases excepción, no hay ninguna 264 00:09:51,960 --> 00:09:53,399 que sea boton o válido. 265 00:09:53,740 --> 00:09:54,059 Exception. 266 00:09:55,419 --> 00:09:57,759 Con lo cual, ¿qué podemos hacer? 267 00:09:58,139 --> 00:10:00,039 Crearnos nuestra propia excepción. 268 00:10:00,960 --> 00:10:01,679 ¿Vale? Crearnos 269 00:10:01,679 --> 00:10:02,820 nuestra propia excepción. 270 00:10:03,720 --> 00:10:05,659 A ver, podríamos lanzar otra, la que nos 271 00:10:05,659 --> 00:10:06,240 diera la gana. 272 00:10:07,360 --> 00:10:14,690 Yo podría lanzar esta, pero... 273 00:10:14,690 --> 00:10:16,549 ¿Vale? Podría lanzar esta excepción. 274 00:10:17,210 --> 00:10:18,629 Pero qué tontería lanzar 275 00:10:18,629 --> 00:10:20,710 una excepción io, que no me explica 276 00:10:20,710 --> 00:10:22,529 nada, cuando lo que yo quiero es 277 00:10:22,529 --> 00:10:24,669 avisar, porque la excepción es avisar 278 00:10:24,669 --> 00:10:26,590 de que el votante ha emitido 279 00:10:26,590 --> 00:10:28,450 un voto no válido, entonces voy a 280 00:10:28,450 --> 00:10:30,370 crearme yo mi propia excepción 281 00:10:30,370 --> 00:10:32,370 voy a crearme mi propia excepción 282 00:10:32,370 --> 00:10:34,450 para ponerla aquí 283 00:10:34,450 --> 00:10:38,059 venga, pues vamos a 284 00:10:38,059 --> 00:10:39,519 crearnos una clase excepción 285 00:10:39,519 --> 00:10:41,720 vale, pues 286 00:10:41,720 --> 00:10:43,580 aquí estamos en el ejercicio 8 287 00:10:43,580 --> 00:10:45,480 pues venga 288 00:10:45,480 --> 00:10:48,100 nuestra clase se va a llamar 289 00:10:48,100 --> 00:10:50,200 voto no 290 00:10:50,200 --> 00:10:50,940 válido 291 00:10:50,940 --> 00:10:54,279 El nombre de la excepción 292 00:10:54,279 --> 00:10:56,600 Da igual lo largo que sea 293 00:10:56,600 --> 00:10:58,019 Cuanto más explicativo mejor 294 00:10:58,019 --> 00:11:00,379 Voto no válido y por convenio 295 00:11:00,379 --> 00:11:01,399 No es que sea obligatorio 296 00:11:01,399 --> 00:11:03,379 Por convenio suelen acabar en exception 297 00:11:03,379 --> 00:11:06,279 Todas para que se vea que es una clase de excepción 298 00:11:06,279 --> 00:11:09,139 Exception 299 00:11:09,139 --> 00:11:12,759 Vale, no es que sea obligatorio 300 00:11:12,759 --> 00:11:13,679 Pero hombre 301 00:11:13,679 --> 00:11:15,360 Aclara mucho el código 302 00:11:15,360 --> 00:11:17,519 Todas las clases cuyo nombre acabe en exception 303 00:11:17,519 --> 00:11:18,460 Son clases de excepción 304 00:11:18,460 --> 00:11:25,769 vale, pues para que esta clase 305 00:11:25,769 --> 00:11:27,809 sea una excepción 306 00:11:27,809 --> 00:11:28,250 de verdad 307 00:11:28,250 --> 00:11:31,889 y tenga todo lo que tienen que tener las excepciones 308 00:11:31,889 --> 00:11:33,529 de poder ser lanzadas 309 00:11:33,529 --> 00:11:35,710 de que el otro la pueda 310 00:11:35,710 --> 00:11:37,429 recoger, etcétera 311 00:11:37,429 --> 00:11:39,990 tiene que heredar 312 00:11:39,990 --> 00:11:41,049 ¿de qué? 313 00:11:41,169 --> 00:11:43,409 de una superclase magnífica que se llama 314 00:11:43,409 --> 00:11:45,929 exception, que tiene todo lo básico de las excepciones 315 00:11:45,929 --> 00:11:49,350 entonces 316 00:11:49,350 --> 00:11:51,590 exception es una superclase 317 00:11:51,590 --> 00:11:55,429 que a su vez hereda de una 318 00:11:55,429 --> 00:11:57,889 interfaz throwable que es todo lo lanzable 319 00:11:57,889 --> 00:11:58,950 todo lo lanzable 320 00:11:58,950 --> 00:12:01,889 y esto ya lo convierte 321 00:12:01,889 --> 00:12:03,629 en excepción y en realidad yo no hace 322 00:12:03,629 --> 00:12:05,570 falta que haga nada más, la puedo dejar así con su 323 00:12:05,570 --> 00:12:07,009 constructor por defecto y ya está 324 00:12:07,009 --> 00:12:08,769 la podría dejar así 325 00:12:08,769 --> 00:12:10,809 pero 326 00:12:10,809 --> 00:12:13,669 la clase exception entre todas 327 00:12:13,669 --> 00:12:15,730 las cosas que tiene dentro tiene una variable 328 00:12:15,730 --> 00:12:16,809 que es su mensajito 329 00:12:16,809 --> 00:12:19,549 y ese mensajito es el mensajito que te 330 00:12:19,549 --> 00:12:21,590 aparece en las líneas rojas cuando 331 00:12:21,590 --> 00:12:23,629 sale, entonces hombre vamos 332 00:12:23,629 --> 00:12:25,950 a aprovechar esa variable y vamos a poner el mensajito 333 00:12:25,950 --> 00:12:27,590 personalizado para esta excepción 334 00:12:27,590 --> 00:12:29,070 que en este caso sería 335 00:12:29,070 --> 00:12:31,909 el votante no ha votado 336 00:12:31,909 --> 00:12:33,029 bien, vale 337 00:12:33,029 --> 00:12:35,590 vale, pues como lo podemos hacer 338 00:12:35,590 --> 00:12:37,009 pues vamos a hacer su 339 00:12:37,009 --> 00:12:39,789 constructor y le vamos a pasar 340 00:12:39,789 --> 00:12:41,590 a partir del constructor esa variable 341 00:12:41,590 --> 00:12:50,940 vale, pues la clase 342 00:12:50,940 --> 00:12:52,820 exception, la clase exception 343 00:12:52,820 --> 00:12:55,159 tiene un constructor 344 00:12:55,159 --> 00:12:58,460 del que yo me voy a aprovechar 345 00:12:58,460 --> 00:13:03,059 un constructor al que si yo le paso 346 00:13:03,059 --> 00:13:04,019 un mensajito 347 00:13:04,019 --> 00:13:06,759 esa variable 348 00:13:06,759 --> 00:13:09,259 mensaje interno se inicializa 349 00:13:09,259 --> 00:13:10,200 con este mensajito 350 00:13:10,200 --> 00:13:23,860 pues cuando este objeto 351 00:13:23,860 --> 00:13:25,299 excepción se instancie 352 00:13:25,299 --> 00:13:28,480 se va a instanciar 353 00:13:28,480 --> 00:13:30,100 metiendo en su variable 354 00:13:30,100 --> 00:13:31,519 interna mensaje esta 355 00:13:31,519 --> 00:13:34,320 y esa variable interna es la que nos saca la máquina virtual 356 00:13:34,320 --> 00:13:42,139 luego, vale, ya está nuestra 357 00:13:42,139 --> 00:13:42,879 excepción hecha 358 00:13:42,879 --> 00:13:45,960 este aviso simplemente de que como implementa 359 00:13:45,960 --> 00:13:47,500 Serializable, todas las exceptions 360 00:13:47,500 --> 00:13:50,019 Nos dice, no tienes un valor de serialización 361 00:13:50,019 --> 00:13:52,159 Pero eso no nos hace falta, si no vamos a serializar 362 00:13:52,159 --> 00:13:53,779 Nah, ese amarillo lo olvidáis 363 00:13:53,779 --> 00:13:55,779 Vale, pues ahora ya 364 00:13:55,779 --> 00:13:58,240 Sí que lanzamos throw new 365 00:13:58,240 --> 00:13:59,820 Voto 366 00:13:59,820 --> 00:14:02,200 No 367 00:14:02,200 --> 00:14:03,480 Válido 368 00:14:03,480 --> 00:14:06,580 Exception 369 00:14:06,580 --> 00:14:09,740 Ala, y esta es 370 00:14:09,740 --> 00:14:11,360 La forma buena, en realidad 371 00:14:11,360 --> 00:14:13,759 La forma buena de que un método avise al de arriba 372 00:14:13,759 --> 00:14:14,840 De que ha pasado algo raro 373 00:14:14,840 --> 00:14:16,580 no devolviendo un null 374 00:14:16,580 --> 00:14:19,000 porque ese null vete a saber el de arriba como lo interpreta 375 00:14:19,000 --> 00:14:20,539 y nada de eso, esta es la forma buena 376 00:14:20,539 --> 00:14:23,159 lanzando con throw 377 00:14:23,159 --> 00:14:24,940 un objeto de excepción 378 00:14:24,940 --> 00:14:26,879 relacionado que explique lo que ha pasado 379 00:14:26,879 --> 00:14:28,799 que normalmente implica 380 00:14:28,799 --> 00:14:30,460 hacernos uno nuestro para nosotros 381 00:14:30,460 --> 00:14:34,919 ¿y por qué se nos ha quedado rojito? 382 00:14:35,919 --> 00:14:37,139 se nos ha quedado rojito 383 00:14:37,139 --> 00:14:38,919 porque si un método puede 384 00:14:38,919 --> 00:14:41,259 que lance una excepción, puede que lance 385 00:14:41,259 --> 00:14:43,000 en la firma que es 386 00:14:43,000 --> 00:14:45,220 lo que hay arriba, hay que avisar 387 00:14:45,220 --> 00:14:46,379 es obligatorio 388 00:14:46,379 --> 00:14:48,960 y esta firma tal y como está hecha 389 00:14:48,960 --> 00:14:50,299 no está avisando de nada de eso 390 00:14:50,299 --> 00:14:52,019 pues tiene que avisar 391 00:14:52,019 --> 00:14:54,879 ¿y cómo avisa? pues poniendo 392 00:14:54,879 --> 00:14:56,000 después de la firma 393 00:14:56,000 --> 00:14:57,500 throws 394 00:14:57,500 --> 00:15:00,879 la clase de excepción que puede ser 395 00:15:00,879 --> 00:15:05,929 que lance ¿vale? 396 00:15:08,149 --> 00:15:08,590 entonces 397 00:15:08,590 --> 00:15:10,629 esto 398 00:15:10,629 --> 00:15:12,470 significa, lanza la excepción 399 00:15:12,470 --> 00:15:14,529 se va a lanzar en el 400 00:15:14,529 --> 00:15:15,730 else, es decir, cuando 401 00:15:15,730 --> 00:15:17,669 el voto no sea válido 402 00:15:17,669 --> 00:15:34,769 Se puede lanzar lo que haya el momento cuando yo decida que toca parar y avisar, ¿vale? Y repito, si hubiera líneas de código aquí después, estas líneas de código, por ejemplo, esta, imaginaos que hay esto, ha votado, ¿vale? 403 00:15:34,769 --> 00:15:38,490 Bueno, claro, es que esto como tenemos aquí un retun 404 00:15:38,490 --> 00:15:40,870 Vale, vamos a poner aquí 405 00:15:40,870 --> 00:15:44,590 Si candidatos 406 00:15:44,590 --> 00:15:48,169 Contains voto 407 00:15:48,169 --> 00:15:52,870 A ver, voy a quitar el retun de aquí porque quiero poner una línea después del list 408 00:15:52,870 --> 00:15:54,210 Voy a poner aquí directamente 409 00:15:54,210 --> 00:15:58,610 Si candidatos no contiene el voto 410 00:15:58,610 --> 00:16:00,230 Entonces ahora ya lanzo la excepción 411 00:16:00,230 --> 00:16:01,769 Y así vemos mejor 412 00:16:01,769 --> 00:16:08,159 Y ahora ha votado y retun voto 413 00:16:08,159 --> 00:16:10,179 así me gusta más 414 00:16:10,179 --> 00:16:20,049 vale, esta versión me gusta más 415 00:16:20,049 --> 00:16:22,350 entonces, leemos el voto 416 00:16:22,350 --> 00:16:24,070 si no está 417 00:16:24,070 --> 00:16:25,549 contenido en los válidos 418 00:16:25,549 --> 00:16:27,409 excepción lanzada 419 00:16:27,409 --> 00:16:29,330 y el método da igual, ya se ha parado 420 00:16:29,330 --> 00:16:32,330 ya se ha parado, esto que hay después ya no se va a ejecutar 421 00:16:32,330 --> 00:16:34,029 nunca, se ha lanzado 422 00:16:34,029 --> 00:16:35,629 excepción y para arriba, se acabó 423 00:16:35,629 --> 00:16:38,149 si el 424 00:16:38,149 --> 00:16:41,149 voto si es válido 425 00:16:41,149 --> 00:16:43,629 entonces ya no entra en el if 426 00:16:43,629 --> 00:16:45,950 con lo cual continúa y pondrá votado 427 00:16:45,950 --> 00:16:47,350 y retumboto, vale 428 00:16:47,350 --> 00:16:49,509 y podemos poner aquí 429 00:16:49,509 --> 00:16:51,529 a lo mejor para verlo 430 00:16:51,529 --> 00:16:52,750 ha votado a este 431 00:16:52,750 --> 00:16:58,090 ha votado a este 432 00:16:58,090 --> 00:16:59,490 por ejemplo, vale 433 00:16:59,490 --> 00:17:01,990 vale, pues este método es más bonito 434 00:17:01,990 --> 00:17:04,390 porque este método ya sí que está avisando 435 00:17:04,390 --> 00:17:06,329 está avisando 436 00:17:06,329 --> 00:17:07,230 de una manera 437 00:17:07,230 --> 00:17:11,190 explícita 438 00:17:11,190 --> 00:17:13,630 y además se para 439 00:17:13,630 --> 00:17:15,930 se para, o sea, si el voto no es válido 440 00:17:15,930 --> 00:17:17,650 es que ni siquiera sigue. Esto ya no lo va a hacer. 441 00:17:17,769 --> 00:17:19,509 Se para. Avisa de manera explícita. 442 00:17:20,289 --> 00:17:21,049 Este ya está mejor. 443 00:17:23,099 --> 00:17:24,720 Pero, recuerdo, 444 00:17:25,559 --> 00:17:27,019 no se nos puede olvidar que si 445 00:17:27,019 --> 00:17:29,319 puede que lance 446 00:17:29,319 --> 00:17:31,099 una excepción, es decir, si hay un throw porque 447 00:17:31,099 --> 00:17:32,720 puede que en algún momento la lance, 448 00:17:33,480 --> 00:17:35,220 la firma del método tiene que incorporar el 449 00:17:35,220 --> 00:17:37,359 throw para avisarlo. 450 00:17:37,920 --> 00:17:38,920 La firma del método tiene 451 00:17:38,920 --> 00:17:40,279 que incorporar el throw. 452 00:17:40,279 --> 00:17:40,700 Vale. 453 00:17:43,259 --> 00:17:44,259 Vamos a llamar 454 00:17:44,259 --> 00:17:45,000 ahora a este método. 455 00:17:45,000 --> 00:17:48,099 Ahora, ¿dónde llamaba yo a GetBoto? 456 00:17:48,180 --> 00:17:48,460 Aquí 457 00:17:48,460 --> 00:17:51,859 Vale, pues esto lo vamos a dejar comentado 458 00:17:51,859 --> 00:17:52,980 Vamos a usar ahora el otro 459 00:17:52,980 --> 00:17:57,150 Vamos a usar ahora el otro 460 00:17:57,150 --> 00:17:59,630 GetBotoV2 461 00:17:59,630 --> 00:18:06,960 GetBotoV2 462 00:18:06,960 --> 00:18:07,880 Vamos a llamar a este 463 00:18:07,880 --> 00:18:11,599 Vale, pues ahora mucho mejor 464 00:18:11,599 --> 00:18:14,440 Porque el propio compilador ya nos ha puesto 465 00:18:14,440 --> 00:18:16,539 Una barrera de seguridad 466 00:18:16,539 --> 00:18:19,759 Yo cuando llamaba a GetBoto 467 00:18:19,759 --> 00:18:22,160 Tan tranquilo, que luego me sale un null 468 00:18:22,160 --> 00:18:23,900 ¿Ya es problema tuyo? ¿Qué haces con ese null? 469 00:18:24,819 --> 00:18:26,140 Ahora, llamo a getVoto2 470 00:18:26,140 --> 00:18:27,400 que me avisa con excepción. 471 00:18:29,180 --> 00:18:30,059 Automáticamente ya el 472 00:18:30,059 --> 00:18:31,779 compilador ya me pone ahí 473 00:18:31,779 --> 00:18:34,140 un freno. ¿Y qué me está 474 00:18:34,140 --> 00:18:35,059 diciendo el compilador? 475 00:18:35,920 --> 00:18:37,920 Pues vamos a leerlo. El compilador 476 00:18:37,920 --> 00:18:39,640 me está diciendo, uy, 477 00:18:40,319 --> 00:18:42,079 cuidadito, cuidadito 478 00:18:42,079 --> 00:18:43,859 que este método te puede dar 479 00:18:43,859 --> 00:18:46,160 voto no válido excepción. Cuidado. 480 00:18:47,039 --> 00:18:47,880 ¿Vale? Cuidado. 481 00:18:48,640 --> 00:18:49,660 Entonces, tú ya sabes 482 00:18:49,660 --> 00:18:51,500 que ese método te puede dar 483 00:18:51,500 --> 00:18:53,079 una excepción y 484 00:18:53,079 --> 00:18:55,640 no te va a compilar mientras tú 485 00:18:55,640 --> 00:18:56,819 no la captures. 486 00:18:58,119 --> 00:18:59,319 Esto es una semi mentira, 487 00:18:59,519 --> 00:19:01,579 pero luego ya la... 488 00:19:01,579 --> 00:19:05,400 ¿Vale? Porque puedes no capturarla 489 00:19:05,400 --> 00:19:06,940 y propagarla, pero bueno, 490 00:19:07,079 --> 00:19:08,200 eso lo hacemos ahora después. 491 00:19:11,420 --> 00:19:13,700 ¿Veis cómo esta forma de avisar es mucho mejor? 492 00:19:14,079 --> 00:19:15,680 Es mucho mejor porque ya el compilador 493 00:19:15,680 --> 00:19:17,720 te está diciendo, oye, cuidado, ten en cuenta 494 00:19:17,720 --> 00:19:19,619 que eso te puede dar una excepción, ten en cuenta. 495 00:19:20,240 --> 00:19:21,259 Entonces tú dices, ¡ah! 496 00:19:22,420 --> 00:19:23,779 Vale, vale. Entonces yo ya 497 00:19:23,779 --> 00:19:25,799 decido aquí que hago, o me hago un bucle 498 00:19:25,799 --> 00:19:27,640 con el boolean que hemos 499 00:19:27,640 --> 00:19:31,420 hecho antes, o 500 00:19:31,420 --> 00:19:34,779 vale, yo ya la capturo 501 00:19:34,779 --> 00:19:36,900 y digo, vale, intenta votar 502 00:19:36,900 --> 00:19:39,839 si no puedes votar 503 00:19:39,839 --> 00:19:42,859 porque te sale 504 00:19:42,859 --> 00:19:44,799 voto no válido, yo aquí la 505 00:19:44,799 --> 00:19:46,420 capturo, la excepción que lanza este 506 00:19:46,420 --> 00:19:48,859 si me sale la excepción 507 00:19:48,859 --> 00:19:50,859 voto no válido, pues entonces 508 00:19:50,859 --> 00:19:52,539 ya aquí hacemos lo que nos dé la gana 509 00:19:52,539 --> 00:19:54,500 pues por ejemplo 510 00:19:54,500 --> 00:19:56,960 todos los que hagan voto no válido van a votar al primero 511 00:19:56,960 --> 00:20:04,869 Ala, ya está, porque yo he decidido eso, pero vamos, lo normal sería meterlo en un bucle, etc. 512 00:20:08,029 --> 00:20:37,410 Candidatos.get de 0, lo podemos poner aquí, voto no válido, se asigna, se asignará al primer candidato, 513 00:20:37,410 --> 00:20:39,529 O lo que uno quiera 514 00:20:39,529 --> 00:20:40,630 Eso ya es lo de menos 515 00:20:40,630 --> 00:20:42,829 Voto no válido 516 00:20:42,829 --> 00:20:44,730 Se asignará al primer candidato 517 00:20:44,730 --> 00:20:45,869 O lo que uno le dé la gana 518 00:20:45,869 --> 00:20:46,410 Y ya está 519 00:20:46,410 --> 00:20:48,470 ¿Vale? 520 00:20:50,369 --> 00:20:52,009 ¿Qué es el método ese que te salía? 521 00:20:56,950 --> 00:20:58,009 Ese es el método 522 00:20:58,009 --> 00:20:58,990 Lo vimos ayer 523 00:20:58,990 --> 00:20:59,869 Es el método 524 00:20:59,869 --> 00:21:03,349 Que te muestra las letras rojas 525 00:21:03,349 --> 00:21:05,470 Es decir, te muestra el contenido dentro de la excepción 526 00:21:05,470 --> 00:21:07,569 Entonces, por eso la máquina virtual 527 00:21:07,569 --> 00:21:09,009 Cuando tú no capturas una excepción 528 00:21:09,009 --> 00:21:09,970 Y para el programa 529 00:21:09,970 --> 00:21:12,650 vale, pues lo primero 530 00:21:12,650 --> 00:21:14,710 que hace es llamar, aunque tú no lo ves 531 00:21:14,710 --> 00:21:16,509 a ese print extract trace y por eso nos aparecen 532 00:21:16,509 --> 00:21:18,470 esas cosas rojas, vale 533 00:21:18,470 --> 00:21:20,450 entonces yo lo voy a, primero lo voy a probar 534 00:21:20,450 --> 00:21:22,190 sin llamarlo, luego llamándolo, vale 535 00:21:22,190 --> 00:21:24,849 bueno, pues entonces 536 00:21:24,849 --> 00:21:26,670 ahora ya esta aplicación está mejor 537 00:21:26,670 --> 00:21:28,509 hecha, porque el compilador 538 00:21:28,509 --> 00:21:30,650 nos ha avisado de que esto puede que salga 539 00:21:30,650 --> 00:21:32,589 mal y te ha obligado a ti 540 00:21:32,589 --> 00:21:34,430 a hacer algo, te ha obligado a ti a hacer algo 541 00:21:34,430 --> 00:21:36,430 pues tú lo capturas y lo que has decidido 542 00:21:36,430 --> 00:21:37,569 hacer es dárselo al primero 543 00:21:37,569 --> 00:21:39,109 Y ya está 544 00:21:39,109 --> 00:21:40,710 Podrías haber decidido otra cosa 545 00:21:40,710 --> 00:21:43,250 O haber metido este try catch en un bucle 546 00:21:43,250 --> 00:21:45,089 O lo que quisiéramos 547 00:21:45,089 --> 00:21:47,990 Venga, vamos a ejecutar ahora esto 548 00:21:47,990 --> 00:21:49,529 Con los cambios que hemos hecho 549 00:21:49,529 --> 00:21:52,349 A ver si nos 550 00:21:52,349 --> 00:21:53,569 Funciona todo 551 00:21:53,569 --> 00:21:57,049 ¿Cuántos se presentan? 552 00:21:57,369 --> 00:21:59,190 Tres, dime nombre 553 00:21:59,190 --> 00:22:01,690 El A, el B y el C 554 00:22:01,690 --> 00:22:06,349 Y ahora ya empezamos con los votos 555 00:22:06,349 --> 00:22:07,930 Porque no dice ni que voto ni nada 556 00:22:07,930 --> 00:22:08,569 Será eso 557 00:22:08,569 --> 00:22:10,470 A, ha votado A 558 00:22:10,470 --> 00:22:13,410 C, ahora pongo el 559 00:22:13,410 --> 00:22:15,509 G, voto no válido 560 00:22:15,509 --> 00:22:17,210 se asigna el primero, vale, muy bien 561 00:22:17,210 --> 00:22:18,029 pero seguimos 562 00:22:18,029 --> 00:22:21,450 el B, el D, no válido, se asigna el primero 563 00:22:21,450 --> 00:22:23,410 vale, y aquí seguimos 564 00:22:23,410 --> 00:22:28,549 hasta acabar, vale, ya está 565 00:22:28,549 --> 00:22:30,069 8, ya está 566 00:22:30,069 --> 00:22:35,849 ¿entendido? 567 00:22:38,920 --> 00:22:41,400 entonces, E es el objeto 568 00:22:41,400 --> 00:22:42,079 excepción 569 00:22:42,079 --> 00:22:45,500 E tiene información que podemos sacar de él si queremos 570 00:22:45,500 --> 00:22:47,240 por ejemplo, a través 571 00:22:47,240 --> 00:22:49,640 de este método, esto te muestra 572 00:22:49,640 --> 00:22:51,440 por consola la traza 573 00:22:51,440 --> 00:22:53,420 de llamadas que llegaron a esa excepción 574 00:22:53,420 --> 00:22:55,259 el mensajito interno 575 00:22:55,259 --> 00:22:57,279 ¿vale? o sea, si quisiéramos 576 00:22:57,279 --> 00:22:58,599 que era lo que comentábamos ayer 577 00:22:58,599 --> 00:23:01,160 si estamos en tiempo de desarrollo de código, queremos 578 00:23:01,160 --> 00:23:02,319 toda la información posible 579 00:23:02,319 --> 00:23:05,240 entonces en ese caso, llamaríamos 580 00:23:05,240 --> 00:23:07,099 a este porque además me sale 581 00:23:07,099 --> 00:23:08,220 toda la información de la excepción 582 00:23:08,220 --> 00:23:11,279 ¿no? si yo vuelvo a ejecutar este programa así 583 00:23:11,279 --> 00:23:15,359 venga, dos candidatos 584 00:23:15,359 --> 00:23:17,220 A y B 585 00:23:17,220 --> 00:23:19,539 Y ahora voy a votar a uno que no hay 586 00:23:19,539 --> 00:23:22,240 ¿Ves? Me sale esto 587 00:23:22,240 --> 00:23:24,799 Este es el print extract trace 588 00:23:24,799 --> 00:23:27,400 Que es la información interna 589 00:23:27,400 --> 00:23:28,799 Entre ella el mensajito 590 00:23:28,799 --> 00:23:30,640 El mensajito que yo he puesto 591 00:23:30,640 --> 00:23:33,579 El votante ni votar ha sabido 592 00:23:33,579 --> 00:23:35,400 Me sale ahí el mensajito 593 00:23:35,400 --> 00:23:37,099 Lo que yo he puesto en la excepción 594 00:23:37,099 --> 00:23:38,759 Pero el programa no ha parado 595 00:23:38,759 --> 00:23:40,240 El programa no para 596 00:23:40,240 --> 00:23:44,000 Porque esto de aquí es simplemente el resultado de 597 00:23:44,000 --> 00:23:47,279 Esta sentencia 598 00:23:47,279 --> 00:23:47,960 Esta 599 00:23:47,960 --> 00:23:50,720 el resultado de esa 600 00:23:50,720 --> 00:23:52,759 y luego después me ha hecho esto 601 00:23:52,759 --> 00:23:54,480 y lo ha asignado al cero 602 00:23:54,480 --> 00:23:57,119 es decir, esto es 603 00:23:57,119 --> 00:24:00,630 esto, que nos da 604 00:24:00,630 --> 00:24:02,450 información, pero claro, cuando ya 605 00:24:02,450 --> 00:24:04,390 le damos el programa a alguien para que lo use 606 00:24:04,390 --> 00:24:06,630 eso lo quitamos, porque no queremos que vea 607 00:24:06,630 --> 00:24:08,509 eso, eso para 608 00:24:08,509 --> 00:24:10,289 nosotros, cuando estamos haciendo pruebas, si nos interesa 609 00:24:10,289 --> 00:24:12,589 para saber dónde ha fallado, tú pinchas 610 00:24:12,589 --> 00:24:14,589 aquí y dices, ah, vale, me falló aquí 611 00:24:14,589 --> 00:24:15,990 pero 612 00:24:15,990 --> 00:24:18,309 cuando ya se acaba o no 613 00:24:18,309 --> 00:24:20,109 No haces eso, ¿vale? 614 00:24:36,839 --> 00:24:38,079 Vale, pues entonces 615 00:24:38,079 --> 00:24:41,160 Más o menos entendido hasta aquí 616 00:24:41,160 --> 00:24:42,960 Pues nos falta un pelinín 617 00:24:42,960 --> 00:24:44,640 Y ya damos lo de las excepciones 618 00:24:44,640 --> 00:24:46,119 Por ventilado 619 00:24:46,119 --> 00:24:50,279 Venga, vamos a aprovechar y paramos aquí un momento