1 00:00:03,439 --> 00:00:11,539 alguna cosita por ahí que queráis comentarme antes de arrancar a contar yo cosas es alguna 2 00:00:11,539 --> 00:00:28,129 duda por ahí bueno si no tenéis nada en particular que queráis que veamos en la última tutoría bueno 3 00:00:28,129 --> 00:00:34,530 me preguntasteis alguno de vosotros por el método finalice y bueno os dije que lo echaba un ojillo 4 00:00:34,530 --> 00:00:37,909 es un método que en verdad se suele utilizar poco 5 00:00:37,909 --> 00:00:42,070 pero bueno, estuve haciendo alguna prueba con él 6 00:00:42,070 --> 00:00:43,770 y os puse una entrada en el foro 7 00:00:43,770 --> 00:00:45,189 vamos a repasarlo un momento 8 00:00:45,189 --> 00:00:49,679 y así ya la dejamos clara 9 00:00:49,679 --> 00:00:55,340 el método finalice un poco la idea que propone 10 00:00:55,340 --> 00:00:58,859 es que sea como un destructor de los objetos de una clase 11 00:00:58,859 --> 00:01:02,439 igual que el constructor 12 00:01:02,439 --> 00:01:04,980 es el que se ejecuta cuando arrancamos 13 00:01:04,980 --> 00:01:09,540 cuando damos de alta un objeto, normalmente hacemos la llamada 14 00:01:09,540 --> 00:01:12,739 al constructor después de poner la etiqueta new 15 00:01:12,739 --> 00:01:17,540 en el momento de crearlo y nos sirve para hacer unas inicializaciones que consideramos 16 00:01:17,540 --> 00:01:21,340 que sean necesarias para que ese objeto vaya trabajando 17 00:01:21,340 --> 00:01:24,939 en, vaya participando dentro del programa 18 00:01:24,939 --> 00:01:28,579 finalice, pues ya os digo, se hace cuando termina 19 00:01:28,579 --> 00:01:33,379 el método finalice, la característica que tiene es que 20 00:01:33,379 --> 00:01:39,920 llamado desde desde el recolector de basura y el recolector de basura lo llama la máquina virtual 21 00:01:39,920 --> 00:01:46,939 dejaba cuando llama el recolector de basura la máquina la máquina virtual dejaba al recolector 22 00:01:46,939 --> 00:01:53,299 de basura pues cuando esté programado cuando en cada versión del recolector de basura han hecho 23 00:01:53,299 --> 00:01:59,420 ese desarrollo pues habrán tenido unos criterios para decidir cuándo se va liberando la memoria 24 00:01:59,420 --> 00:02:07,359 ram que ocupan los los diferentes objetos y junto a esto la llamada al método finalice de esos 25 00:02:07,359 --> 00:02:15,099 objetos en línea general es cuando por lo que he podido leer es raro ver que se hacen llamadas en 26 00:02:15,099 --> 00:02:21,120 los programas sobre todo en estos tan cortos que vamos utilizando nosotros al método finalice pero 27 00:02:21,120 --> 00:02:28,659 cuando he visto por ahí que suelen llamarlos pues suelen llamarlos cuando la máquina virtual detecta 28 00:02:28,659 --> 00:02:33,639 que a lo mejor hay demasiada memoria RAM ocupada, pues dice, pues mira, en este momento o si tiene una cuota 29 00:02:33,639 --> 00:02:38,979 para la ejecución del programa que le haya asignado el sistema operativo, pues cuando ve que empieza a haber 30 00:02:38,979 --> 00:02:44,099 carencia de memoria RAM que utilizar para dar de alta nuevos objetos, llama al recolector de basura 31 00:02:44,099 --> 00:02:50,180 para que libere todo lo que sea posible. ¿Tenemos otros controles en principio de eso? Pues en principio 32 00:02:50,180 --> 00:02:56,979 de nuestro programa no, a no ser que llamemos a un método del sistema que fuerza la llamada al recolector 33 00:02:56,979 --> 00:03:00,979 de basura más allá de cuando esté programada por la máquina virtual. 34 00:03:01,199 --> 00:03:03,759 Ahora hacemos una pruebecilla que viene a ser la que os puse. 35 00:03:04,659 --> 00:03:08,719 Y luego, sin hacer esa llamada, podemos intentar forzar 36 00:03:08,719 --> 00:03:12,439 que se ejecute el método finalice 37 00:03:12,439 --> 00:03:17,300 haciendo un bucle cercano a que sea infinito 38 00:03:17,300 --> 00:03:21,080 de construcción de nuevos objetos 39 00:03:21,080 --> 00:03:24,259 que vayan creándose y finalizándose 40 00:03:24,259 --> 00:03:29,539 pero se acaban creándose y destruyéndose dentro del ámbito en el que estén definidos. 41 00:03:29,740 --> 00:03:31,400 Ahora después lo hacemos con código y vemos cómo. 42 00:03:33,180 --> 00:03:37,360 Pero claro, cuya memoria va a quedar liberada cuando pase el recolector de basura. 43 00:03:37,360 --> 00:03:42,319 Entonces obligaremos a hacer mucha reserva de memoria RAM en nuestro programa 44 00:03:42,319 --> 00:03:47,800 de tal forma que la máquina virtual se dé cuenta que estamos ocupando mucha memoria RAM 45 00:03:47,800 --> 00:03:53,560 y haga la llamada al recolector de basura y como consecuencia al método finalice. 46 00:03:54,259 --> 00:04:20,420 Si más allá de liberar memoria queremos tener certeza que de forma inmediata cuando desaparece un objeto, como más o menos vienen a proponer los ejercicios que se plantean en este tema, pase algo, en el ejercicio que me comentabais que aparecía el método finalice la semana pasada y que vamos a utilizar ahora como ejemplo, lo que pasa es que se decrementa una variable estática del número de personas que se han dado de alta. 47 00:04:20,420 --> 00:04:37,519 Si queremos que eso pase inmediatamente en el momento en el que desaparece el objeto de la persona, lo tenemos complicado, porque como el algoritmo de la máquina virtual no considera oportuno llamar al recolector de basura, ese finalice no se va a ejecutar. 48 00:04:37,519 --> 00:04:43,240 entonces si queremos que pase algo cuando se destruye el objeto pues igual sería interesante 49 00:04:43,240 --> 00:04:47,839 intentar hacer una llamada forzando la llamada al método finalice o a cualquier otro método 50 00:04:47,839 --> 00:04:53,120 llamándolo como queramos y si queremos que pase algo pero no nos importa cuándo 51 00:04:53,120 --> 00:04:57,240 pues entonces sí que podríamos dejar ese código metido en este método 52 00:04:57,240 --> 00:05:02,120 vamos con código que yo creo que será más sencillo 53 00:05:02,120 --> 00:05:07,139 entonces mirad aquí el ejercicio 4 con la solución que tenemos propuesta 54 00:05:07,139 --> 00:05:53,899 pues lo tengo por aquí y entonces lo voy a cargar en un proyecto, vemos el método finalice, cómo funciona y luego bueno pues continuamos con alguna otra cosa por ahí, vamos a crear un proyecto que se llame finalice, cargo el proyecto, aquí la clave está un poco en estas dos clases, fijaros la clase persona, bueno pues tiene un constructor por aquí, varios constructores, tiene el constructor completo 55 00:05:54,899 --> 00:06:03,019 Constructor completo es el que recibe como parámetros todos los atributos que tiene definidos en la clase y se los asigna. 56 00:06:03,740 --> 00:06:06,139 Además hace aquí que incrementa el número de personas. 57 00:06:07,319 --> 00:06:12,480 Y luego este es el constructor copia que recibe una referencia a otro objeto de la clase persona 58 00:06:12,480 --> 00:06:17,759 y desde los atributos que tiene este objeto los asignamos a este, ese sería el copia. 59 00:06:17,759 --> 00:06:20,399 Y luego tiene un constructor vacío. 60 00:06:20,399 --> 00:06:44,779 El método finalice, por aquí lo tenemos, que lo que hace es decrementar el número de personas que están a dar de alta. El problema es que puede ser que una de las personas deje de participar ya en nuestro programa porque se sale del ámbito donde ha sido definido y la llamada finalice no sea inmediata, por lo menos la llamada a través del recolector de basura. 61 00:06:44,779 --> 00:06:53,300 entonces aquí en el método en probar persona que es donde tenemos el método main fijaros que lo 62 00:06:53,300 --> 00:07:00,560 que hacemos es definir es como aquí como cinco personas verdad fijaros por aquí que están que 63 00:07:00,560 --> 00:07:07,939 existirán en todo el ámbito del método main y luego lo que hace es llamar aquí a un método 64 00:07:07,939 --> 00:07:21,939 que es el método pruebaPersonaTemporal, que lo que hace es crear otra persona, pero esta persona existirá en el ámbito en el que es definido, es decir, en el ámbito de este método, será local a este método. 65 00:07:22,620 --> 00:07:31,879 Entonces, esta persona en particular, en el momento en el que termina la ejecución del método, desaparecerá. Aquí desaparece. 66 00:07:31,879 --> 00:07:39,939 En cambio, estas otras personas permanecen hasta el final del main, es decir, permanecerían hasta aquí. 67 00:07:41,579 --> 00:07:58,209 Según vamos dando de alta personas, aquí tendríamos una persona dada de alta, la variable estática número de personas sería 1, en este momento sería 2, 3, 4, 5, se han dado de alta 5. 68 00:07:59,189 --> 00:08:05,310 Cuando entramos en este método, justo en este momento serían seis las personas que están a dar de alta. 69 00:08:06,550 --> 00:08:13,730 Al salir del método, esta desaparecería, volverían a ser cinco, es decir, aquí tenemos cinco en esta zona de código, 70 00:08:13,829 --> 00:08:19,529 las cinco que hemos definido arriba, una sexta mientras estamos ejecutando el método y aquí volveríamos a tener cinco. 71 00:08:21,209 --> 00:08:28,689 ¿Qué es lo que pasa? Que como el método finalice, probablemente en esta ejecución rápida no va a ser llamado por el recolector de basura, 72 00:08:28,689 --> 00:08:34,309 lo que hemos hecho ha sido forzar aquí una llamada al método finalice entonces en verdad no estamos 73 00:08:34,309 --> 00:08:40,629 comprobando muy bien el funcionamiento de finalice como un método llamado de forma automática pues 74 00:08:40,629 --> 00:08:46,149 porque lo estamos haciendo con la llamada aquí es decir se convierte en algo del estilo a la llamada 75 00:08:46,149 --> 00:08:52,629 de cualquier otro método ya si hacemos una ejecución con esto manteniendo esto hacer 76 00:08:52,629 --> 00:08:57,909 varias ejecuciones. Bueno, pues aquí nos diría que hay un total 77 00:08:57,909 --> 00:09:02,289 de seis personas. Una, dos, tres, cuatro, cinco. Está la sexta 78 00:09:02,289 --> 00:09:08,210 persona, fijaros. Y ese mensaje me lo saca aquí. Dice, aquí hay 79 00:09:08,210 --> 00:09:14,049 seis personas. Cuando he dado de alta este, me saca este mensaje 80 00:09:14,049 --> 00:09:17,970 y dice, pues hay siete personas. Llamo a finalice, aunque lo estoy 81 00:09:17,970 --> 00:09:21,809 llamando de forma forzada yo aquí, al método finalice 82 00:09:21,809 --> 00:09:25,970 del objeto de la clase persona, que recordad 83 00:09:25,970 --> 00:09:29,210 que lo que hace es decrementar esta variable estática en 1. 84 00:09:31,879 --> 00:09:35,320 Entonces, una vez terminado esto, cuando volvemos a sacar este mensaje me dice que hay 6 personas. 85 00:09:35,840 --> 00:09:39,440 Como consecuencia de que hemos llamado a finalice. Pero lo hemos llamado nosotros aquí 86 00:09:39,440 --> 00:09:43,539 de forma forzada. Si lo comentamos 87 00:09:43,539 --> 00:09:47,360 y la llamada que ponemos nosotros aquí de forma 88 00:09:47,360 --> 00:09:54,139 explícita y lo ejecutamos fijaros como este mensaje sigue diciendo que hay siete personas aunque está 89 00:09:54,139 --> 00:10:01,220 ya habrá desaparecido porque no está fuera de su ámbito pero qué pasa que desde terminar aquí hasta 90 00:10:01,220 --> 00:10:09,320 ejecutar este sistema println no ha entrado en funcionamiento el recolector de basura entonces 91 00:10:09,320 --> 00:10:15,139 como como os proponemos una entrada en el aula virtual justo buenos y también en la zona de 92 00:10:15,139 --> 00:10:18,299 actividades donde están los enunciados, puse como si fuera una actividad más 93 00:10:18,299 --> 00:10:22,980 comentándoos la solución que voy a dar ahora para comprobar efectivamente 94 00:10:22,980 --> 00:10:30,440 cómo funciona el finalice y lo que podemos hacer aquí es justo después 95 00:10:30,440 --> 00:10:35,559 de esta llamada, es decir, en esta llamada habrá un momento en el que serán 96 00:10:35,559 --> 00:10:42,759 siete, se termina aquí el método, con lo cual esta persona ya desaparece 97 00:10:42,759 --> 00:10:46,259 este objeto, lo que vamos a hacer es utilizar una llamada al 98 00:10:46,259 --> 00:10:51,320 sistema que fuerce la llamada al recolector de basura con 99 00:10:51,320 --> 00:10:55,600 independencia de que en algún momento lo tenga que llamar la 100 00:10:55,600 --> 00:10:56,220 máquina virtual. 101 00:10:56,539 --> 00:10:59,399 Entonces, esta llamada la podemos hacer desde código. 102 00:11:02,000 --> 00:11:06,120 GC vienen a ser las siglas de recolector de basura en inglés, 103 00:11:06,120 --> 00:11:09,299 Garbage Collector, recolector de basura. 104 00:11:12,200 --> 00:11:15,259 Y entonces, si hacemos esto, este se entiende que aparte de 105 00:11:15,259 --> 00:11:18,639 liberar la memoria, llamará a los finalices de todos los métodos, 106 00:11:19,440 --> 00:11:22,500 de todos los objetos que ya estén desapareciendo. 107 00:11:22,659 --> 00:11:26,480 Y el finalice del método de la clase persona 108 00:11:26,480 --> 00:11:28,320 lo que hace es decrementarnos este valor. 109 00:11:30,320 --> 00:11:32,539 Vamos a hacer varias ejecuciones sin meter nada más. 110 00:11:34,809 --> 00:11:36,690 Y fijaros, me sigue dando 7 por aquí. 111 00:11:37,470 --> 00:11:40,250 A ver si con varias, 7, 6. 112 00:11:40,250 --> 00:11:42,490 Fijaros, aquí, esta vez me ha dado 6. 113 00:11:43,590 --> 00:11:44,970 Las dos anteriores, 7. 114 00:11:45,809 --> 00:11:46,570 7, ¿veis? 115 00:11:46,570 --> 00:12:13,230 6, 7, 7, bueno, ha dado una vez 6, a ver si vuelve a dar otra 6, ha dado varias veces, mirad, esta vez 6. ¿Qué es lo que sucede? El año que viene en la asignatura de programación de servicios y procesos, típicamente está situada esta asignatura en segundo, veréis la programación multihilo. 116 00:12:13,909 --> 00:12:20,429 Esto quiere decir que diferentes secciones de un programa se pueden ejecutar de forma concurrente al mismo tiempo. 117 00:12:21,110 --> 00:12:27,210 Si tenemos varios procesadores, pues puede haber unos que estén ejecutando unas partes y otros que estén ejecutando otras partes del código. 118 00:12:27,769 --> 00:12:38,889 El recolector de basura, participando como un hilo o como un programa diferente, un proceso o un hilo diferente, a nuestro programa se ejecuta de forma paralela. 119 00:12:38,889 --> 00:13:04,169 Entonces, hay ejecuciones en las que esa competición de recursos del sistema para ejecutarse, este gana y entonces no le ha dado tiempo a acabar al recolector de basura y llamar a los finalices y me muestra aquí un 7 y otra vez es donde gana en esa ejecución competitiva el recolector de basura, ha ejecutado ya el método finalice y esto se ejecuta después del recolector de basura y entonces me pone aquí 6. 120 00:13:04,169 --> 00:13:16,250 Por eso va alternando una vez entre 6 o 7. Para tener certeza de que el recolector de basura se ejecuta antes, lo que podemos hacer es parar este proceso o este hilo durante un determinado tiempo. 121 00:13:16,889 --> 00:13:25,830 Y esto lo podemos hacer desde un método de una clase que tenemos disponible en Java, que es la clase Thread, que es precisamente hilo, que os comentaba antes. 122 00:13:25,830 --> 00:13:30,990 poner un sleep, duérmete durante, y aquí ponemos 123 00:13:30,990 --> 00:13:34,590 en milisegundos el tiempo que queramos que se duerma, vamos a poner por ejemplo 124 00:13:34,590 --> 00:13:38,909 3 segundos, 3000 milisegundos, es obligatorio meter esto 125 00:13:38,909 --> 00:13:43,269 entre una estructura de try-catch, la gestión de excepciones 126 00:13:43,269 --> 00:13:46,409 que veremos en otro tema, para que me compile 127 00:13:46,409 --> 00:13:50,509 me ayudo del IDE con el botón derecho, me lo ofrece 128 00:13:50,509 --> 00:13:54,730 y fijaros que ahora en la secuencia de ejecución se va a dormir aquí 129 00:13:54,730 --> 00:14:00,070 este proceso tres segundos para que estoy metiendo estos tres segundos para que esa competición 130 00:14:00,070 --> 00:14:05,350 paralela que hay entre el recolector de basura y mi programa le esté vaya pues se duerma aquí 131 00:14:05,350 --> 00:14:10,750 tres segundos y tengamos la garantía de que el recolector de basura se ejecuta antes entonces 132 00:14:10,750 --> 00:14:19,629 ahora si damos aquí a ejecución yo creo que pasan 23 veis y seis personas ahora ya con estos tres 133 00:14:19,629 --> 00:14:23,970 segundos le hemos dado tiempo a que el recolector de basura vamos a hacer varias ejecuciones pero 134 00:14:23,970 --> 00:14:28,490 en principio nunca pierda en esa competición para ver cuál de los dos acaba antes. 135 00:14:28,990 --> 00:14:33,750 Voy a mostrar aquí 6, fijaros que aquí tenemos un lazo de tiempo hasta que me saca el tercer 136 00:14:33,750 --> 00:14:38,870 mensaje que corresponde a estos 3 segundos, en ese tiempo el recolector de basura habrá 137 00:14:38,870 --> 00:14:43,789 hecho su tarea, que lo estamos forzando aquí, y habrá llamado al método finalice de la 138 00:14:43,789 --> 00:14:48,409 clase persona y a todos los métodos finalice de objetos que pudiera haber pendientes de 139 00:14:48,409 --> 00:14:53,370 limpiarse, me hace el decremento del número de personas y por eso 140 00:14:53,370 --> 00:14:57,840 ya me vuelve a mostrar 6 aquí. Hagamos otro par de ejecuciones 141 00:14:57,840 --> 00:15:14,259 y otra más. Estos 3 segundos de tiempo, veis 6. 142 00:15:14,419 --> 00:15:18,519 Aquí ya gana todas las veces el recolector de basura. Fijaros como 143 00:15:18,519 --> 00:15:22,559 ahora tenemos aquí comentado el finalice, o sea que realmente es el recolector de basura 144 00:15:22,559 --> 00:15:26,539 quien está llamando a través de esta invocación que hacemos, quien está 145 00:15:26,539 --> 00:15:30,480 llamando al método finalice. Y luego otra 146 00:15:30,480 --> 00:15:34,460 cosa que podemos probar también, mirad, antes de nada vamos 147 00:15:34,460 --> 00:15:38,279 a hacer algo más para estar seguros, aunque bueno, no parece que haya 148 00:15:38,279 --> 00:15:42,179 mucho margen de duda, pero para estar seguros que el decremento del número de personas 149 00:15:42,179 --> 00:15:46,120 se está haciendo aquí en el método finalice, podemos poner aquí un 150 00:15:46,120 --> 00:15:56,659 system.out.println, una traza, ejecutando 151 00:15:56,659 --> 00:16:00,039 vamos a poner aquí el método finalice 152 00:16:00,039 --> 00:16:10,990 vamos a ejecutar de nuevo, invocamos el recolector de basura 153 00:16:10,990 --> 00:16:16,029 pasan los tres segundos fijaros como el recolector de basura habrá llamado al finalice la clase 154 00:16:16,029 --> 00:16:24,820 persona nos ha mostrado la traza que hemos puesto aquí y luego ya pues nos muestra esta traza en la 155 00:16:24,820 --> 00:16:29,820 cual considera que hay seis personas que todavía siguen activas que son las seis que hemos dado de 156 00:16:29,820 --> 00:16:35,600 alta por aquí estas cinco y esta sexta y la séptima que habíamos dado aquí de alta como ya desapareció 157 00:16:35,600 --> 00:16:41,080 de su ámbito no está siendo considerada en el programa recolector de basura limpia la memoria 158 00:16:41,080 --> 00:16:47,539 que tenga disponible y hace la ejecución que hayamos puesto nosotros en el método finalice 159 00:16:47,539 --> 00:16:56,679 a modo de instructor del objeto una prueba más que podemos hacer para intentar yo probé en casa 160 00:16:56,679 --> 00:17:04,799 y me funcionaba si nos va también aquí es intentar forzar que se ejecute el recolector de basura pero 161 00:17:04,799 --> 00:17:15,759 sin hacer nosotros una llamada de forma explícita aquí entonces para esto lo que hice fijaros quito 162 00:17:15,759 --> 00:17:19,039 la llamada al recolector de basura, si quito la llamada al recolector de basura 163 00:17:19,039 --> 00:17:21,940 volvemos a la secuencia que estábamos antes 164 00:17:21,940 --> 00:17:24,880 en la cual el programa termina tan rápido sin que se haya 165 00:17:24,880 --> 00:17:28,180 llamado el recolector de basura que nos dará 7 aquí 166 00:17:28,180 --> 00:17:30,660 todas las veces, vamos a hacer un par de ejecuciones 167 00:17:30,660 --> 00:17:36,700 fijaros, 7, 7 y una tercera 168 00:17:36,700 --> 00:17:39,200 7 todas las veces, fijaros, por aquí 169 00:17:39,200 --> 00:17:42,400 y lo que hice fue aquí 170 00:17:42,400 --> 00:17:46,910 donde estamos dando de alta un objeto 171 00:17:46,910 --> 00:17:49,430 lo que podemos hacer es dar de alta 172 00:17:49,430 --> 00:17:52,769 pues bastantes objetos, entonces para hacer esto 173 00:17:52,769 --> 00:17:57,289 lo que podemos hacer es poner aquí un bucle 174 00:17:57,289 --> 00:17:59,990 while on for 175 00:17:59,990 --> 00:18:06,549 int i igual a cero, mientras 176 00:18:06,549 --> 00:18:10,950 i sea menor de cien, vamos a poner por ejemplo 177 00:18:10,950 --> 00:18:13,809 vamos a hacer un i más más 178 00:18:13,809 --> 00:18:27,500 disculpad la tos, estoy un poquito con la garganta ahí tocada 179 00:18:27,500 --> 00:18:30,140 entonces lo que estoy haciendo aquí es dar de alta 180 00:18:30,140 --> 00:18:32,079 100 personas, luego, bueno vamos a dar de alta 181 00:18:32,079 --> 00:18:33,559 más, vamos a dar 1000 182 00:18:33,559 --> 00:18:36,160 personas, si no, luego vemos a ver que pasa 183 00:18:36,160 --> 00:18:45,559 bueno, vamos a ver que pasa 184 00:18:45,559 --> 00:18:47,299 damos de alta 1000 personas 185 00:18:47,299 --> 00:18:49,200 que desaparecerán 186 00:18:49,200 --> 00:18:51,940 luego aquí, en este ámbito 187 00:18:51,940 --> 00:18:53,779 vamos a poner aquí un thread sleep 188 00:18:53,779 --> 00:19:03,609 que tarde un milisegundo 189 00:19:03,609 --> 00:19:05,049 para que no se nos quede colgado 190 00:19:05,049 --> 00:19:05,910 dejamos 191 00:19:05,910 --> 00:19:09,829 un milisegundo entre la ejecución de cada una de las personas 192 00:19:09,829 --> 00:19:11,730 vamos a hacer una primera prueba, noto claro 193 00:19:11,730 --> 00:19:22,369 que como he puesto el código no vaya a funcionar si no hacemos alguna variante ahora mil seis 194 00:19:22,369 --> 00:19:47,279 personas me ha dicho por aquí vamos a poner este for pero en lugar de aquí vamos a poner aquí os 195 00:19:47,279 --> 00:20:04,740 cuento ahora lo que voy a hacer va a ser llamar mil veces a este método para que dé de alta mil 196 00:20:04,740 --> 00:20:10,079 personas y desaparezcan en cada una de las llamadas está dando de alta a una persona 197 00:20:10,079 --> 00:20:14,960 y aquí vamos a poner otro bucle. En cada una de las entradas 198 00:20:14,960 --> 00:20:26,089 quede de alta mil personas. Llamamos mil veces a este método 199 00:20:26,089 --> 00:20:41,089 y cada vez da de alta mil personas. Con lo cual ya estamos dando de alta 200 00:20:41,089 --> 00:20:44,970 un millón de personas antes de que se acabe el programa. A ver si saturamos 201 00:20:44,970 --> 00:20:48,990 la memoria RAM y automáticamente como cada mil 202 00:20:48,990 --> 00:20:53,089 van quedándose liberadas porque en cada llamada las mil personas 203 00:20:53,089 --> 00:20:56,710 que damos de alta cuando llamamos aquí dejan de estar en el ámbito 204 00:20:56,710 --> 00:21:17,680 A ver si nos llama al recolector de basura. Bueno, ahí lo tenéis. Mirad, ¿veis? Ejecutando finalice. Todas las veces que está llamando mi programa al recolector de basura. Fijaros que ahora mismo el método finalice se está llamando como consecuencia de ejecución del recolector de basura. 205 00:21:17,680 --> 00:21:20,039 y al recolector de basura de forma explícita 206 00:21:20,039 --> 00:21:22,420 yo ya no lo estoy llamando, lo está llamando la máquina virtual 207 00:21:22,420 --> 00:21:24,180 y fijaros como 208 00:21:24,180 --> 00:21:25,019 al hacer 209 00:21:25,019 --> 00:21:28,339 reserva de muchos objetos 210 00:21:28,339 --> 00:21:30,460 de la clase persona que terminan su ámbito 211 00:21:30,460 --> 00:21:32,339 aquí, en cada una de las llamadas 212 00:21:32,339 --> 00:21:34,660 de las mil llamadas que hago aquí y reservo mil personas 213 00:21:34,660 --> 00:21:36,420 pues habrá un momento en el que la máquina 214 00:21:36,420 --> 00:21:38,500 virtual se dé cuenta que estamos ocupando 215 00:21:38,500 --> 00:21:40,319 mucha memoria RAM y dirá 216 00:21:40,319 --> 00:21:42,400 vamos a liberar y empezará a llamar 217 00:21:42,400 --> 00:21:44,619 al recolector de basura y ese recolector de basura 218 00:21:44,619 --> 00:21:46,519 está ejecutando el método 219 00:21:46,519 --> 00:21:53,680 finalice y cada una de estos de estas trazas que tenemos aquí de ejecutando el método finalice 220 00:21:53,680 --> 00:22:02,640 supone que una de las personas ha salido del programa y en cada una de las llamadas a método 221 00:22:02,640 --> 00:22:07,799 temporal fijaros está dejando de estar en su ámbito cuando termina hasta mil personas que 222 00:22:07,799 --> 00:22:17,829 tenemos aquí por eso nos sale en ejecutando el método finalice tantas veces en definitiva el 223 00:22:17,829 --> 00:22:24,450 método final y el recolector de basura se ejecuta cuando le viene bien a la máquina virtual de java 224 00:22:24,450 --> 00:22:32,569 la llamada al recolector de basura implica que todos los objetos del programa que dejen de ser 225 00:22:32,569 --> 00:22:39,190 operativos porque han salido de su ámbito ejecutarán su método finalice podemos tenerlo programado como 226 00:22:39,190 --> 00:22:43,390 aquí o no tenerlo programado si no lo tenemos programado en cualquier caso este método siempre 227 00:22:43,390 --> 00:22:51,490 existe pero tendremos uno heredado de la clase object de la parte de arriba que hará poca cosa 228 00:22:51,490 --> 00:23:00,440 más allá de liberar la memoria ram si nosotros desde el código queremos asegurarnos que se 229 00:23:00,440 --> 00:23:05,180 ejecuta el recolector de basura independientemente de cuando lo haga la máquina virtual tenemos a 230 00:23:05,180 --> 00:23:11,579 nuestra disposición el mes del método si éste en jefe qué bueno pues prácticamente de forma 231 00:23:11,579 --> 00:23:16,480 inmediata llama al recolector de basura y el recolector de basura ejecutará todos los finalices 232 00:23:16,480 --> 00:23:25,259 y si queremos comprobar que sea un poco queremos forzar el hecho de que se llame el recolector de 233 00:23:25,259 --> 00:23:30,019 basura a través de la máquina virtual lo podemos hacer es algo como lo que hemos hecho aquí hacer 234 00:23:30,019 --> 00:23:37,420 una reserva así bruta de objetos que desaparezcan de su ámbito de ejecución para que sean candidatos 235 00:23:37,420 --> 00:23:45,180 a que se les llame por el recolector de basura y crear muchos aquí un ford de 0 a 1000 y otros 236 00:23:45,180 --> 00:23:51,339 ford de 0 a 1000 con lo cual el programa en sí intentaría ejecutar crear un millón de objetos 237 00:23:51,339 --> 00:23:56,740 de la clase persona y como veis cuando la máquina virtual se da cuenta que empieza a ver mucho uso 238 00:23:56,740 --> 00:24:01,420 de memoria ram pues empieza a llamar el recolector de basura y el recolector de basura cada uno de 239 00:24:01,420 --> 00:24:13,880 los métodos finalice alguna cosa si alguna duda se ve se entiende si se entiende paso ya otra cosa 240 00:24:13,880 --> 00:24:22,119 yo creo que no no no no vale la pena enredar mucho más con esto porque además os digo que es un método 241 00:24:22,119 --> 00:24:31,619 que se suele utilizar más bien poco así que vale pues pues mirad más cosas que os quería contar 242 00:24:31,619 --> 00:24:41,619 normalmente cuando tenemos un método tenemos la posibilidad desde desde la llamada al método de 243 00:24:41,619 --> 00:24:48,920 recibir una respuesta desde donde se está llamando a cómo ha ido la ejecución vamos a volver al 244 00:24:50,140 --> 00:24:53,039 por ejemplo a esta prueba que habíamos abierto antes 245 00:24:53,039 --> 00:24:55,700 o no sé, bueno 246 00:24:55,700 --> 00:24:58,039 vamos a crear un nuevo proyecto 247 00:24:58,039 --> 00:25:25,099 teoría, vale pues ahí tenemos la clase 248 00:25:25,099 --> 00:25:30,990 de teoría, vamos a meter en main 249 00:25:30,990 --> 00:25:40,069 mirad cuando 250 00:25:40,069 --> 00:25:42,329 definimos métodos 251 00:25:42,329 --> 00:25:47,440 tenemos la posibilidad de decir que este 252 00:25:47,440 --> 00:25:48,960 método devuelva algo y esto 253 00:25:48,960 --> 00:25:51,640 que devuelva algo más allá de los constructores 254 00:25:51,640 --> 00:25:53,819 que no devuelven nada pero no lo indicamos 255 00:25:53,819 --> 00:25:55,440 si no devuelve nada 256 00:25:55,440 --> 00:25:57,619 ponemos un void y si devuelve algo 257 00:25:57,619 --> 00:25:58,819 ponemos por ejemplo int 258 00:25:58,819 --> 00:26:00,619 devuelve 259 00:26:00,619 --> 00:26:08,299 int, vamos a poner aquí, vamos a llamar al método, entonces tenemos aquí 260 00:26:08,299 --> 00:26:12,140 que por aquí podríamos recibir parámetros 261 00:26:12,140 --> 00:26:15,819 de como devuelve algo, se nos queja porque no tiene un return 262 00:26:15,819 --> 00:26:21,210 vamos a poner un 1 de momento, vale, ya nos compila 263 00:26:21,210 --> 00:26:25,269 tenemos desde en la zona donde llamemos al método, tenemos la posibilidad de 264 00:26:25,269 --> 00:26:29,289 pasarle información que tenemos aquí disponible a través de 265 00:26:29,289 --> 00:26:33,230 los parámetros de entrada, como ya conocemos, y tenemos la posibilidad de que 266 00:26:33,230 --> 00:26:36,569 tras su ejecución, disponer de cierta información 267 00:26:36,569 --> 00:26:39,309 de cómo ha ido la ejecución, por ejemplo, este 1 que estamos haciendo aquí 268 00:26:39,309 --> 00:26:42,470 un return, en el método desde donde se está 269 00:26:42,470 --> 00:26:45,230 llamando, en este caso el main, para seguir procesándolo. 270 00:26:45,369 --> 00:26:48,269 Por ejemplo, podría ser que si devuelve 0 es que ha ido bien la ejecución, 271 00:26:48,410 --> 00:26:51,009 si devuelve 1 es que se ha dado un error en el acceso a un fichero. 272 00:26:51,349 --> 00:26:54,289 Pondríamos return 0 o return 1 según haya ido 273 00:26:54,289 --> 00:26:56,549 la ejecución esta, que haya sido correcta o con ese 274 00:26:56,549 --> 00:26:59,609 error que comentábamos al acceso al fichero. 275 00:26:59,609 --> 00:27:09,220 fijaros que la posibilidad de devolver aquí algo bueno pues es un poco escasa porque imaginaos que 276 00:27:09,220 --> 00:27:19,440 en el método quisiéramos devolver dos cosas vamos a llamar este método recoger info por ejemplo y 277 00:27:19,440 --> 00:27:29,250 imaginaros que estamos recogiendo una edad de una persona y un nombre pues vale pues entonces aquí 278 00:27:29,250 --> 00:27:37,410 podríamos devolver un es un entero que fuese la edad o podríamos devolver un string que fuese el 279 00:27:37,410 --> 00:27:43,109 nombre pero a la vez no podemos decir que devuelva las dos cosas como podríamos saber qué podríamos 280 00:27:43,109 --> 00:27:49,410 hacer aquí pues fijaros aquí lo que podríamos hacer es si tenemos que esa información se la 281 00:27:49,410 --> 00:27:58,259 vamos a meter a un objeto por ejemplo de una clase persona una clase persona aquí esta persona que 282 00:27:58,259 --> 00:28:09,859 tenga precisamente esto que decimos y edad como atributos tiene ese nombre una primera cosa que 283 00:28:09,859 --> 00:28:15,740 podríamos hacer sería decir que devuelva un objeto de la clase persona pero si devuelve un objeto de 284 00:28:15,740 --> 00:28:29,509 la clase persona aquí podríamos decir que podríamos dar de alta una persona persona ni per igual año 285 00:28:29,509 --> 00:28:39,000 persona, decir mi per 286 00:28:39,000 --> 00:28:43,740 imaginaos que lo cogemos desde teclado como fuese, no vamos a entrar ahora con el 287 00:28:43,740 --> 00:28:47,380 escáner, pero bueno, de alguna forma recogeríamos la edad, 10 años 288 00:28:47,380 --> 00:28:50,480 mi per punto ese nombre 289 00:28:50,480 --> 00:28:54,420 y decir que esta persona, por ejemplo, se llama Noah 290 00:28:54,420 --> 00:28:58,839 y luego aquí haríamos un return de mi per 291 00:28:58,839 --> 00:29:02,900 fijaros como esto, bueno, pues va bien la cosa 292 00:29:02,900 --> 00:29:09,259 devuelve un objeto de la clase persona definimos mi per como un objeto de la clase persona hemos 293 00:29:09,259 --> 00:29:13,559 trabajado a por aquí con el algoritmo para que sería a través de escáner o como correspondiese 294 00:29:13,559 --> 00:29:19,099 para esos datos rellenar sus atributos y luego que devolvemos un objeto de la clase persona que 295 00:29:19,099 --> 00:29:26,930 efectivamente es lo que se espera aquí aquí si queremos trabajar con esta persona pues que 296 00:29:26,930 --> 00:29:33,869 podríamos hacer pues fijaros podremos y decir persona per aus de alguna forma fijaros que aquí 297 00:29:33,869 --> 00:29:42,630 no voy a hacer un new porque porque mi idea es que ahora voy a llamar a recoger info este se hará un 298 00:29:42,630 --> 00:29:49,950 new verdad reservará en la zona de memoria ram un espacio para guardar la edad y el nombre vamos a 299 00:29:49,950 --> 00:29:56,470 suponer que es en la memoria ram la posición la que le diga el sistema operativo 35.000 por decir 300 00:29:56,470 --> 00:30:02,470 una que será la que la que decía el sistema operativo y en este reto lo que estoy haciendo 301 00:30:02,470 --> 00:30:09,369 devolver esta posición de memoria que corresponde a un objeto de la clase persona aquí en la posición 302 00:30:09,369 --> 00:30:22,750 35.000 habrá hecho una reserva de espacio suficiente para guardar edad y nombre con lo 303 00:30:22,750 --> 00:30:27,390 cual irá desde la 35.000 y vamos a hacer una suposición será hasta la posición que sea 304 00:30:27,390 --> 00:30:32,490 Vamos a suponer que desde la 35.000 hasta la 35.050, por decir algo. 305 00:30:34,130 --> 00:30:38,890 Entonces, aquí cogemos, definimos una referencia, un dedito que apunta a una persona, 306 00:30:39,089 --> 00:30:43,269 pero no hacemos el new, con lo cual no estamos reservando espacio de memoria para esta persona. 307 00:30:43,849 --> 00:30:51,420 Aquí lo que diríamos sería que per aus sea igual, vamos a definir este método static, 308 00:30:51,880 --> 00:30:53,779 porque lo estamos llamando desde main que es static, 309 00:30:53,779 --> 00:30:58,480 para no tener necesidad de estar creando objetos de la clase tutoría. 310 00:30:58,759 --> 00:31:11,960 Si no, lo podemos hacer también de la otra forma en un momento dado, pero bueno, pues decimos recoger info, llevamos al método este y si lo pongo bien, igual compila, ahí está. 311 00:31:12,680 --> 00:31:21,000 Entonces, ¿qué es lo que hará esto? Esto que no tiene una reserva de memoria, en principio ese dedito hacia una persona apunta a nul, a nada. 312 00:31:21,000 --> 00:31:28,579 lo que estamos haciendo es decir que sea igual a lo que devuelva este método y este método tiene 313 00:31:28,579 --> 00:31:35,240 una referencia a una persona a la que le hemos dado estos dos valores que hemos hecho la suposición 314 00:31:35,240 --> 00:31:41,240 de que el sistema operativo ha dicho que apunta a 35.000 con lo cual de esta forma per aus pasa a 315 00:31:41,240 --> 00:31:50,480 tener la posición de memoria ram 35.000 con lo cual per aus punto y edad es previsible que nos 316 00:31:50,480 --> 00:31:58,460 devuelva un 10 y per aus ese nombre nos devuelva no si cogemos hacemos aquí un sistema punto out 317 00:31:58,460 --> 00:32:38,609 punto println de per aus punto y edad más tenemos esta ejecución fijaros como el programa nos muestra 318 00:32:38,609 --> 00:32:45,329 edad 10 y nombre no estamos utilizando per aus que en verdad es algo que es capaz de apuntar 319 00:32:45,329 --> 00:32:47,049 una persona, para este no hemos hecho el new 320 00:32:47,049 --> 00:32:49,069 pero hemos aprovechado que 321 00:32:49,069 --> 00:32:51,349 hemos hecho que per aus apunta al mismo sitio 322 00:32:51,349 --> 00:32:53,450 donde apuntaba mi per 323 00:32:53,450 --> 00:32:55,190 es algo parecido a lo que hacemos 324 00:32:55,190 --> 00:32:56,529 con el constructor copia 325 00:32:56,529 --> 00:32:59,470 hacer que apunten unos registros a otros 326 00:32:59,470 --> 00:33:04,460 veis esta asociación 327 00:33:04,460 --> 00:33:06,180 de posiciones de memoria 328 00:33:06,180 --> 00:33:07,740 que permite que per aus 329 00:33:07,740 --> 00:33:10,180 y que mi per apunten a la misma 330 00:33:10,180 --> 00:33:22,970 persona, bueno 331 00:33:22,970 --> 00:33:24,970 estarían repetidas, si, sería 332 00:33:24,970 --> 00:33:27,309 todas las referencias a objetos 333 00:33:27,309 --> 00:33:33,730 todo habría un montón de deditos que los hemos definido como referencias a personas y todos 334 00:33:33,730 --> 00:33:39,289 ellos estarían apuntando a la misma posición de memoria con lo cual sería sería la misma 335 00:33:39,289 --> 00:33:47,009 información vendría a ser mira aquí por ejemplo aquí pero ahora mismo ya apunta a 35.000 pues 336 00:33:47,009 --> 00:33:56,789 si nosotros cogemos y hacemos aquí persona per aus dos que sea igual a per aus fijaros que no 337 00:33:56,789 --> 00:34:00,829 estoy diciendo, no estoy haciendo un new para esta persona, con lo cual estoy 338 00:34:00,829 --> 00:34:04,369 definiendo un dedito que apunta a una persona, un puntero, un indicador 339 00:34:04,369 --> 00:34:09,010 y le decimos, si esto lo partimos en dos instrucciones y lo ponemos así 340 00:34:09,010 --> 00:34:12,710 aquí apuntaría null, lo juntamos, vale 341 00:34:12,710 --> 00:34:16,929 y al igualarlo a este, pues pasará a apuntar también a la 342 00:34:16,929 --> 00:34:21,070 zona de memoria RAM donde está apuntando peraus, que además lo ha recogido 343 00:34:21,070 --> 00:34:25,050 de cuando hicimos este new, con lo cual también apuntaría a ese supuesto 344 00:34:25,050 --> 00:34:31,469 35.000 que será el que sea vale según el sistema operativo entonces si cogemos aquí hacemos esto 345 00:34:31,469 --> 00:34:40,530 y ahora aquí ponemos pero los dos veremos que también no vuelva a sacar los mismos datos pero 346 00:34:40,530 --> 00:34:48,670 espera los dos y miper los tres apuntan al mismo sitio ambos dos dicen esto en verdad cuando 347 00:34:48,670 --> 00:34:55,289 estamos ejecutando este código esta referencia ya ha desaparecido ha desaparecido con lo cual 348 00:34:56,489 --> 00:35:12,570 Aquí tendríamos solamente dos personas activas, que serían esta y esta. Este ya habría dejado de apuntar al 35.000, fijaros que ha salido de su ámbito de ejecución, y estas dos seguirían en su ámbito de ejecución, que es el main, con lo cual sí que estarían activas. 349 00:35:12,570 --> 00:35:28,570 Si pasase el recolector de basura, ¿qué sucedería? Pues no se ejecutaría ningún finalice a pesar de que éste ha salido de su referencia porque la posición de memoria a la que estaba asociado éste todavía continúa referenciada por estos dos punteros. 350 00:35:28,570 --> 00:35:33,670 dos punteros cuando pasa del recolector de basura enlazando con lo que comentábamos antes cuando hay 351 00:35:33,670 --> 00:35:40,590 una zona de memoria a la cual no apunta ya nadie aunque mientras siga apuntando a alguien a esa 352 00:35:40,590 --> 00:35:46,090 zona de memoria porque sigue disponible esa persona aunque no sea la que inicialmente se 353 00:35:46,090 --> 00:35:50,989 utilizó para hacer el new el recolector de basura no lo considera para liberar esa memoria porque 354 00:35:50,989 --> 00:35:56,230 si lo llamase aquí el recolector de basura y se perdiese la persona de 35.000 aquí dejaríamos de 355 00:35:56,230 --> 00:36:02,010 tenerla disponible entonces mientras haya alguien que esté apuntando a esa zona de memoria continuará 356 00:36:02,010 --> 00:36:06,250 funcionando y si el recolector de basura ni liberará la memoria ni llamará al finalice 357 00:36:06,250 --> 00:36:18,500 bueno entonces una posibilidad de devolver más de un valor a través de un método antes estábamos 358 00:36:18,500 --> 00:36:24,119 contraponiendo lo a lo que decíamos antes cuando habíamos definido el método este y habíamos dicho 359 00:36:24,119 --> 00:36:30,579 que hiciera un retorno en lugar de esto habíamos dicho un índice decíamos aquí solamente devuelve 360 00:36:30,579 --> 00:36:36,059 el la edad si ponemos un string solamente devuelve el nombre no podemos devolver los 361 00:36:36,059 --> 00:36:44,960 dos pues una técnica es si tenemos una clase en la cual tenemos varios atributos lo que devolvemos 362 00:36:44,960 --> 00:36:52,659 es una referencia a un objeto de esa clase y podremos cargarlos con varios datos y luego 363 00:36:52,659 --> 00:37:00,159 tenemos si tenéis dudas o no se entiende me decís vale que esto a las hablar de la memoria a veces 364 00:37:00,159 --> 00:37:06,219 cuesta siempre un poco entonces mejor dejarlo claro aunque avancemos menos pero que lo que 365 00:37:06,219 --> 00:37:17,260 avancemos pues que os vayáis enterando bien pero imaginaros que decimos esto me parece muy bien que 366 00:37:17,260 --> 00:37:23,639 aquí devuelvas un objeto una persona pero es que yo quiero que el método recoger info me devuelva 367 00:37:23,639 --> 00:37:28,380 si la ejecución de este método ha ido bien, yo quiero que me devuelva un código numérico 368 00:37:28,380 --> 00:37:35,630 vamos a hacer otro método, diciendo que esto devuelva 369 00:37:35,630 --> 00:37:44,719 un entero, int, con lo cual 370 00:37:44,719 --> 00:37:48,960 si llega hasta aquí, la ejecución, que me devuelva un 0, o me devuelva 371 00:37:48,960 --> 00:37:52,980 si ha habido un error en un momento dado, que me devuelva un 1, o otro tipo de error, un 2 372 00:37:52,980 --> 00:37:56,559 es decir, quiero un código de errores numérico 373 00:37:56,559 --> 00:38:00,340 y que me lo devuelva a través del return, en este caso, lo que haríamos sería 374 00:38:00,340 --> 00:38:14,679 poner hacer la llamada a recoger info 2 en este caso y se lo cargaríamos y valor devuelto 375 00:38:16,380 --> 00:38:21,960 a una variable de qué tipo tiene que esta variable de tipo entero porque porque hemos dicho que lo 376 00:38:21,960 --> 00:38:27,679 devuelve que lo que devuelve es un entero como devuelve este método es entero a través de la 377 00:38:27,679 --> 00:38:47,539 instrucción retour. Aquí estamos poniéndolo a pelo que sea un 0, pero aquí, en función de diferentes cosas que pudiera hacer, se podrían dar diferentes errores y que en diferentes momentos devolviese un 1 que sería un error de acceso a fichero, un 2 que fuese un error de lo que fuese, según el algoritmo que estemos implementando. 378 00:38:47,539 --> 00:39:05,980 Y si queremos, además de tener un código de cómo ha ido la ejecución que lo estamos devolviendo aquí, si queremos tener información de, oye, esto está bien, pero yo me gustaría también que este método me devolviese el nombre y la edad de una persona. 379 00:39:05,980 --> 00:39:19,199 ¿Cómo podríamos hacerlo? Pues mira, lo que podemos hacer en ese caso es aprovechar un truquillo aquí como parámetro de entrada y pasarle una referencia a una persona. 380 00:39:19,199 --> 00:39:28,280 Entonces decimos persona, vamos a llamarlo miPer aquí y voy a quitarla de aquí. 381 00:39:35,809 --> 00:39:40,929 Entonces lo que podemos hacer aquí es coger y antes de la llamada definir una persona, 382 00:39:41,429 --> 00:39:45,489 persona per tercera. 383 00:39:47,389 --> 00:39:51,469 En este caso sí que hago una reserva de memoria, new persona. 384 00:39:51,469 --> 00:39:57,760 entonces aquí estoy haciendo definiendo una persona 385 00:39:57,760 --> 00:40:01,139 per tercera y vamos a suponer que 386 00:40:01,139 --> 00:40:03,920 como estoy haciendo un new, el sistema operativo me devuelve 387 00:40:03,920 --> 00:40:06,780 una zona de memoria donde reservar espacio 388 00:40:06,780 --> 00:40:09,800 para esta tercera persona, vamos a suponer que es la posición 389 00:40:09,800 --> 00:40:12,820 40.000, ya os digo que esto es simplemente 390 00:40:12,820 --> 00:40:15,840 para seguir con el ejemplo y hablar de una referencia 391 00:40:15,840 --> 00:40:18,480 de memoria RAM que será la que sea, la que es el sistema operativo 392 00:40:18,480 --> 00:40:21,860 esta tercera persona la pasamos 393 00:40:21,860 --> 00:40:24,099 por aquí como atributo, fijaros como 394 00:40:24,099 --> 00:40:31,099 como parámetro fijaros como este método recibe un objeto una referencia un objeto de la clase 395 00:40:31,099 --> 00:40:41,579 persona qué referencia es esta per tercera que es lo que valdrá per tercera punto y edad de momento 396 00:40:41,579 --> 00:40:47,039 valdrá cero porque no hemos dado valores y p tercera punto ese nombre valdrá comillas comillas 397 00:40:47,039 --> 00:40:55,579 está inicializado las dos variables probablemente pero eso es punto y edad y punto ese nombre pero 398 00:40:55,579 --> 00:41:00,980 per tercera que vale una posición de memoria 40.000 qué es lo que pasa cuando le pasamos 399 00:41:00,980 --> 00:41:08,000 parámetros a información a través de los parámetros de entrada a un método que la 400 00:41:08,000 --> 00:41:14,940 información que tiene aquí se copia aquí si aquí cogemos y le pasamos por poner un segundo 401 00:41:14,940 --> 00:41:27,800 parámetro que nos resulte más familiar, ponemos int p, pues resulta que este 2, ¿verdad?, se copia en el primero 402 00:41:27,800 --> 00:41:35,239 de los atributos en la p, con lo cual p valdrá 2. ¿Qué sucede con mi per, que es una referencia, un puntero, 403 00:41:35,280 --> 00:41:41,840 una clase persona? Pues que cogerá el valor que le estamos pasando, entonces aquí, que será el valor que tenga 404 00:41:41,840 --> 00:41:47,900 per tercera, entonces aquí en el momento de ejecutar para estas dos variables que se reciben como parámetros 405 00:41:47,900 --> 00:41:56,079 y actúan como variables locales dentro de este método, resulta que lo que tenemos es que p será igual a 2, 406 00:41:56,360 --> 00:42:00,960 no vamos a utilizar p, pero bueno, lo he puesto por poner un segundo parámetro diferente al de persona, 407 00:42:00,960 --> 00:42:12,280 y mi per será igual a 40.000. 40.000 vale mi per porque 40.000 hemos supuesto que es la zona de memoria 408 00:42:12,280 --> 00:42:17,840 que ha asignado a la referencia per tercera a través del new del sistema operativo. 409 00:42:17,900 --> 00:42:23,679 entonces y ahora pongo yo aquí mi per y edad sobre qué edad estará actuando 410 00:42:23,679 --> 00:42:27,579 sobre la edad relacionada con un objeto de la clase persona 411 00:42:27,579 --> 00:42:31,599 que en la memoria RAM está siendo apuntada por mi per 412 00:42:31,599 --> 00:42:36,280 mi per es 40.000 y de la misma forma para un nombre 413 00:42:36,280 --> 00:42:43,460 para una variable nombre que forma parte de los atributos de una clase persona 414 00:42:43,460 --> 00:42:45,360 que está siendo apuntada por mi per 415 00:42:45,360 --> 00:42:50,679 que en memoria RAM, según hemos visto, está en la posición 40.000. 416 00:42:51,420 --> 00:42:55,300 Aquí devolvemos un return cero, que se devuelve por aquí y se carga aquí, ¿verdad? 417 00:42:56,320 --> 00:43:05,239 Pues perfectamente, ahora podríamos decir aquí, if evalDef es igual a cero, 418 00:43:05,239 --> 00:43:09,820 según el código que tengamos definido, pues aquí podríamos hacer una serie de cosas 419 00:43:09,820 --> 00:43:12,139 como que la ejecución de este método ha ido bien. 420 00:43:12,139 --> 00:43:27,019 Y si es distinto de cero, pues a lo mejor podríamos decir, pues se ha producido un determinado error. Si aquí hacemos returns diferentes a este que hemos puesto única y exclusivamente, de valores diferentes de cero para posibles errores que se puedan ir dando. 421 00:43:27,019 --> 00:43:52,159 Con lo cual aquí tenemos la gestión de un código error del método y otra cosa que en principio nos interesaba tener era información que íbamos a ir cargando por ejemplo en este método recoger info2 que podría ser a través de teclado con escáner o a través de quien correspondiese y queríamos tenerlo disponible desde el método llamante y lo cargábamos aquí. 422 00:43:52,159 --> 00:43:59,599 pues efectivamente lo tenemos en mi per y edad mi per ese nombre aquí que apuntaba al 40.000 423 00:43:59,599 --> 00:44:07,159 una vez que termina esto, este punterito que apunta a memoria rana a la posición 40.000 424 00:44:07,159 --> 00:44:13,199 ya no tiene sentido porque su ámbito de ejecución, estas variables hemos dicho que actúan como locales al método 425 00:44:13,199 --> 00:44:18,400 dejará de existir esta referencia, pero a partir de la ejecución cuando llegamos aquí 426 00:44:18,400 --> 00:44:30,539 sí que permanece per tercera disponible en la posición 40.000 porque el ámbito de ejecución de per tercera es el método main, 427 00:44:30,659 --> 00:44:32,099 con lo cual por aquí sigue disponible. 428 00:44:32,860 --> 00:44:46,860 Entonces si hacemos un system.out.println de per tercera, voy a hacerlo más rápido, voy a hacer un copy y pega de esto, 429 00:44:46,860 --> 00:45:03,789 y aquí decimos per tercera, vamos a poner aquí esto para distinguerlo de los otros mensajes, 430 00:45:05,150 --> 00:45:09,070 desejecutamos y fijaros como me dice que la edad es 10 y que el nombre es no A, 431 00:45:09,670 --> 00:45:13,250 es decir, hemos hecho una pequeña trampa a través de un parámetro de entrada, 432 00:45:14,969 --> 00:45:20,190 aprovechando que lo que se pasa es la referencia, la memoria RAM, cuando pasamos referencias a objetos, 433 00:45:20,969 --> 00:45:24,349 para modificarlo aquí, que era donde correspondía recoger la información, 434 00:45:24,349 --> 00:45:38,070 Ya os digo, aquí podríamos haber recogido esa edad y ese nombre en lugar de ponerlo así con escáner o leyéndolo de un fichero o a través de unos determinados cálculos, lo que nos dijese el algoritmo y luego lo tenemos disponible aquí. 435 00:45:38,710 --> 00:45:53,429 De alguna forma es como que tenemos información de salida del método a través de un parámetro de entrada aprovechando la característica de que lo que se pasa es la posición de memoria donde nos ha dado el sistema operativo espacio para este objeto. 436 00:45:53,429 --> 00:46:35,179 Sí, mira, bueno, para la grabación me preguntaba qué es lo que se relaciona entre per tercera y mi per, en realidad. Cuando estamos pasando información a través de parámetros de entrada a un método, la información que tienen estos parámetros de entrada se copian como variables locales al método en estas variables. 437 00:46:35,179 --> 00:46:41,880 este que es un entero pues que copian esta variable p se copia un 2 con lo cual p vale 2 438 00:46:42,940 --> 00:46:49,300 per tercera que es lo que vale pues per tercera vale una zona de memoria imaginaos que el sistema 439 00:46:49,300 --> 00:46:55,239 operativo al hacer este niño como siempre ha dicho a partir de la posición 40.000 de memoria ram 440 00:46:55,239 --> 00:47:02,179 tengo suficiente espacio como para reservar trocitos y meter las variables de la edad y 441 00:47:02,179 --> 00:47:04,900 el nombre de esta persona que está 442 00:47:04,900 --> 00:47:06,880 dando de alta. Entonces vamos a suponer que en el 443 00:47:06,880 --> 00:47:08,440 mismo 40.000 444 00:47:08,440 --> 00:47:10,440 está 445 00:47:10,440 --> 00:47:13,099 a partir de esa posición, que es donde empieza 446 00:47:13,099 --> 00:47:15,000 el espacio que ha reservado en memoria 447 00:47:15,000 --> 00:47:16,619 RAM, es donde metemos la edad 448 00:47:16,619 --> 00:47:18,619 y vamos a suponer, 449 00:47:18,840 --> 00:47:21,000 no me acuerdo exactamente de qué espacio ocupa 450 00:47:21,000 --> 00:47:22,920 un entero, pero vamos por hacer una 451 00:47:22,920 --> 00:47:25,000 suposición también, que a partir del 40.020 452 00:47:25,659 --> 00:47:26,960 es donde 453 00:47:26,960 --> 00:47:29,179 se puede meter el nombre. 454 00:47:33,150 --> 00:47:34,130 Si tú coges y haces 455 00:47:34,130 --> 00:47:34,670 ahora aquí 456 00:47:34,670 --> 00:47:36,869 un 457 00:47:36,869 --> 00:47:40,289 un system of println 458 00:47:40,289 --> 00:47:47,000 como este, cuando 459 00:47:47,000 --> 00:47:49,119 vaya de la 460 00:47:49,119 --> 00:47:51,019 edad de la per tercera, cuando vaya 461 00:47:51,019 --> 00:47:52,460 aquí, se irá a la posición 462 00:47:52,460 --> 00:47:55,239 empieza aquí el objeto 463 00:47:55,239 --> 00:47:56,920 persona, la edad justo 464 00:47:56,920 --> 00:47:59,019 en el punto donde empieza, pues irá a la posición 465 00:47:59,019 --> 00:48:01,199 40.000, cogerá el valor del entero 466 00:48:01,199 --> 00:48:02,239 que hay ahí y lo mostrará aquí 467 00:48:02,239 --> 00:48:05,059 y cuando mostramos aquí per tercera 468 00:48:05,059 --> 00:48:06,900 ese nombre, pues irá, dirá, vale 469 00:48:06,900 --> 00:48:12,840 El 40.000, per tercera, empieza en la posición de memoria RAM 40.000. 470 00:48:13,199 --> 00:48:17,420 Lo desplazo, lo que me ocupa un entero, que hemos hecho un supuesto de que es 20, ¿vale? 471 00:48:17,880 --> 00:48:21,000 Y entonces me voy al 40.020, que es donde está el nombre, 472 00:48:21,000 --> 00:48:25,139 y apoyándome en el 40.020, muestro el nombre que tenga. 473 00:48:25,800 --> 00:48:29,440 Aquí, como no lo hemos modificado, todavía mostraría cero y comillas, comillas. 474 00:48:32,250 --> 00:48:35,630 Como aquí lo que pasamos es la información que tiene, 475 00:48:36,170 --> 00:48:38,269 la información que tiene se copia en el método, 476 00:48:38,730 --> 00:48:51,949 Este 2 se copia en el primer atributo, el primer parámetro que tiene aquí, la p valdrá 2 y esta referencia que es un punterito hacia una persona, ¿qué valor cogerá? Pues el que le estamos pasando aquí. ¿Qué valor le estamos pasando aquí? 40.000. 477 00:48:51,949 --> 00:48:54,389 entonces mi per 478 00:48:54,389 --> 00:48:55,909 valdrá 479 00:48:55,909 --> 00:48:57,949 posición de memoria 40.000 480 00:48:57,949 --> 00:49:00,170 donde debe haber una reserva para una 481 00:49:00,170 --> 00:49:02,190 persona, entonces cuando yo pongo aquí 482 00:49:02,190 --> 00:49:04,150 mi per punto y edad 483 00:49:04,150 --> 00:49:06,210 pues irá a la posición de memoria RAM 484 00:49:06,210 --> 00:49:07,949 40.000 y 485 00:49:07,949 --> 00:49:10,090 con el desplazamiento de la edad que es lo 486 00:49:10,090 --> 00:49:12,010 primero en la posición 40.000 487 00:49:12,010 --> 00:49:15,940 40.000 que es 488 00:49:15,940 --> 00:49:17,739 hiper, mi per 489 00:49:17,739 --> 00:49:19,659 que coincide 490 00:49:19,659 --> 00:49:21,619 con 491 00:49:21,619 --> 00:49:26,900 per tercera, porque es el valor que se ha copiado aquí 492 00:49:26,900 --> 00:49:29,960 como parámetro de entrada, más 493 00:49:29,960 --> 00:49:31,639 el desplazamiento 494 00:49:31,639 --> 00:49:35,179 de la edad, que hemos supuesto 495 00:49:35,179 --> 00:49:38,239 que la edad justo está en la misma posición 496 00:49:38,239 --> 00:49:41,280 parte del mismo punto en el que hemos reservado la memoria 497 00:49:41,280 --> 00:49:44,320 pues en la posición 40.000 de la memoria RAM 498 00:49:44,320 --> 00:49:47,219 está metiendo un 10, en la pos 499 00:49:47,219 --> 00:49:50,139 40.000 está metiendo 500 00:49:50,139 --> 00:49:53,039 un valor 10 con esta asignación 501 00:49:53,059 --> 00:50:14,760 Por su parte, para el nombre, dice, a partir de la posición 40.000, que es donde apunta mi PER, que coincide con PER tercera, por esta copia, como os digo, en la llamada PER tercera, que estaba en 40.000, lo que quiero meter es el nombre. 502 00:50:14,760 --> 00:50:30,360 Y el desplazamiento del nombre es 40.000, que es donde está mi per, y hemos dicho que para el nombre por aquí habíamos supuesto que hacía un desplazamiento dejando el espacio para que se metiera la edad, que era 20. 503 00:50:30,360 --> 00:50:52,929 Entonces, entendemos que en la posición 40.020 de la memoria RAM es donde está poniendo, aquí se acaba el programa, se termina, esta referencia por ser una variable local desaparece, pero gracias a esta referencia hemos metido en la posición 40.010 y en la 40.020 no va. 504 00:50:53,289 --> 00:51:19,329 Si llegamos ahora por aquí, después de la ejecución esta, y nos venimos aquí, per tercera, aquí sí que sigue existiendo. ¿Por qué? Porque per tercera está definida en el ámbito del main. ¿Dónde apunta per tercera? A 40.000. Si yo imprimo per tercera y edad, ¿dónde está puesta? Si hemos dicho que la edad no tiene desplazamiento desde donde apunta per tercera, pues a la posición 40.000. Y en la posición 40.000, ¿qué pone? Un 10, que es el valor que le hemos dado aquí. 505 00:51:19,329 --> 00:51:26,829 por eso al imprimir aquí per tercera y edad nos saca este 10 y cuando imprimimos esto pues hemos 506 00:51:26,829 --> 00:51:32,449 dicho que per tercera apunta a la posición 40.020 que justo coincide con la 40.020 donde habíamos 507 00:51:32,449 --> 00:51:38,030 puesto no a y todo es consecuencia de que mi per es un puntero que está apuntando al mismo sitio 508 00:51:38,030 --> 00:51:50,570 que per tercera que hemos definido aquí entonces por eso este nombre me muestra no no sé si aclara 509 00:51:50,570 --> 00:52:09,070 vale pues nada esto es una posibilidad de en conclusión lo que hay que tener claro es que 510 00:52:09,070 --> 00:52:17,869 como principio es que esta variable está apuntando al mismo sitio donde estaba apuntando está por lo 511 00:52:17,869 --> 00:52:22,030 cual son dos deditos que apuntan a la misma posición de memoria los cambios que hagan una 512 00:52:22,030 --> 00:52:32,840 pues se aplicarán a la otra fijaros un poco redundando ya por un poco más en las posiciones 513 00:52:32,840 --> 00:52:41,989 de memoria quizás como previo a todo lo que os he contado aunque lo cuenta ahora después imaginaos 514 00:52:41,989 --> 00:52:59,840 que tenemos una persona pero una persona este perú no digo y edad que tenga 20 años ahora digo persona 515 00:52:59,840 --> 00:53:29,639 per 2 igual a per 1 falta el igual aquí si yo pongo aquí un system out lógicamente esto me 516 00:53:29,639 --> 00:53:34,800 sacará un 20 no con este código define una persona le pongo que tenga de valor 20 y le digo con 20 517 00:53:34,800 --> 00:53:40,739 pues ya está lógicamente sacar un 1 dentro de nuestras suposiciones del sistema operativo pero 518 00:53:40,739 --> 00:53:47,219 no vamos a entender que va nos ha dado espacio en la memoria ram de la posición 40.000 o la 519 00:53:47,219 --> 00:53:49,260 50.000, por decir una diferente a la de antes. 520 00:53:52,280 --> 00:53:53,659 ¿Por qué nos ha dado una zona 521 00:53:53,659 --> 00:53:55,539 de memoria reservada? Porque le hemos hecho un new. 522 00:53:56,300 --> 00:53:57,659 Si no le hacemos un new, no nos da 523 00:53:57,659 --> 00:53:58,880 una zona de memoria reservada. 524 00:53:59,400 --> 00:54:01,199 Si aquí yo cogiese e hiciese esto, 525 00:54:09,449 --> 00:54:11,010 ¿aquí qué estaríamos haciendo? Pues mirad, 526 00:54:11,269 --> 00:54:13,070 aquí, por ejemplo, bajo nuestro supuesto 527 00:54:13,070 --> 00:54:15,250 estaría per 1 apuntando a 50.000 528 00:54:15,250 --> 00:54:17,309 y aquí 529 00:54:17,309 --> 00:54:18,829 estamos haciendo otro new, 530 00:54:19,010 --> 00:54:21,130 pues buscaría en memoria RAM y diría 531 00:54:21,130 --> 00:54:22,630 que per 1 apunte ya 532 00:54:22,630 --> 00:54:25,130 a otro espacio, a 55.000. 533 00:54:25,130 --> 00:54:30,300 perderíamos la referencia de este per1. 534 00:54:30,400 --> 00:54:33,880 Si aquí pusiésemos per1 igual a 20, 535 00:54:35,079 --> 00:54:37,159 si hacemos esto, perdemos cualquier referencia 536 00:54:37,159 --> 00:54:40,159 porque ya no tenemos nada que esté apuntando a per1. 537 00:54:41,619 --> 00:54:45,400 No tendríamos la posibilidad de mostrar por pantalla este 20. 538 00:54:46,519 --> 00:54:50,440 Si per1 apunta a 50.000 y le damos un valor a la edad de 20, 539 00:54:51,699 --> 00:54:55,980 si per1 lo sobreescribimos y le damos otra posición de memoria, 540 00:54:55,980 --> 00:54:58,320 le da otra posición de memoria al sistema operativo 541 00:54:58,320 --> 00:54:59,460 porque le estamos haciendo otro new 542 00:54:59,460 --> 00:55:02,599 ¿qué posibilidad tenemos de recuperar este valor? 543 00:55:02,760 --> 00:55:04,519 si lo único que teníamos para llegar a la edad 544 00:55:04,519 --> 00:55:07,099 era que per 1 apuntaba a 50.000 545 00:55:07,099 --> 00:55:08,500 lo habríamos perdido 546 00:55:08,500 --> 00:55:12,019 en cambio si hacemos esto, fijaros 547 00:55:12,019 --> 00:55:16,860 ahora per 2 548 00:55:16,860 --> 00:55:18,739 ¿a dónde estaría apuntando? 549 00:55:19,219 --> 00:55:20,099 a per 1 550 00:55:20,099 --> 00:55:21,860 per 2, ¿dónde estaría apuntando? 551 00:55:22,039 --> 00:55:23,400 a 50.000 552 00:55:23,400 --> 00:55:30,380 si hacemos un per 1 new 553 00:55:30,380 --> 00:55:33,139 este per 1 lo perdemos 554 00:55:33,139 --> 00:56:07,199 que es al que habíamos aplicado 20, ¿por qué? porque nos dará otra posición de memoria, si ahora nosotros hacemos aquí un system.out.println, bueno este, este que tenemos aquí, vamos a poner aquí, antes de poner un persona1, fijaros como persona1 me dice que vale 0, ¿por qué? 555 00:56:07,199 --> 00:56:22,579 Aquí le había asignado el valor 20, es cierto, pero era un 20 que estaba colgando de 50.000. Con este nuevo new ya no apunta al 50.000, hemos supuesto que es al 55.000 y las variables enteras se inicializan a 0. 556 00:56:22,579 --> 00:56:39,699 Pues entonces me dice que persona 1 vale 0. ¿Por qué? Porque esto ya no apunta a la zona de la edad donde sí que le habíamos asignado ese valor. Pero en cambio, si hacemos esto, fijaros, a pesar de que a persona 2 no le hemos aplicado ninguna edad, con esta copia, persona 2 ha pasado a apuntar a 50.000, como este. 557 00:56:39,699 --> 00:56:51,099 si yo cojo y hago persona 2 persona 2 sí que me indica que vale 20 porque porque es el que está 558 00:56:51,099 --> 00:57:00,780 apuntando realmente a 50.000 poco la gestión de las posiciones de memoria cuando hacemos 559 00:57:00,780 --> 00:57:05,579 asignaciones sin hacer news lo que estamos asignando es posiciones de memoria que es un 560 00:57:05,579 --> 00:57:12,000 poquito lo que nos está pasando aquí está pasando la posición de memoria aquí por eso aquí dentro 561 00:57:12,000 --> 00:57:23,110 trabajamos con el objeto del cual hemos hecho un new en esta fue en esta zona de código bien más 562 00:57:23,110 --> 00:57:35,550 o menos bueno os cuento si no si no me paráis con esto no hace ninguna pregunta por ahí que 563 00:57:35,550 --> 00:57:42,269 tengáis alguna duda os cuento otra de las cosas que hay por el código que es pasar variables por 564 00:57:42,269 --> 00:57:51,510 argumento a un método bueno variables pasar un array métodos que admiten un número de parámetros 565 00:57:51,510 --> 00:58:00,099 que no está definido el número no le ponemos título mejor vamos a hacerlo porque si no os 566 00:58:00,099 --> 00:58:07,110 más lío, voy a limpiar esto 567 00:58:07,110 --> 00:58:11,769 vamos a definir un public static 568 00:58:11,769 --> 00:58:14,130 que no devuelva nada 569 00:58:14,130 --> 00:58:35,789 numpar, bueno este método 570 00:58:35,789 --> 00:58:39,489 nada nuevo nos dice verdad, un método 571 00:58:39,489 --> 00:58:42,849 no devuelve nada, recibe un parámetro 572 00:58:42,849 --> 00:58:44,750 para llamar este método 573 00:58:44,750 --> 00:58:48,630 no estamos definiendo objetos para llamarle porque estamos llamándole 574 00:58:48,630 --> 00:58:50,789 de un sitio static a otro sitio static 575 00:58:50,789 --> 00:58:53,449 entonces hacemos numpar 576 00:58:56,570 --> 00:59:02,190 Pasamos un 2, por ejemplo, como es un entero, se ejecuta y aquí nos muestra el 2, nada nuevo. 577 00:59:02,190 --> 00:59:22,219 A través de la sobrecarga de métodos, podemos definir otro método con el mismo nombre, pero un número de parámetros de entrada diferente o, aunque sea el mismo número, un tipo diferente. 578 00:59:22,760 --> 00:59:32,460 Básicamente, un mecanismo para que en el momento de hacer la llamada, el programa sepa si tiene que ejecutar este o tiene que ejecutar este. 579 00:59:32,460 --> 00:59:42,780 En este caso, hay discrepancia porque bajo la posibilidad de enviarle un único parámetro numérico, serían válidos estos dos, entonces por eso no le gusta. 580 00:59:42,780 --> 01:00:14,960 Si yo cojo y hago una sobrecarga aquí, pues ya me compila, le gusta todo, ya no tiene dudas. Si yo hago esta llamada como de parámetro de entrada tiene un número, ejecutará este. Si hago esta otra, sin lugar a dudas, pues llamará este, que es el que corresponde con los parámetros de entrada que está recibiendo. 581 01:00:14,960 --> 01:00:37,530 Si resulta que tenemos un método en el cual tenemos claro, por ejemplo, que va a recibir un entero, pero luego puede recibir en unas llamadas una cadena de texto, 582 01:00:37,530 --> 01:01:01,900 o puede recibir cinco cadenas de texto, puede ser que reciba diferente número, pero por código, imaginaos que una vez recibe una, otra dos, otra tres cadenas de texto, aquí por código pondríamos un string S, otro string S2, pero resulta que esta vez recibe dos, 583 01:01:01,900 --> 01:01:29,179 pero otra vez a lo mejor recibe 3, pues tendría que poner string ese 3, pero si defino el método string con 3, la vez que reciba 2, ¿qué pasa? Ya tengo que andar poniendo en la llamada 3 cadenas de caracteres, aunque una esté entre comillas, digamos que la posibilidad de que se pueda recibir un número de parámetros diferente en cuanto al último parámetro que recibe, en este caso el string, tendríamos que poder gestionarlo. 584 01:01:29,179 --> 01:01:48,019 ¿Y cómo nos lo permite esto Java? Bueno, nos lo permite de esta forma. Si ponemos esto y ponemos aquí unos puntos suspensivos, lo que estamos diciendo es que la llamada a este método siempre recibirá un entero y luego puede recibir uno o varios cadenas de caracteres. 585 01:01:48,019 --> 01:01:52,760 Entonces fijaros como para este me está compilando, me está gustando, le va bien 586 01:01:52,760 --> 01:02:02,480 Bueno y este, incluso este, fijaros, este compila y funciona porque recibe, le pasa un número 587 01:02:02,480 --> 01:02:07,800 Que se carga aquí en P y luego no le pasa ninguna cadena de caracteres, es decir, cero strings 588 01:02:07,800 --> 01:02:11,940 Este le pasa un número y le pasa una cadena de caracteres 589 01:02:11,940 --> 01:02:20,159 Pues el 2 y una cadena de caracteres 590 01:02:20,159 --> 01:02:23,639 Y vamos a poner otro que le pase por ejemplo 2 591 01:02:23,639 --> 01:02:33,840 ¿Veis? Pues también le compila, le gusta, ¿por qué? Porque tiene la garantía de que el 2 se carga aquí en la P y varias cadenas de caracteres se estarán cargando en este bloque. 592 01:02:35,219 --> 01:02:49,349 ¿Cómo funciona este bloque? Pues funciona como un array. Los arrays, en el siguiente tema, lo vemos un poquito más en detalle, o digamos formalmente, aunque ya hemos hablado en algunos momentos de ellos. 593 01:02:49,349 --> 01:03:07,889 Los Arrays son estructuras de datos que se identifican por un nombre y que tienen un conjunto de variables todas del mismo tipo. En Java hay otros lenguajes que permiten que sean de diferentes tipos los Arrays, cada uno de los datos Java tienen que ser del mismo tipo. 594 01:03:07,889 --> 01:03:22,889 Y para acceder a cada uno de ellos se pone el nombre del array S y entre corchetes un índice, si ponemos un 0 sería el primero, si ponemos un 1 sería el segundo, va de 0 hasta el número de valores que tiene. 595 01:03:22,889 --> 01:04:06,260 Entonces, fijaros, aquí podríamos con un bucle hacer un for desde i igual a cero, mientras i sea menor que ese punto length, length nos indica el número de elementos que tiene el array, hacemos un i más más, y aquí podemos, sí, yo creo que sí, también el for each. 596 01:04:06,260 --> 01:04:09,800 para los arrays puedes utilizar el bucle for each 597 01:04:09,800 --> 01:04:11,519 bucle for each apareció 598 01:04:11,519 --> 01:04:13,000 en una versión 599 01:04:13,000 --> 01:04:15,639 a partir de una determinada versión de java 600 01:04:15,639 --> 01:04:17,780 apareció la opción 601 01:04:17,780 --> 01:04:19,780 del bucle for each, antes eran todos for 602 01:04:19,780 --> 01:04:21,760 for each te recorre todos 603 01:04:21,760 --> 01:04:23,719 los elementos de un array 604 01:04:23,719 --> 01:04:25,039 o de una colección 605 01:04:25,039 --> 01:04:27,920 el for te da la opción 606 01:04:27,920 --> 01:04:29,139 de hacer lo mismo que el for each 607 01:04:29,139 --> 01:04:31,760 y te da una posibilidad añadida porque con un 608 01:04:31,760 --> 01:04:33,699 for each, imaginaros que 609 01:04:33,699 --> 01:04:35,920 tienes un array con tres elementos 610 01:04:38,960 --> 01:04:41,500 Para recorrer los tres elementos lo podéis hacer de esta forma. 611 01:04:41,820 --> 01:04:46,019 Justo este bucle, ahora lo terminamos de completar, nos permitiría esto. 612 01:04:47,320 --> 01:04:50,300 Con un for each te recorre esos mismos tres elementos, 613 01:04:50,940 --> 01:04:53,380 que es por cada uno de los elementos del array, 614 01:04:53,920 --> 01:04:57,179 pues hazme la ejecución y ejecuta para cada uno de los elementos 615 01:04:57,179 --> 01:04:59,119 el código que se ponga aquí dentro. 616 01:05:00,119 --> 01:05:02,360 Un for each te recorre todos, todos los elementos, 617 01:05:02,360 --> 01:05:06,599 pero imaginaros que es perfecto, 618 01:05:06,599 --> 01:05:14,099 No estoy echando por tierra el for each, que cuando quieres recorrer todos los elementos, pues está muy bien y además salió en una versión posterior de Java, muy bien, ¿no? 619 01:05:14,420 --> 01:05:19,440 Pero imaginaos que solamente queréis recorrer del array uno sí y uno no. 620 01:05:19,440 --> 01:05:32,079 Pues con el for each os haría tantas vueltas como tiene el array y aquí es verdad que podríais poner un if uno sí, else uno no, if uno sí, pero con for, por ejemplo, 621 01:05:32,079 --> 01:05:38,460 lo podréis hacer aquí, un i igual a i más 2, y directamente ya va dando saltos de 2 en 2. 622 01:05:39,639 --> 01:05:42,639 O sea, el for te da un poquito más de versatilidad. 623 01:05:43,719 --> 01:05:47,199 Pero el for each está bien también, no es que lo quiera demonizar. 624 01:05:48,159 --> 01:05:50,739 Yo estoy muy acostumbrado a utilizar el for en lugar del for each, 625 01:05:50,739 --> 01:05:54,059 porque como estaba desde antes y ya llevo unos cuantos años programando, 626 01:05:55,079 --> 01:05:57,480 pues yo siempre se me va la mano al for, pero sería válido. 627 01:05:57,480 --> 01:06:27,639 Entonces definimos aquí la variable y aquí hacemos un system.out.println, ponemos aquí atributo, aquí ponemos un in más uno, voy a poner in más uno para que me diga el atributo uno cuando en realidad estemos trabajando con la posición cero. 628 01:06:27,639 --> 01:06:33,380 la primera entrada en este for va a ser con el valor de inicializado a 0 y ahora lo voy a 629 01:06:33,380 --> 01:06:38,679 utilizar como índice aquí en el array entonces para que me diga atributo 1 y no me diga atributo 630 01:06:38,679 --> 01:06:54,800 0 podría también poner atributo 0 pues le pongo el atributo y más 1 y digo es y aquí ese y ahora 631 01:06:54,800 --> 01:06:58,199 aquí en lugar de poner un 0 un 1 o lo que sea para que me de siempre lo mismo pues aprovecho 632 01:06:58,199 --> 01:07:12,599 la variable y que estoy utilizando en el bucle entonces aquí vamos a poner un system ahora aquí 633 01:07:12,599 --> 01:07:22,389 primera llamada para diferenciarlos un poco y aquí pongo un barra n para dejar una línea entre medias 634 01:07:22,389 --> 01:07:56,420 segunda llamada entonces si le damos aquí ejecutar pues nada fijaros en la primera la primera llamada 635 01:07:56,420 --> 01:08:01,739 durante la primera llamada se hace con un par aquí le estoy diciendo que me muestre el valor de p 636 01:08:01,739 --> 01:08:04,900 p es el entero este, me dice un 2 637 01:08:04,900 --> 01:08:06,679 y no me muestra ningún string 638 01:08:06,679 --> 01:08:08,119 ¿por qué? pues porque no le pasó ninguno 639 01:08:08,119 --> 01:08:10,639 la segunda 640 01:08:10,639 --> 01:08:12,420 llamada, pues estábamos haciéndola 641 01:08:12,420 --> 01:08:14,260 con p de nuevo, que vale 2 642 01:08:14,260 --> 01:08:16,600 y dentro del bucle me dice el atributo 643 01:08:16,600 --> 01:08:18,039 que está en la posición 0 644 01:08:18,039 --> 01:08:20,420 aquí me muestra un 1 porque le he puesto 0 más 1 645 01:08:20,420 --> 01:08:22,479 es el que 646 01:08:22,479 --> 01:08:24,420 tiene este s como 647 01:08:24,420 --> 01:08:26,680 array, que es el primero de los 648 01:08:26,680 --> 01:08:27,840 que le hemos pasado aquí como 649 01:08:27,840 --> 01:08:30,279 parámetro de los primeros strings 650 01:08:30,279 --> 01:08:40,020 y luego ya en la tercera llamada que arranca por aquí me muestra el 2, fijaros el 2 por aquí de nuevo 651 01:08:40,020 --> 01:08:48,640 y me dice, una vez que está dando la vuelta al bucle, me dice el atributo 1 sola, por aquí 652 01:08:48,640 --> 01:08:54,819 y en la siguiente vuelta, fijaros que después de la primera vuelta incrementa ahí, pasa de valer 0 a valer 1 653 01:08:54,819 --> 01:08:57,880 con lo cual ya el sistema que me muestra es 654 01:08:57,880 --> 01:09:00,779 1 más 1, me dice que el atributo 2 es 655 01:09:00,779 --> 01:09:03,460 el que se encuentra en el array en la posición S1 656 01:09:03,460 --> 01:09:07,520 en la posición S1 es adiós, que lo hemos pasado por aquí 657 01:09:07,520 --> 01:09:12,399 entonces esto es algo que me parece que aparece 658 01:09:12,399 --> 01:09:15,199 en el temario como 659 01:09:15,199 --> 01:09:18,460 var args, me parece en la teoría 660 01:09:18,460 --> 01:09:22,039 algo así pone en var args 661 01:09:22,039 --> 01:09:23,539 o sea, hace referencia a esto 662 01:09:23,539 --> 01:09:29,279 ¿Cuántas veces podemos poner para pasarle un número variable de parámetros a un método? 663 01:09:29,279 --> 01:09:35,359 Lo podemos poner una vez, si ponemos aquí otros puntos, pues ya no compila, no le gusta. 664 01:09:35,979 --> 01:09:40,279 Y tiene que ir al final, tiene que ser el último bloque de atributos. 665 01:09:41,619 --> 01:09:49,260 Podría ser así, solamente él, ya no le gusta este, claro, no le gusta toda esta llamada porque no existe ese constructor. 666 01:09:49,260 --> 01:09:51,800 puede ser con uno, podríamos tener 667 01:09:51,800 --> 01:09:53,699 pues que 668 01:09:53,699 --> 01:09:55,899 recibir aquí un objeto de la clase 669 01:09:55,899 --> 01:09:56,720 persona p 670 01:09:56,720 --> 01:09:59,960 y luego ya 671 01:09:59,960 --> 01:10:03,060 p no, porque es como me llamo 672 01:10:03,060 --> 01:10:05,279 a esta otra variable, sería el mismo nombre 673 01:10:05,279 --> 01:10:07,460 j y luego ya pues un conjunto 674 01:10:07,460 --> 01:10:08,939 de strings 675 01:10:08,939 --> 01:10:11,420 y el tipo puede ser strings 676 01:10:11,420 --> 01:10:12,500 o puede ser el que sea 677 01:10:12,500 --> 01:10:14,699 siempre el último y solo uno 678 01:10:14,699 --> 01:10:17,199 por ejemplo podríamos pasar un número de variable 679 01:10:17,199 --> 01:10:19,039 de personas, pues ponemos tres puntos 680 01:10:19,039 --> 01:10:25,039 y ya está pues este método recibiría en primer lugar un entero y luego un número de variables 681 01:10:25,039 --> 01:10:34,369 de personas que podría ser 0 1 2 3 los que donde se determina el número pues se determina en la 682 01:10:34,369 --> 01:10:40,029 llamada según el número de personas en este caso de string que pasemos aquí será el número que se 683 01:10:40,029 --> 01:10:46,609 cargue en la en el array y cómo podemos saber cuántos se ha pasado en cada llamada pues con 684 01:10:46,609 --> 01:10:52,710 el atributo Length que tienen todos los Arrays. ¿Cómo podemos recorrerlo? Pues con un for de este 685 01:10:52,710 --> 01:11:01,159 tipo o un for each. Vamos a ver, vamos a rescatarlo y vamos a hacerlo con un for each, a ver si me 686 01:11:01,159 --> 01:11:12,039 acuerdo bien de la sintaxis, string s, lo rescatamos y el equivalente a esto del for each, 687 01:11:12,039 --> 01:12:13,369 a ver, for each, o es separado, for each, no me acuerdo, muy bien, como ya os digo, utilizo siempre este, a ver, string, es así, no, no me acuerdo como es la sintaxis, ahora mismo es for each, si os acordáis alguno, si no, bueno, pues lo, a ver, vamos a buscar un momentito, vamos a ver como es la sintaxis del for each, 688 01:12:13,369 --> 01:12:39,180 a la E mayúscula, no le voy a dedicar mucho tiempo a esto 689 01:12:39,180 --> 01:12:41,899 lo miro un segundo más, a ver si lo localizo por aquí 690 01:12:41,899 --> 01:12:47,180 se pone for, pero el for each es así, vale, string cadena 691 01:12:47,180 --> 01:13:07,229 dos puntos, lista, ahí lo tenemos, entonces en cada una 692 01:13:07,229 --> 01:13:11,170 de las vueltas, en lugar de ir con el i, para este array se va cargando 693 01:13:11,170 --> 01:13:20,380 aquí en el la información, entonces aquí no existe 694 01:13:20,380 --> 01:13:23,439 i ya, fijaros, pues aquí ya tendríamos un inconveniente de hacerlo así 695 01:13:23,439 --> 01:13:30,699 y la variable que utilizamos es L, que L en cada una de las iteraciones 696 01:13:30,699 --> 01:13:33,800 se va cargando con cada uno de los valores que tiene S 697 01:13:33,800 --> 01:13:41,119 L es un string, esto es un array de strings 698 01:13:41,119 --> 01:13:44,680 cada vez carga su string aquí, entonces si damos aquí una ejecución 699 01:13:44,680 --> 01:13:52,619 pues fijaros como me funciona igual. Bueno, ¿alguna duda sobre el 700 01:13:52,619 --> 01:13:53,659 var ars este? 701 01:14:02,840 --> 01:14:05,579 Pues nada, os paso a contar otra cosa 702 01:14:05,579 --> 01:14:10,250 en particular esto yo creo que 703 01:14:10,250 --> 01:14:11,550 no sé si luego lo vemos 704 01:14:11,550 --> 01:14:14,350 más formalmente en alguno de los 705 01:14:14,350 --> 01:14:16,050 temas más adelante 706 01:14:16,050 --> 01:14:17,710 pero bueno es interesante 707 01:14:17,710 --> 01:14:20,149 verlo ahora yo creo y si hace falta 708 01:14:20,149 --> 01:14:22,550 pues luego en otro tutorial lo volvemos a repasar 709 01:14:22,550 --> 01:14:24,390 y más vale dos veces 710 01:14:24,390 --> 01:14:25,430 que ninguna yo creo 711 01:14:25,430 --> 01:14:27,050 mirad 712 01:14:27,050 --> 01:14:30,170 se trata de otra de las etiquetas que yo creo 713 01:14:30,170 --> 01:14:32,069 que aparece también por ahí que es la etiqueta 714 01:14:32,069 --> 01:14:34,189 abstract para en los 715 01:14:34,189 --> 01:14:35,550 métodos 716 01:14:35,550 --> 01:15:05,039 Cuando estamos definiendo una clase, tenemos la posibilidad de definir sus atributos, como siempre, tenemos la posibilidad de definir métodos, por ejemplo, public void saludar, con el código que corresponda, y aquí ponemos el código que sea, system.out.println hola. 717 01:15:05,039 --> 01:15:24,829 Y también podemos definir métodos que sean abstractos. Publiz, abstract, etiqueta abstract, voy a poner que despedirse es abstracto. 718 01:15:24,829 --> 01:15:57,750 si intentamos poner su código por aquí, fijaros que no me compila, si me pongo aquí a ver que nos dice, dice borra el body, borra el cuerpo de este método, me está diciendo que borre esto y pongo aquí un punto y coma, aquí me dice que si defino un método abstracto la clase también tiene que ser abstracta, 719 01:15:57,750 --> 01:16:23,770 Vamos a poner aquí también la etiqueta ASTRAT a la clase. Y ahora ya me compila todo. Fijaros, lo que he hecho, a diferencia del método saludar, en el que he dicho cuando se invoca este método para un objeto que ejecute este código, en principio es un system of println hola, lo que he hecho aquí ha sido definir un método, pero no he puesto su cuerpo, no he puesto lo que tiene que pasar cuando se ejecute. 720 01:16:23,770 --> 01:16:54,699 De alguna forma, esta clase persona está incompleta. Está incompleta hasta el punto de que si yo ahora me vengo aquí al método main y digo que me instancia un objeto de la clase persona, no me compila. 721 01:16:54,699 --> 01:17:14,300 ¿Esto tiene sentido? Dice, no puedes instanciar un objeto de la clase persona. Me dice aquí el Mechiva Eclipse. ¿Esto tiene sentido? Pues sí, porque si yo intento decir un miper, objeto de la clase persona, saludar, está claro lo que va a pasar. 722 01:17:14,300 --> 01:17:31,500 Lo tengo bien definido en el código. Me va a decir un System.out.println. Hola. Me va a sacar por pantalla. Hola. Pero si yo pongo un System.out.println.despedirse, ¿qué es lo que pasa si no tenemos definido para la clase persona lo que tiene que pasar? 723 01:17:31,500 --> 01:17:34,619 entonces tiene todo el sentido de que no se pueden instanciar 724 01:17:34,619 --> 01:17:36,880 objetos de clases abstractas 725 01:17:36,880 --> 01:17:38,300 normalmente las clases son abstractas 726 01:17:38,300 --> 01:17:40,199 cuando tienen métodos que son abstractos 727 01:17:40,199 --> 01:17:44,289 ¿y qué sentido tiene esto? 728 01:17:45,210 --> 01:17:47,029 pues tiene que ver con algo que habíamos hablado 729 01:17:47,029 --> 01:17:48,630 el otro día, que ya os digo 730 01:17:48,630 --> 01:17:50,069 que lo volveremos a ver 731 01:17:50,069 --> 01:17:53,250 en el código, que es una característica de la programación 732 01:17:53,250 --> 01:17:54,829 orientada a objetos, que es la herencia 733 01:17:54,829 --> 01:17:56,750 nosotros podemos querer 734 01:17:56,750 --> 01:17:59,029 definir un conjunto de cosas 735 01:17:59,029 --> 01:18:01,130 en una clase que sea 736 01:18:01,130 --> 01:18:03,130 padre, pero luego no instanciar objetos 737 01:18:03,130 --> 01:18:06,909 de esa clase. Es decir, personas, por ejemplo, en el ámbito 738 01:18:06,909 --> 01:18:10,770 de una de nuestras clases, pues está persona del profesor, 739 01:18:10,890 --> 01:18:14,989 persona de los alumnos. Cada uno, todos compartimos 740 01:18:14,989 --> 01:18:19,069 cosas comunes como personas, pues esto, edad 741 01:18:19,069 --> 01:18:22,810 y nombre. Podemos compartir mecanismos para 742 01:18:22,810 --> 01:18:27,010 saludar, métodos, pues podemos saludar así como saludan 743 01:18:27,010 --> 01:18:30,310 en general las personas, aunque luego en cada una de las clases, como decíamos 744 01:18:30,310 --> 01:18:34,369 en otras de las tutorías podríamos sobrescribirlo para particularizar 745 01:18:34,369 --> 01:18:36,750 los profesores o los alumnos la forma de saludar 746 01:18:36,750 --> 01:18:39,869 y luego podemos querer obligar 747 01:18:39,869 --> 01:18:43,210 a que todo aquel que actúe como una persona 748 01:18:43,210 --> 01:18:46,149 por herencia, es decir, que coja las características de una persona 749 01:18:46,149 --> 01:18:49,470 esté obligado a despedirse 750 01:18:49,470 --> 01:18:52,489 pero podemos no querer decir 751 01:18:52,489 --> 01:18:54,609 en la clase personal cómo se tienen que despedir 752 01:18:54,609 --> 01:18:57,029 pero sí decir, si tú quieres 753 01:18:57,029 --> 01:19:00,890 comportarte a grandes rasgos, aunque luego 754 01:19:00,890 --> 01:19:04,829 tras tus particularidades como alumno, siendo una clase hija, comportarte como 755 01:19:04,829 --> 01:19:08,609 una persona, quieres tener disponibles aquellos atributos y 756 01:19:08,609 --> 01:19:12,810 métodos que tienen las personas por herencia, aunque no te voy a decir 757 01:19:12,810 --> 01:19:17,170 cómo, sí que te obligo, es decir, fírmame aquí un contrato 758 01:19:17,170 --> 01:19:21,050 que por ser una persona vas a implementar 759 01:19:21,050 --> 01:19:25,149 un código de cómo despedirte. Y eso lo conseguimos 760 01:19:25,149 --> 01:19:30,189 de esta forma. ¿Podemos instanciar objetos de la clase persona? No. ¿Por qué? Porque no se sabe 761 01:19:30,189 --> 01:19:37,369 cómo se despiden. Pero todo aquel que sea hijo de una clase persona estará obligado a implementar 762 01:19:37,369 --> 01:19:41,489 un método que sea despedirse, porque como persona te tienes que despedir, aunque no te voy a decir 763 01:19:41,489 --> 01:19:56,609 yo cómo. ¿Cómo haríamos esto? Pues mirad, vamos a definir una clase alumno. La herencia, ya os digo, 764 01:19:56,609 --> 01:20:03,930 volveremos a verla esto sería una clase alumno normal y podemos decir vamos a vamos a hacer que 765 01:20:03,930 --> 01:20:11,289 este alumno sea hijo de la clase persona decimos aquí stands que es la etiqueta con la que 766 01:20:11,289 --> 01:20:19,380 identificamos la herencia de la clase persona esto implica que los alumnos más allá de los 767 01:20:19,380 --> 01:20:27,899 atributos y métodos que pongamos aquí tendrán disponibles los atributos y métodos que tienen 768 01:20:27,899 --> 01:20:33,180 la clase persona. Podrán saludar, si no lo sobreescribimos, tal cual saludan las personas 769 01:20:33,180 --> 01:20:38,539 y tendrán la posibilidad de todo objeto que definamos como alumno de asignarle una edad 770 01:20:38,539 --> 01:20:46,260 y un nombre. Y por ser una clase abstracta persona y haberlo identificado aquí, hemos 771 01:20:46,260 --> 01:20:52,659 obligado a que el alumno tenga sí o sí que implementar el método de despedirse. Si os 772 01:20:52,659 --> 01:20:57,560 fijáis, esto todavía no compila. Veis que el alumno lo tengo en rojito y si me pongo 773 01:20:57,560 --> 01:21:02,600 sobre él, me dice, añade los métodos no implementados. 774 01:21:03,819 --> 01:21:06,420 Si lo doy aquí, fijaros qué método me añade, despedirse. 775 01:21:06,699 --> 01:21:11,319 Me está obligando, sí o sí, a que defina dentro de la clase 776 01:21:11,319 --> 01:21:13,300 alumno el método de despedirse. 777 01:21:13,439 --> 01:21:13,739 ¿Por qué? 778 01:21:13,739 --> 01:21:17,479 Porque toda persona tiene que tener la posibilidad de 779 01:21:17,479 --> 01:21:17,979 despedirse. 780 01:21:18,460 --> 01:21:21,840 Alumno como hijo de persona también lo tiene que hacer. 781 01:21:22,800 --> 01:21:23,920 ¿Y cómo se tiene que despedir? 782 01:21:24,600 --> 01:21:26,140 Pues de saludar, no me lo ha pedido, 783 01:21:26,140 --> 01:21:32,319 porque ya lo tenía aquí indicado, fijaros que saludar no es abstracto, pero despedirse que sí lo es y no lo había identificado 784 01:21:32,319 --> 01:21:41,050 me obliga a que lo ponga aquí. Y ahora ya me compila. Aquí es donde podríamos poner cómo se despiden en sí los alumnos. 785 01:21:46,640 --> 01:21:52,979 Respecto a saludar, otra de las características de la programación orientada a objetos, los alumnos ya podrán saludar, 786 01:21:53,140 --> 01:22:00,819 podrán despedirse, tal cual ha dicho aquí, y podrán saludar, aunque no lo tengo definido en la clase alumno, 787 01:22:00,819 --> 01:22:05,619 por herencia de la clase Persona, tal cual está identificado aquí. 788 01:22:05,960 --> 01:22:10,659 Y si no me gusta cómo se despiden las personas en general siendo un alumno, 789 01:22:10,939 --> 01:22:14,439 pues tengo la posibilidad de otra de las características de la programación orientada a objetos, 790 01:22:14,800 --> 01:22:16,600 que es sobrescribir este método. 791 01:22:24,159 --> 01:22:28,520 Entonces, un alumno que salude, ahora ya se fijaría en su propia definición, 792 01:22:28,520 --> 01:22:32,140 que está sobrescribiendo la general de cómo se saludan todas las personas. 793 01:22:33,479 --> 01:22:38,279 Y para despedirse, utilizaría el único código que tiene disponible, 794 01:22:39,140 --> 01:22:59,789 porque en la clase persona no lo tenemos al ser abstracto si se entiende mirad imaginaos que 795 01:22:59,789 --> 01:23:07,909 seguís ahí verdad eso sí vale bueno que seguís y que se hubiera perdido la conexión quería decir 796 01:23:11,050 --> 01:23:19,479 mirad en relación a la herencia si definimos aquí otra clase vamos a poner la clase humano 797 01:23:19,479 --> 01:23:31,880 la clase humano podríamos decir que tiene un método public void que sea saltar vamos a decir 798 01:23:31,880 --> 01:23:44,090 no lo defino abstracto ni nada y aquí pondríamos el código system.out.println aquí pondríamos lo 799 01:23:44,090 --> 01:23:49,609 que correspondería a un humano para estar saltando vamos a poner que muestra por pantalla que está 800 01:23:49,609 --> 01:23:59,470 saltando podríamos suponer que un alumno aparte de ser una persona lógicamente es un humano entonces 801 01:23:59,470 --> 01:24:17,850 Entonces nos podría dar la tentación de decir, pues si es un alumno y es un humano, vamos a hacer que el alumno extienda de persona para que herede como saludar, para que me obligue a despedirme y de humano para poder saltar. 802 01:24:17,850 --> 01:24:27,909 les podría poner aquí estén persona y podría poner aquí humano pero esto no es no me compila 803 01:24:27,909 --> 01:24:36,000 a ver qué me dice me dice que era no sé qué bueno no me compila os cuento por qué la en java aunque 804 01:24:36,000 --> 01:24:41,739 algunos lenguajes sí que bueno pues hacen sus artimañas para poder gestionarlo en java la 805 01:24:41,739 --> 01:24:49,859 herencia es única solamente digamos una herencia implícita que podría ser desde la clase object 806 01:24:49,859 --> 01:24:51,859 heredando o disponiendo de 807 01:24:51,859 --> 01:24:53,659 métodos que están definidos en la clase object 808 01:24:53,659 --> 01:24:54,880 y en nuestro código 809 01:24:54,880 --> 01:24:57,600 solamente podemos poner una herencia 810 01:24:57,600 --> 01:24:59,920 única, no podemos poner herencia desde diferentes 811 01:24:59,920 --> 01:25:01,960 clases. ¿Cuál es el motivo? 812 01:25:02,279 --> 01:25:03,300 Pues imaginaros que 813 01:25:03,300 --> 01:25:05,279 en la clase persona 814 01:25:05,279 --> 01:25:07,659 yo he definido un método 815 01:25:07,659 --> 01:25:09,899 saludar y en la 816 01:25:09,899 --> 01:25:13,140 clase humano yo defino 817 01:25:13,140 --> 01:25:14,260 un método saludar. 818 01:25:18,659 --> 01:25:20,659 Si Java nos permitiese hacer herencia 819 01:25:20,659 --> 01:25:22,739 múltiple, poner 820 01:25:22,739 --> 01:25:24,579 que herede de persona y de humano 821 01:25:24,579 --> 01:25:46,930 Si yo instancio un objeto de la clase alumno y digo que salude, no sabría muy bien si lo tuviese aquí. Sobrescribiría cualquiera, pero si no lo tiene, se iría a buscar ese método en la clase padre. ¿De qué clase padre lo cojo? ¿De persona que tiene un método de saludar o de humano que también lo tiene? 822 01:25:46,930 --> 01:25:53,569 entonces esta coincidencia hace que haya una discrepancia que no le deja elegir a los alumnos 823 01:25:53,569 --> 01:25:58,229 cómo saludar porque lo tiene disponible por herencia desde dos sitios diferentes 824 01:25:58,229 --> 01:26:14,340 entonces no lo permite no deja la herencia múltiple java la herencia es simple herencia 825 01:26:14,340 --> 01:26:16,579 simple ahora sigo contando más cosas 826 01:26:16,579 --> 01:26:18,239 volvemos un momento a las 827 01:26:18,239 --> 01:26:19,779 clases abstractas 828 01:26:19,779 --> 01:26:22,340 las clases abstractas tienen métodos 829 01:26:22,340 --> 01:26:24,399 que son 830 01:26:24,399 --> 01:26:26,020 abstractos que obligan 831 01:26:26,020 --> 01:26:28,460 a los hijos 832 01:26:28,460 --> 01:26:30,140 de la clase a 833 01:26:30,140 --> 01:26:31,680 implementarlos como despedirse 834 01:26:31,680 --> 01:26:33,680 y tiene otros métodos 835 01:26:33,680 --> 01:26:36,180 que tienen código pues este 836 01:26:36,180 --> 01:26:38,439 no te obligó a implementarlo si tú lo quieres implementar 837 01:26:38,439 --> 01:26:40,119 para sobrecargarlo me parece bien 838 01:26:40,119 --> 01:26:42,380 y si no tienes este disponible 839 01:26:42,380 --> 01:26:45,590 una clase abstracta 840 01:26:45,710 --> 01:26:57,329 podría tener todos sus métodos abstractos como es abstracto no le pongo código y bueno pues he 841 01:26:57,329 --> 01:27:03,390 añadido a ese a ese choque de manos en el cual habíamos firmado un acuerdo y obligado a que 842 01:27:03,390 --> 01:27:07,130 todos los hijos ya no sólo tengan que implementar despedirse sino también están obligados a 843 01:27:07,130 --> 01:27:14,789 implementar saludar salvo esto y fijaros como directamente ahora alumno deja de compilar me 844 01:27:14,789 --> 01:27:18,810 tengo implementado despedirse, fijaros que me está diciendo aquí que está 845 01:27:18,810 --> 01:27:22,770 sobrescribiendo uno que había definido en persona 846 01:27:22,770 --> 01:27:26,569 que no estaba implementado, si me pongo aquí me vuelve a decir 847 01:27:26,569 --> 01:27:30,250 que añada los métodos no implementados y que me dice 848 01:27:30,250 --> 01:27:41,640 me mete a saludar que es el que tengo ahí en el acuerdo, fijaros en este caso estamos definiendo 849 01:27:41,640 --> 01:27:45,619 la clase persona como algo que 850 01:27:45,619 --> 01:27:49,520 no tiene código propio y que directamente 851 01:27:49,520 --> 01:27:54,220 es, perdón aquí, y que directamente es un acuerdo 852 01:27:54,220 --> 01:27:57,880 para implementar una serie de métodos. Y más si todavía 853 01:27:57,880 --> 01:28:01,539 quitamos además esto. Fijaros, simplemente dos métodos aquí abstractos. 854 01:28:01,960 --> 01:28:05,819 No podemos implementar objetos, instanciar objetos de la clase persona 855 01:28:05,819 --> 01:28:09,720 porque no está desarrollado su código. Y sí que estamos obligados a que 856 01:28:09,720 --> 01:28:13,699 todo aquel que quiera ser una persona, por lo menos disponga 857 01:28:13,699 --> 01:28:17,600 de estas funcionalidades. Cuando todas 858 01:28:17,600 --> 01:28:26,340 es decir una clase abstracta puede tener métodos abstractos y métodos desarrollados cuando una 859 01:28:26,340 --> 01:28:35,119 clase abstracta todos sus métodos están son abstractos esto más lo considera java como 860 01:28:35,119 --> 01:28:43,720 un interfaz entonces si nos venimos aquí fijaros y damos año una de las opciones que nos ofrece 861 01:28:43,720 --> 01:28:44,840 es la de interface. 862 01:28:46,260 --> 01:28:47,720 No sé en qué método, yo creo que esto 863 01:28:47,720 --> 01:28:48,939 todavía no lo hemos visto en la teoría. 864 01:28:49,399 --> 01:28:51,699 Cuando llegue ya lo llevéis un poco adelantado. 865 01:28:53,579 --> 01:28:54,880 Entonces si yo defino aquí un interface, 866 01:28:55,000 --> 01:28:55,720 vamos a poner 867 01:28:55,720 --> 01:28:58,939 mi inter, como si estuviéramos 868 01:28:58,939 --> 01:28:59,779 definiendo una clase. 869 01:29:01,520 --> 01:29:02,939 Ahora, este en lugar de ser un 870 01:29:02,939 --> 01:29:03,600 public class, 871 01:29:04,779 --> 01:29:06,819 pues se define public class, o sea, 872 01:29:07,420 --> 01:29:09,199 en lugar de ser public class, pues 873 01:29:09,199 --> 01:29:10,960 es public interface. 874 01:29:12,880 --> 01:29:13,840 Los interfaces 875 01:29:13,840 --> 01:29:36,579 public void saludar fijaros como una interfaz no me compila si intento decir qué código tiene 876 01:29:36,579 --> 01:29:46,239 un método como haríamos en una clase si me pongo por aquí me dice que lo cambia estático que borre 877 01:29:46,239 --> 01:29:58,739 el cuerpo por ser ni siquiera hay que poner la etiqueta abstract por lo que veo si ponemos 878 01:29:58,739 --> 01:30:03,960 public astra pues tiene la consideración de método abstracto y si no yo creo que no hace 879 01:30:03,960 --> 01:30:12,300 ni falta por lo que veo porque también me compila aquí vamos a ponerlo vamos a poner un inter 880 01:30:13,300 --> 01:30:27,430 saludar y un inter despedir una interfaz es un acuerdo de cosas que quien utilice 881 01:30:27,430 --> 01:30:30,630 esta interfaz va a tener que desarrollar como métodos. 882 01:30:32,189 --> 01:30:33,750 ¿Cómo se identifican los interfaces? 883 01:30:34,550 --> 01:30:39,590 Pues fijaros, la clase alumno puede ser que herede de la clase persona, 884 01:30:39,729 --> 01:30:42,829 de una sola clase, herencia única, no permite herencia múltiple. 885 01:30:42,829 --> 01:30:49,489 Y podemos, para los interfaces, utilizar la etiqueta Implements. 886 01:30:49,710 --> 01:30:55,729 Dice, la clase alumno tiene sus propios métodos por aquí desarrollados, 887 01:30:55,729 --> 01:31:04,710 sus propios atributos, por herencia dispondrá de aquellas cosas que tiene la clase persona, que si es abstracta habrá que haber implementado sus métodos 888 01:31:04,710 --> 01:31:14,930 y los que estén desarrollados estarán disponibles, y además implementa una interfaz, y en este caso hemos llamado a la interfaz Minter. 889 01:31:19,300 --> 01:31:28,060 Y fijaros, se me vuelve a poner esto en rojo, que no compila, y si me pongo por aquí, me dice, añade los métodos no implementados, 890 01:31:28,060 --> 01:31:38,000 y los métodos que me han añadido son los dos que están identificados en el interfaz, es decir, algo parecido a los métodos abstractos 891 01:31:38,000 --> 01:31:45,640 que tenía una clase padre, en este caso de la clase alumno. ¿Veis? Un poco esa idea. 892 01:31:52,649 --> 01:31:59,710 ¿Para qué nos sirven los interfaces? En realidad, fijaros que no tiene código aquí desarrollado, pero es una forma de obligar 893 01:31:59,710 --> 01:32:02,409 a que las clases consideren ciertas 894 01:32:02,409 --> 01:32:05,609 funcionalidades. Imaginaos que la clase 895 01:32:05,609 --> 01:32:08,529 alumno es un programa como para llevarlo 896 01:32:08,529 --> 01:32:11,329 ahí a lo grande, como os digo otras veces, que tiene 897 01:32:11,329 --> 01:32:14,310 muchas líneas de código, tiene 60 clases, hay 898 01:32:14,310 --> 01:32:15,550 diferentes grupos de trabajo 899 01:32:15,550 --> 01:32:20,550 y alguien dice, mira, desde el banco 900 01:32:20,550 --> 01:32:23,130 que os hablo a veces, un cliente, el cliente del banco 901 01:32:23,130 --> 01:32:26,529 y dicen desde nóminas, pues yo voy a necesitar 902 01:32:26,529 --> 01:32:29,250 conocer el DNI 903 01:32:29,250 --> 01:32:32,369 o yo qué sé, la dirección del cliente. 904 01:32:33,229 --> 01:32:36,770 Entonces, pueden acordar un interfaz común 905 01:32:36,770 --> 01:32:40,329 en la clase cliente dice que implements interfaz 906 01:32:40,329 --> 01:32:42,970 y el acuerdo ese común que tienen 907 01:32:42,970 --> 01:32:46,130 desde donde va a ser llamado el objeto del cliente 908 01:32:46,130 --> 01:32:49,090 para conocer su dirección y de quien lo desarrolla 909 01:32:49,090 --> 01:32:51,069 lo definen en una interfaz. 910 01:32:51,850 --> 01:32:55,529 No desarrollan cómo el cliente va a coger su dirección. 911 01:32:55,789 --> 01:32:58,069 ¿Por qué? Porque a lo mejor quien esté haciendo 912 01:32:58,069 --> 01:33:02,590 el desarrollo de la clase código cliente, pues sabes si esa información 913 01:33:02,590 --> 01:33:06,390 está en una base de datos o vete tú a saber dónde está, en un fichero 914 01:33:06,390 --> 01:33:09,590 o se la pide un operario manualmente. 915 01:33:10,710 --> 01:33:14,430 Desde la otra parte, desde la parte esa de, no sé si había dicho nóminas antes, 916 01:33:15,050 --> 01:33:17,350 desde la parte de nóminas, lo que quieren es el dato de la dirección. 917 01:33:17,470 --> 01:33:19,090 Le da igual cómo lo consiga el cliente. 918 01:33:19,270 --> 01:33:23,449 El cliente sabe que, es decir, quiere poder pedírselo por un método 919 01:33:23,449 --> 01:33:24,069 y que le llegue. 920 01:33:24,430 --> 01:33:27,449 Cómo lo vaya a conseguir la clase cliente, le da igual. 921 01:33:28,069 --> 01:33:31,510 La clase cliente sí que sabe de dónde la puede coger, que será de la base de datos. 922 01:33:32,310 --> 01:33:38,470 Entonces dicen, el cliente, yo voy a hacer el desarrollo del código para coger esa información de la base de datos. 923 01:33:39,170 --> 01:33:44,550 Y si no han llegado a un acuerdo con una interfaz en la cual están firmando un acuerdo de cómo se va a llamar ese método 924 01:33:44,550 --> 01:33:51,909 desde el cual va a poder acceder desde nóminas, pues a lo mejor el cliente sabe coger el dato y luego crea un método para devolverlo 925 01:33:51,909 --> 01:34:00,489 que sea def info cliente y desde el otro sitio espera conseguirlo con red de recuperar info 926 01:34:00,489 --> 01:34:06,789 cliente pues si uno crea el método def y otro red mal vamos como llegan un acuerdo común pues 927 01:34:06,789 --> 01:34:12,010 hacen una interfaz en la interfaz define exactamente lo que hay sin decir cómo se 928 01:34:12,010 --> 01:34:17,090 recupera que de eso ya se encargará el cliente y el cliente como en este caso el alumno implementa 929 01:34:17,090 --> 01:34:22,770 esa interfaz y obligatoriamente tiene que desarrollar el método de devolver la dirección 930 01:34:22,770 --> 01:34:30,170 del cliente. Se desarrolla, se pone el detalle de cómo se recupera esa información aquí en 931 01:34:30,170 --> 01:34:35,470 la interfaz. No, es sólo el acuerdo. ¿Quién es quien tiene que saber cómo hacerlo? Pues en la 932 01:34:35,470 --> 01:34:39,810 implementación del cliente, que en este caso sería el alumno aquí. Sería acceder a la base de datos 933 01:34:39,810 --> 01:34:51,020 para obtener esa información mira las interfaces os cuento estoy con esto yo creo ya vamos terminando 934 01:34:51,020 --> 01:35:10,810 si no tenéis otras dudas vamos a crear otras una segunda interfaz inter 2 vamos a poner este método 935 01:35:10,810 --> 01:35:23,819 vamos a poner saludar debemos dicho despedirse saludar crear mira esta interfaz nos obliga a 936 01:35:23,819 --> 01:35:29,039 quien implemente esta interfaz que la implementación de las interfaces se hace con implement y el nombre 937 01:35:29,039 --> 01:35:37,460 la interfaz a desarrollar un método que sea inter saludar e inter despedir esta otra interfaz quien 938 01:35:37,460 --> 01:35:43,060 la implemente está obligado a hacer un método que sea inter saludar e inter crear a propósito 939 01:35:43,060 --> 01:35:51,840 puesto saludar igual que aquí y despedir diferente de aquí que es crear qué pasaba antes con un mano 940 01:35:51,840 --> 01:35:57,600 y con persona para la herencia simple que habíamos dicho que si los dos implementaban un método que 941 01:35:57,600 --> 01:36:30,170 fuera saludar, en la herencia el alumno no sabría si utilizar uno u otro. Aquí en las interfaces he hecho coincidir el inter saludar y a pesar de todo aquí me deja implementar mi inter y si pongo aquí mi inter 2, se separan por una coma yo creo, a ver, sí, me deja y si yo digo aquí me dice añadir métodos no implementados. 942 01:36:30,170 --> 01:36:32,069 fijaros que la implementación 943 01:36:32,069 --> 01:36:34,109 sí que me la permite 944 01:36:34,109 --> 01:36:35,470 múltiple, cuando la herencia 945 01:36:35,470 --> 01:36:37,310 tenía que ser sencilla 946 01:36:37,310 --> 01:36:39,649 ¿por qué es esto? pues bueno, pues tiene 947 01:36:39,649 --> 01:36:42,310 una explicación 948 01:36:42,310 --> 01:36:42,989 muy rápida 949 01:36:42,989 --> 01:36:46,310 al fin y al cabo, ¿qué estamos haciendo con los interfaces? 950 01:36:46,510 --> 01:36:48,350 los interfaces tienen todas sus clases 951 01:36:48,350 --> 01:36:50,510 abstractas, todos sus métodos abstractos 952 01:36:50,510 --> 01:36:51,949 no estamos diciendo cómo se 953 01:36:51,949 --> 01:36:54,090 ejecutan, aquí lo que estamos diciendo 954 01:36:54,090 --> 01:36:56,170 en el alumno, en la clase 955 01:36:56,170 --> 01:36:57,829 alumno al implementar estos dos interfaces 956 01:36:57,829 --> 01:37:00,149 es que tienen que 957 01:37:00,170 --> 01:37:04,510 para desarrollar el código para cada uno de los métodos que están definidos en el interfaz. 958 01:37:04,750 --> 01:37:08,510 ¿Que hay uno que coincide el nombre? Pues me parece muy bien, me obligas por dos lados, 959 01:37:08,810 --> 01:37:13,689 pero no tengo discrepancia de que en un interfaz y en otro haya código que sea diferente. 960 01:37:13,930 --> 01:37:17,329 Lo único que desde dos sitios me estás diciendo, crea el método saludar. 961 01:37:17,930 --> 01:37:22,649 Aunque me obligues desde dos sitios, el único código para saludar que tendrá el inter saludar 962 01:37:22,649 --> 01:37:26,689 será el que ponga aquí, por mucho que me estés obligando desde aquí y desde aquí. 963 01:37:26,689 --> 01:37:41,170 Y luego, por separado, habrá que implementar cada uno de los métodos que tiene cada una de las interfaces. El intersaludar, el interdespedir y el intercrear, los tres métodos que estamos identificando entre las dos interfaces. 964 01:37:42,449 --> 01:37:55,090 Es decir, para la herencia, la herencia tiene que ser simple, siempre, no permite directamente Java desde el área de compilación heredar desde varias clases, pero la implementación puede ser múltiple. 965 01:37:55,090 --> 01:38:05,289 ¿Qué tal? ¿Cómo lo veis? ¿Alguna preguntilla? 966 01:38:06,369 --> 01:38:06,649 Esto 967 01:38:06,649 --> 01:38:16,720 Nada más, yo creo que, ya os digo 968 01:38:16,720 --> 01:38:18,680 creo recordar que la herencia y los 969 01:38:18,680 --> 01:38:20,760 interfaces aparecen luego, volvemos 970 01:38:20,760 --> 01:38:22,399 a hacer 971 01:38:22,399 --> 01:38:24,859 un ejercicio igual que este para volver a repasarlo 972 01:38:24,859 --> 01:38:31,680 ¿Para este próximo examen? 973 01:38:33,899 --> 01:38:35,720 Sí, para el de febrero entra 974 01:38:35,720 --> 01:38:37,920 hasta el tema que abre mañana 975 01:38:37,920 --> 01:38:39,960 No me acuerdo si está ahí 976 01:38:39,960 --> 01:38:41,840 o está más adelante, si no está 977 01:38:41,840 --> 01:38:44,100 ahí no entra, el último 978 01:38:44,100 --> 01:38:45,079 tema para el de febrero 979 01:38:45,079 --> 01:38:48,500 lo que tenéis ya visible a partir de mañana. 980 01:38:54,420 --> 01:38:56,460 Bueno, no sé si tenéis alguna cosilla 981 01:38:56,460 --> 01:38:58,560 que me queréis preguntar más 982 01:38:58,560 --> 01:39:01,159 o si no lo vamos a ir dejando aquí, me parece. 983 01:39:04,520 --> 01:39:05,960 Mañana os abro el nuevo tema 984 01:39:05,960 --> 01:39:10,979 y bueno, pues por ahí ando por los foros pendientes 985 01:39:10,979 --> 01:39:13,079 si tenéis algunas consultas que ir haciendo. 986 01:39:17,880 --> 01:39:20,239 Respecto a alguna cosa que alguna vez me habéis preguntado, 987 01:39:21,180 --> 01:39:23,479 el otro día nos pasó el coordinador Juanjo, 988 01:39:23,479 --> 01:39:25,199 nos pasó un mensaje 989 01:39:25,199 --> 01:39:27,420 bueno, como siempre se dan 990 01:39:27,420 --> 01:39:29,220 justificantes de asistencia 991 01:39:29,220 --> 01:39:32,000 al examen, lo que pasa es que yo no sé 992 01:39:32,000 --> 01:39:33,859 yo no sé si otros años también ha sido así 993 01:39:33,859 --> 01:39:35,960 en este examen de febrero, pero sí que era lo que 994 01:39:35,960 --> 01:39:38,300 nos decía ahora, que los justificantes 995 01:39:38,300 --> 01:39:40,020 para ahora sí que aparece que el examen 996 01:39:40,020 --> 01:39:41,800 es voluntario, lo digo un poco 997 01:39:41,800 --> 01:39:43,319 o sea que el justificante podríais tener 998 01:39:43,319 --> 01:39:46,199 pero no sé si quedará en presa 999 01:39:46,199 --> 01:39:47,899 el hecho de la coletilla esa de que el examen 1000 01:39:47,899 --> 01:39:50,239 es voluntario, os puede condicionar 1001 01:39:50,239 --> 01:39:51,779 para que os lo acepten 1002 01:39:51,779 --> 01:39:52,779 de alguna forma 1003 01:39:52,779 --> 01:39:55,520 si podéis arreglarlas 1004 01:39:55,520 --> 01:39:57,600 yo creo que es interesante que vengáis a ver el examen 1005 01:39:57,600 --> 01:39:59,319 porque ya os digo, el modelo luego 1006 01:39:59,319 --> 01:40:01,640 en la ordinaria, lógicamente las preguntas 1007 01:40:01,640 --> 01:40:03,779 son distintas, pero el modelo es igual 1008 01:40:03,779 --> 01:40:05,079 entonces para un poco 1009 01:40:05,079 --> 01:40:07,939 ya que a distancia todo es mucho más complicado 1010 01:40:07,939 --> 01:40:09,560 un mini entrenamiento 1011 01:40:09,560 --> 01:40:11,859 para ver cómo es el examen, os puede venir bien 1012 01:40:11,859 --> 01:40:15,439 pero bueno, nos vemos 1013 01:40:15,439 --> 01:40:16,859 más semanas antes de esto 1014 01:40:16,859 --> 01:40:21,880 y nada, poco más que contaros 1015 01:40:21,880 --> 01:40:23,920 por hoy, la semana que viene 1016 01:40:23,920 --> 01:40:25,579 vemos alguna otra cosita por aquí 1017 01:40:25,579 --> 01:40:26,899 que tengo a punto de este tema 1018 01:40:26,899 --> 01:40:29,020 y yo creo que haremos la tarea 1019 01:40:29,020 --> 01:40:31,399 de justo 1020 01:40:31,399 --> 01:40:32,220 que se cierra 1021 01:40:32,220 --> 01:40:35,420 esta noche, para revisarla 1022 01:40:35,420 --> 01:40:37,380 todos juntos y bueno, pues seguimos 1023 01:40:37,380 --> 01:40:38,279 ahí al pie de cañón 1024 01:40:38,279 --> 01:40:42,380 bueno, venga, pues nada 1025 01:40:42,380 --> 01:40:44,340 que tengáis buena semana si no tenéis más preguntas 1026 01:40:44,340 --> 01:40:46,020 luego 1027 01:40:46,020 --> 01:40:48,520 os subo la grabación 1028 01:40:48,520 --> 01:40:49,819 por si queréis volver a revisarla