Saltar navegación

2025-01-20-Programacion - Contenido educativo

Ajuste de pantalla

El ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:

Subido el 20 de enero de 2025 por Jose Manuel M.

37 visualizaciones

Tema 5 - Método finalize, método varargs, herencia e interfaces, información devuelta por métodos

Descargar la transcripción

alguna cosita por ahí que queráis comentarme antes de arrancar a contar yo cosas es alguna 00:00:03
duda por ahí bueno si no tenéis nada en particular que queráis que veamos en la última tutoría bueno 00:00:11
me preguntasteis alguno de vosotros por el método finalice y bueno os dije que lo echaba un ojillo 00:00:28
es un método que en verdad se suele utilizar poco 00:00:34
pero bueno, estuve haciendo alguna prueba con él 00:00:37
y os puse una entrada en el foro 00:00:42
vamos a repasarlo un momento 00:00:43
y así ya la dejamos clara 00:00:45
el método finalice un poco la idea que propone 00:00:49
es que sea como un destructor de los objetos de una clase 00:00:55
igual que el constructor 00:00:58
es el que se ejecuta cuando arrancamos 00:01:02
cuando damos de alta un objeto, normalmente hacemos la llamada 00:01:04
al constructor después de poner la etiqueta new 00:01:09
en el momento de crearlo y nos sirve para hacer unas inicializaciones que consideramos 00:01:12
que sean necesarias para que ese objeto vaya trabajando 00:01:17
en, vaya participando dentro del programa 00:01:21
finalice, pues ya os digo, se hace cuando termina 00:01:24
el método finalice, la característica que tiene es que 00:01:28
llamado desde desde el recolector de basura y el recolector de basura lo llama la máquina virtual 00:01:33
dejaba cuando llama el recolector de basura la máquina la máquina virtual dejaba al recolector 00:01:39
de basura pues cuando esté programado cuando en cada versión del recolector de basura han hecho 00:01:46
ese desarrollo pues habrán tenido unos criterios para decidir cuándo se va liberando la memoria 00:01:53
ram que ocupan los los diferentes objetos y junto a esto la llamada al método finalice de esos 00:01:59
objetos en línea general es cuando por lo que he podido leer es raro ver que se hacen llamadas en 00:02:07
los programas sobre todo en estos tan cortos que vamos utilizando nosotros al método finalice pero 00:02:15
cuando he visto por ahí que suelen llamarlos pues suelen llamarlos cuando la máquina virtual detecta 00:02:21
que a lo mejor hay demasiada memoria RAM ocupada, pues dice, pues mira, en este momento o si tiene una cuota 00:02:28
para la ejecución del programa que le haya asignado el sistema operativo, pues cuando ve que empieza a haber 00:02:33
carencia de memoria RAM que utilizar para dar de alta nuevos objetos, llama al recolector de basura 00:02:38
para que libere todo lo que sea posible. ¿Tenemos otros controles en principio de eso? Pues en principio 00:02:44
de nuestro programa no, a no ser que llamemos a un método del sistema que fuerza la llamada al recolector 00:02:50
de basura más allá de cuando esté programada por la máquina virtual. 00:02:56
Ahora hacemos una pruebecilla que viene a ser la que os puse. 00:03:01
Y luego, sin hacer esa llamada, podemos intentar forzar 00:03:04
que se ejecute el método finalice 00:03:08
haciendo un bucle cercano a que sea infinito 00:03:12
de construcción de nuevos objetos 00:03:17
que vayan creándose y finalizándose 00:03:21
pero se acaban creándose y destruyéndose dentro del ámbito en el que estén definidos. 00:03:24
Ahora después lo hacemos con código y vemos cómo. 00:03:29
Pero claro, cuya memoria va a quedar liberada cuando pase el recolector de basura. 00:03:33
Entonces obligaremos a hacer mucha reserva de memoria RAM en nuestro programa 00:03:37
de tal forma que la máquina virtual se dé cuenta que estamos ocupando mucha memoria RAM 00:03:42
y haga la llamada al recolector de basura y como consecuencia al método finalice. 00:03:47
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. 00:03:54
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. 00:04:20
entonces si queremos que pase algo cuando se destruye el objeto pues igual sería interesante 00:04:37
intentar hacer una llamada forzando la llamada al método finalice o a cualquier otro método 00:04:43
llamándolo como queramos y si queremos que pase algo pero no nos importa cuándo 00:04:47
pues entonces sí que podríamos dejar ese código metido en este método 00:04:53
vamos con código que yo creo que será más sencillo 00:04:57
entonces mirad aquí el ejercicio 4 con la solución que tenemos propuesta 00:05:02
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 00:05:07
Constructor completo es el que recibe como parámetros todos los atributos que tiene definidos en la clase y se los asigna. 00:05:54
Además hace aquí que incrementa el número de personas. 00:06:03
Y luego este es el constructor copia que recibe una referencia a otro objeto de la clase persona 00:06:07
y desde los atributos que tiene este objeto los asignamos a este, ese sería el copia. 00:06:12
Y luego tiene un constructor vacío. 00:06:17
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. 00:06:20
entonces aquí en el método en probar persona que es donde tenemos el método main fijaros que lo 00:06:44
que hacemos es definir es como aquí como cinco personas verdad fijaros por aquí que están que 00:06:53
existirán en todo el ámbito del método main y luego lo que hace es llamar aquí a un método 00:07:00
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. 00:07:07
Entonces, esta persona en particular, en el momento en el que termina la ejecución del método, desaparecerá. Aquí desaparece. 00:07:22
En cambio, estas otras personas permanecen hasta el final del main, es decir, permanecerían hasta aquí. 00:07:31
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. 00:07:41
Cuando entramos en este método, justo en este momento serían seis las personas que están a dar de alta. 00:07:59
Al salir del método, esta desaparecería, volverían a ser cinco, es decir, aquí tenemos cinco en esta zona de código, 00:08:06
las cinco que hemos definido arriba, una sexta mientras estamos ejecutando el método y aquí volveríamos a tener cinco. 00:08:13
¿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, 00:08:21
lo que hemos hecho ha sido forzar aquí una llamada al método finalice entonces en verdad no estamos 00:08:28
comprobando muy bien el funcionamiento de finalice como un método llamado de forma automática pues 00:08:34
porque lo estamos haciendo con la llamada aquí es decir se convierte en algo del estilo a la llamada 00:08:40
de cualquier otro método ya si hacemos una ejecución con esto manteniendo esto hacer 00:08:46
varias ejecuciones. Bueno, pues aquí nos diría que hay un total 00:08:52
de seis personas. Una, dos, tres, cuatro, cinco. Está la sexta 00:08:57
persona, fijaros. Y ese mensaje me lo saca aquí. Dice, aquí hay 00:09:02
seis personas. Cuando he dado de alta este, me saca este mensaje 00:09:08
y dice, pues hay siete personas. Llamo a finalice, aunque lo estoy 00:09:14
llamando de forma forzada yo aquí, al método finalice 00:09:17
del objeto de la clase persona, que recordad 00:09:21
que lo que hace es decrementar esta variable estática en 1. 00:09:25
Entonces, una vez terminado esto, cuando volvemos a sacar este mensaje me dice que hay 6 personas. 00:09:31
Como consecuencia de que hemos llamado a finalice. Pero lo hemos llamado nosotros aquí 00:09:35
de forma forzada. Si lo comentamos 00:09:39
y la llamada que ponemos nosotros aquí de forma 00:09:43
explícita y lo ejecutamos fijaros como este mensaje sigue diciendo que hay siete personas aunque está 00:09:47
ya habrá desaparecido porque no está fuera de su ámbito pero qué pasa que desde terminar aquí hasta 00:09:54
ejecutar este sistema println no ha entrado en funcionamiento el recolector de basura entonces 00:10:01
como como os proponemos una entrada en el aula virtual justo buenos y también en la zona de 00:10:09
actividades donde están los enunciados, puse como si fuera una actividad más 00:10:15
comentándoos la solución que voy a dar ahora para comprobar efectivamente 00:10:18
cómo funciona el finalice y lo que podemos hacer aquí es justo después 00:10:22
de esta llamada, es decir, en esta llamada habrá un momento en el que serán 00:10:30
siete, se termina aquí el método, con lo cual esta persona ya desaparece 00:10:35
este objeto, lo que vamos a hacer es utilizar una llamada al 00:10:42
sistema que fuerce la llamada al recolector de basura con 00:10:46
independencia de que en algún momento lo tenga que llamar la 00:10:51
máquina virtual. 00:10:55
Entonces, esta llamada la podemos hacer desde código. 00:10:56
GC vienen a ser las siglas de recolector de basura en inglés, 00:11:02
Garbage Collector, recolector de basura. 00:11:06
Y entonces, si hacemos esto, este se entiende que aparte de 00:11:12
liberar la memoria, llamará a los finalices de todos los métodos, 00:11:15
de todos los objetos que ya estén desapareciendo. 00:11:19
Y el finalice del método de la clase persona 00:11:22
lo que hace es decrementarnos este valor. 00:11:26
Vamos a hacer varias ejecuciones sin meter nada más. 00:11:30
Y fijaros, me sigue dando 7 por aquí. 00:11:34
A ver si con varias, 7, 6. 00:11:37
Fijaros, aquí, esta vez me ha dado 6. 00:11:40
Las dos anteriores, 7. 00:11:43
7, ¿veis? 00:11:45
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. 00:11:46
Esto quiere decir que diferentes secciones de un programa se pueden ejecutar de forma concurrente al mismo tiempo. 00:12:13
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. 00:12:21
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. 00:12:27
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. 00:12:38
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. 00:13:04
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. 00:13:16
poner un sleep, duérmete durante, y aquí ponemos 00:13:25
en milisegundos el tiempo que queramos que se duerma, vamos a poner por ejemplo 00:13:30
3 segundos, 3000 milisegundos, es obligatorio meter esto 00:13:34
entre una estructura de try-catch, la gestión de excepciones 00:13:38
que veremos en otro tema, para que me compile 00:13:43
me ayudo del IDE con el botón derecho, me lo ofrece 00:13:46
y fijaros que ahora en la secuencia de ejecución se va a dormir aquí 00:13:50
este proceso tres segundos para que estoy metiendo estos tres segundos para que esa competición 00:13:54
paralela que hay entre el recolector de basura y mi programa le esté vaya pues se duerma aquí 00:14:00
tres segundos y tengamos la garantía de que el recolector de basura se ejecuta antes entonces 00:14:05
ahora si damos aquí a ejecución yo creo que pasan 23 veis y seis personas ahora ya con estos tres 00:14:10
segundos le hemos dado tiempo a que el recolector de basura vamos a hacer varias ejecuciones pero 00:14:19
en principio nunca pierda en esa competición para ver cuál de los dos acaba antes. 00:14:23
Voy a mostrar aquí 6, fijaros que aquí tenemos un lazo de tiempo hasta que me saca el tercer 00:14:28
mensaje que corresponde a estos 3 segundos, en ese tiempo el recolector de basura habrá 00:14:33
hecho su tarea, que lo estamos forzando aquí, y habrá llamado al método finalice de la 00:14:38
clase persona y a todos los métodos finalice de objetos que pudiera haber pendientes de 00:14:43
limpiarse, me hace el decremento del número de personas y por eso 00:14:48
ya me vuelve a mostrar 6 aquí. Hagamos otro par de ejecuciones 00:14:53
y otra más. Estos 3 segundos de tiempo, veis 6. 00:14:57
Aquí ya gana todas las veces el recolector de basura. Fijaros como 00:15:14
ahora tenemos aquí comentado el finalice, o sea que realmente es el recolector de basura 00:15:18
quien está llamando a través de esta invocación que hacemos, quien está 00:15:22
llamando al método finalice. Y luego otra 00:15:26
cosa que podemos probar también, mirad, antes de nada vamos 00:15:30
a hacer algo más para estar seguros, aunque bueno, no parece que haya 00:15:34
mucho margen de duda, pero para estar seguros que el decremento del número de personas 00:15:38
se está haciendo aquí en el método finalice, podemos poner aquí un 00:15:42
system.out.println, una traza, ejecutando 00:15:46
vamos a poner aquí el método finalice 00:15:56
vamos a ejecutar de nuevo, invocamos el recolector de basura 00:16:00
pasan los tres segundos fijaros como el recolector de basura habrá llamado al finalice la clase 00:16:10
persona nos ha mostrado la traza que hemos puesto aquí y luego ya pues nos muestra esta traza en la 00:16:16
cual considera que hay seis personas que todavía siguen activas que son las seis que hemos dado de 00:16:24
alta por aquí estas cinco y esta sexta y la séptima que habíamos dado aquí de alta como ya desapareció 00:16:29
de su ámbito no está siendo considerada en el programa recolector de basura limpia la memoria 00:16:35
que tenga disponible y hace la ejecución que hayamos puesto nosotros en el método finalice 00:16:41
a modo de instructor del objeto una prueba más que podemos hacer para intentar yo probé en casa 00:16:47
y me funcionaba si nos va también aquí es intentar forzar que se ejecute el recolector de basura pero 00:16:56
sin hacer nosotros una llamada de forma explícita aquí entonces para esto lo que hice fijaros quito 00:17:04
la llamada al recolector de basura, si quito la llamada al recolector de basura 00:17:15
volvemos a la secuencia que estábamos antes 00:17:19
en la cual el programa termina tan rápido sin que se haya 00:17:21
llamado el recolector de basura que nos dará 7 aquí 00:17:24
todas las veces, vamos a hacer un par de ejecuciones 00:17:28
fijaros, 7, 7 y una tercera 00:17:30
7 todas las veces, fijaros, por aquí 00:17:36
y lo que hice fue aquí 00:17:39
donde estamos dando de alta un objeto 00:17:42
lo que podemos hacer es dar de alta 00:17:46
pues bastantes objetos, entonces para hacer esto 00:17:49
lo que podemos hacer es poner aquí un bucle 00:17:52
while on for 00:17:57
int i igual a cero, mientras 00:17:59
i sea menor de cien, vamos a poner por ejemplo 00:18:06
vamos a hacer un i más más 00:18:10
disculpad la tos, estoy un poquito con la garganta ahí tocada 00:18:13
entonces lo que estoy haciendo aquí es dar de alta 00:18:27
100 personas, luego, bueno vamos a dar de alta 00:18:30
más, vamos a dar 1000 00:18:32
personas, si no, luego vemos a ver que pasa 00:18:33
bueno, vamos a ver que pasa 00:18:36
damos de alta 1000 personas 00:18:45
que desaparecerán 00:18:47
luego aquí, en este ámbito 00:18:49
vamos a poner aquí un thread sleep 00:18:51
que tarde un milisegundo 00:18:53
para que no se nos quede colgado 00:19:03
dejamos 00:19:05
un milisegundo entre la ejecución de cada una de las personas 00:19:05
vamos a hacer una primera prueba, noto claro 00:19:09
que como he puesto el código no vaya a funcionar si no hacemos alguna variante ahora mil seis 00:19:11
personas me ha dicho por aquí vamos a poner este for pero en lugar de aquí vamos a poner aquí os 00:19:22
cuento ahora lo que voy a hacer va a ser llamar mil veces a este método para que dé de alta mil 00:19:47
personas y desaparezcan en cada una de las llamadas está dando de alta a una persona 00:20:04
y aquí vamos a poner otro bucle. En cada una de las entradas 00:20:10
quede de alta mil personas. Llamamos mil veces a este método 00:20:14
y cada vez da de alta mil personas. Con lo cual ya estamos dando de alta 00:20:26
un millón de personas antes de que se acabe el programa. A ver si saturamos 00:20:41
la memoria RAM y automáticamente como cada mil 00:20:44
van quedándose liberadas porque en cada llamada las mil personas 00:20:48
que damos de alta cuando llamamos aquí dejan de estar en el ámbito 00:20:53
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. 00:20:56
y al recolector de basura de forma explícita 00:21:17
yo ya no lo estoy llamando, lo está llamando la máquina virtual 00:21:20
y fijaros como 00:21:22
al hacer 00:21:24
reserva de muchos objetos 00:21:25
de la clase persona que terminan su ámbito 00:21:28
aquí, en cada una de las llamadas 00:21:30
de las mil llamadas que hago aquí y reservo mil personas 00:21:32
pues habrá un momento en el que la máquina 00:21:34
virtual se dé cuenta que estamos ocupando 00:21:36
mucha memoria RAM y dirá 00:21:38
vamos a liberar y empezará a llamar 00:21:40
al recolector de basura y ese recolector de basura 00:21:42
está ejecutando el método 00:21:44
finalice y cada una de estos de estas trazas que tenemos aquí de ejecutando el método finalice 00:21:46
supone que una de las personas ha salido del programa y en cada una de las llamadas a método 00:21:53
temporal fijaros está dejando de estar en su ámbito cuando termina hasta mil personas que 00:22:02
tenemos aquí por eso nos sale en ejecutando el método finalice tantas veces en definitiva el 00:22:07
método final y el recolector de basura se ejecuta cuando le viene bien a la máquina virtual de java 00:22:17
la llamada al recolector de basura implica que todos los objetos del programa que dejen de ser 00:22:24
operativos porque han salido de su ámbito ejecutarán su método finalice podemos tenerlo programado como 00:22:32
aquí o no tenerlo programado si no lo tenemos programado en cualquier caso este método siempre 00:22:39
existe pero tendremos uno heredado de la clase object de la parte de arriba que hará poca cosa 00:22:43
más allá de liberar la memoria ram si nosotros desde el código queremos asegurarnos que se 00:22:51
ejecuta el recolector de basura independientemente de cuando lo haga la máquina virtual tenemos a 00:23:00
nuestra disposición el mes del método si éste en jefe qué bueno pues prácticamente de forma 00:23:05
inmediata llama al recolector de basura y el recolector de basura ejecutará todos los finalices 00:23:11
y si queremos comprobar que sea un poco queremos forzar el hecho de que se llame el recolector de 00:23:16
basura a través de la máquina virtual lo podemos hacer es algo como lo que hemos hecho aquí hacer 00:23:25
una reserva así bruta de objetos que desaparezcan de su ámbito de ejecución para que sean candidatos 00:23:30
a que se les llame por el recolector de basura y crear muchos aquí un ford de 0 a 1000 y otros 00:23:37
ford de 0 a 1000 con lo cual el programa en sí intentaría ejecutar crear un millón de objetos 00:23:45
de la clase persona y como veis cuando la máquina virtual se da cuenta que empieza a ver mucho uso 00:23:51
de memoria ram pues empieza a llamar el recolector de basura y el recolector de basura cada uno de 00:23:56
los métodos finalice alguna cosa si alguna duda se ve se entiende si se entiende paso ya otra cosa 00:24:01
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 00:24:13
que se suele utilizar más bien poco así que vale pues pues mirad más cosas que os quería contar 00:24:22
normalmente cuando tenemos un método tenemos la posibilidad desde desde la llamada al método de 00:24:31
recibir una respuesta desde donde se está llamando a cómo ha ido la ejecución vamos a volver al 00:24:41
por ejemplo a esta prueba que habíamos abierto antes 00:24:50
o no sé, bueno 00:24:53
vamos a crear un nuevo proyecto 00:24:55
teoría, vale pues ahí tenemos la clase 00:24:58
de teoría, vamos a meter en main 00:25:25
mirad cuando 00:25:30
definimos métodos 00:25:40
tenemos la posibilidad de decir que este 00:25:42
método devuelva algo y esto 00:25:47
que devuelva algo más allá de los constructores 00:25:48
que no devuelven nada pero no lo indicamos 00:25:51
si no devuelve nada 00:25:53
ponemos un void y si devuelve algo 00:25:55
ponemos por ejemplo int 00:25:57
devuelve 00:25:58
int, vamos a poner aquí, vamos a llamar al método, entonces tenemos aquí 00:26:00
que por aquí podríamos recibir parámetros 00:26:08
de como devuelve algo, se nos queja porque no tiene un return 00:26:12
vamos a poner un 1 de momento, vale, ya nos compila 00:26:15
tenemos desde en la zona donde llamemos al método, tenemos la posibilidad de 00:26:21
pasarle información que tenemos aquí disponible a través de 00:26:25
los parámetros de entrada, como ya conocemos, y tenemos la posibilidad de que 00:26:29
tras su ejecución, disponer de cierta información 00:26:33
de cómo ha ido la ejecución, por ejemplo, este 1 que estamos haciendo aquí 00:26:36
un return, en el método desde donde se está 00:26:39
llamando, en este caso el main, para seguir procesándolo. 00:26:42
Por ejemplo, podría ser que si devuelve 0 es que ha ido bien la ejecución, 00:26:45
si devuelve 1 es que se ha dado un error en el acceso a un fichero. 00:26:48
Pondríamos return 0 o return 1 según haya ido 00:26:51
la ejecución esta, que haya sido correcta o con ese 00:26:54
error que comentábamos al acceso al fichero. 00:26:56
fijaros que la posibilidad de devolver aquí algo bueno pues es un poco escasa porque imaginaos que 00:26:59
en el método quisiéramos devolver dos cosas vamos a llamar este método recoger info por ejemplo y 00:27:09
imaginaros que estamos recogiendo una edad de una persona y un nombre pues vale pues entonces aquí 00:27:19
podríamos devolver un es un entero que fuese la edad o podríamos devolver un string que fuese el 00:27:29
nombre pero a la vez no podemos decir que devuelva las dos cosas como podríamos saber qué podríamos 00:27:37
hacer aquí pues fijaros aquí lo que podríamos hacer es si tenemos que esa información se la 00:27:43
vamos a meter a un objeto por ejemplo de una clase persona una clase persona aquí esta persona que 00:27:49
tenga precisamente esto que decimos y edad como atributos tiene ese nombre una primera cosa que 00:27:58
podríamos hacer sería decir que devuelva un objeto de la clase persona pero si devuelve un objeto de 00:28:09
la clase persona aquí podríamos decir que podríamos dar de alta una persona persona ni per igual año 00:28:15
persona, decir mi per 00:28:29
imaginaos que lo cogemos desde teclado como fuese, no vamos a entrar ahora con el 00:28:39
escáner, pero bueno, de alguna forma recogeríamos la edad, 10 años 00:28:43
mi per punto ese nombre 00:28:47
y decir que esta persona, por ejemplo, se llama Noah 00:28:50
y luego aquí haríamos un return de mi per 00:28:54
fijaros como esto, bueno, pues va bien la cosa 00:28:58
devuelve un objeto de la clase persona definimos mi per como un objeto de la clase persona hemos 00:29:02
trabajado a por aquí con el algoritmo para que sería a través de escáner o como correspondiese 00:29:09
para esos datos rellenar sus atributos y luego que devolvemos un objeto de la clase persona que 00:29:13
efectivamente es lo que se espera aquí aquí si queremos trabajar con esta persona pues que 00:29:19
podríamos hacer pues fijaros podremos y decir persona per aus de alguna forma fijaros que aquí 00:29:26
no voy a hacer un new porque porque mi idea es que ahora voy a llamar a recoger info este se hará un 00:29:33
new verdad reservará en la zona de memoria ram un espacio para guardar la edad y el nombre vamos a 00:29:42
suponer que es en la memoria ram la posición la que le diga el sistema operativo 35.000 por decir 00:29:49
una que será la que la que decía el sistema operativo y en este reto lo que estoy haciendo 00:29:56
devolver esta posición de memoria que corresponde a un objeto de la clase persona aquí en la posición 00:30:02
35.000 habrá hecho una reserva de espacio suficiente para guardar edad y nombre con lo 00:30:09
cual irá desde la 35.000 y vamos a hacer una suposición será hasta la posición que sea 00:30:22
Vamos a suponer que desde la 35.000 hasta la 35.050, por decir algo. 00:30:27
Entonces, aquí cogemos, definimos una referencia, un dedito que apunta a una persona, 00:30:34
pero no hacemos el new, con lo cual no estamos reservando espacio de memoria para esta persona. 00:30:39
Aquí lo que diríamos sería que per aus sea igual, vamos a definir este método static, 00:30:43
porque lo estamos llamando desde main que es static, 00:30:51
para no tener necesidad de estar creando objetos de la clase tutoría. 00:30:53
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á. 00:30:58
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. 00:31:12
lo que estamos haciendo es decir que sea igual a lo que devuelva este método y este método tiene 00:31:21
una referencia a una persona a la que le hemos dado estos dos valores que hemos hecho la suposición 00:31:28
de que el sistema operativo ha dicho que apunta a 35.000 con lo cual de esta forma per aus pasa a 00:31:35
tener la posición de memoria ram 35.000 con lo cual per aus punto y edad es previsible que nos 00:31:41
devuelva un 10 y per aus ese nombre nos devuelva no si cogemos hacemos aquí un sistema punto out 00:31:50
punto println de per aus punto y edad más tenemos esta ejecución fijaros como el programa nos muestra 00:31:58
edad 10 y nombre no estamos utilizando per aus que en verdad es algo que es capaz de apuntar 00:32:38
una persona, para este no hemos hecho el new 00:32:45
pero hemos aprovechado que 00:32:47
hemos hecho que per aus apunta al mismo sitio 00:32:49
donde apuntaba mi per 00:32:51
es algo parecido a lo que hacemos 00:32:53
con el constructor copia 00:32:55
hacer que apunten unos registros a otros 00:32:56
veis esta asociación 00:32:59
de posiciones de memoria 00:33:04
que permite que per aus 00:33:06
y que mi per apunten a la misma 00:33:07
persona, bueno 00:33:10
estarían repetidas, si, sería 00:33:22
todas las referencias a objetos 00:33:24
todo habría un montón de deditos que los hemos definido como referencias a personas y todos 00:33:27
ellos estarían apuntando a la misma posición de memoria con lo cual sería sería la misma 00:33:33
información vendría a ser mira aquí por ejemplo aquí pero ahora mismo ya apunta a 35.000 pues 00:33:39
si nosotros cogemos y hacemos aquí persona per aus dos que sea igual a per aus fijaros que no 00:33:47
estoy diciendo, no estoy haciendo un new para esta persona, con lo cual estoy 00:33:56
definiendo un dedito que apunta a una persona, un puntero, un indicador 00:34:00
y le decimos, si esto lo partimos en dos instrucciones y lo ponemos así 00:34:04
aquí apuntaría null, lo juntamos, vale 00:34:09
y al igualarlo a este, pues pasará a apuntar también a la 00:34:12
zona de memoria RAM donde está apuntando peraus, que además lo ha recogido 00:34:16
de cuando hicimos este new, con lo cual también apuntaría a ese supuesto 00:34:21
35.000 que será el que sea vale según el sistema operativo entonces si cogemos aquí hacemos esto 00:34:25
y ahora aquí ponemos pero los dos veremos que también no vuelva a sacar los mismos datos pero 00:34:31
espera los dos y miper los tres apuntan al mismo sitio ambos dos dicen esto en verdad cuando 00:34:40
estamos ejecutando este código esta referencia ya ha desaparecido ha desaparecido con lo cual 00:34:48
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. 00:34:56
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. 00:35:12
dos punteros cuando pasa del recolector de basura enlazando con lo que comentábamos antes cuando hay 00:35:28
una zona de memoria a la cual no apunta ya nadie aunque mientras siga apuntando a alguien a esa 00:35:33
zona de memoria porque sigue disponible esa persona aunque no sea la que inicialmente se 00:35:40
utilizó para hacer el new el recolector de basura no lo considera para liberar esa memoria porque 00:35:46
si lo llamase aquí el recolector de basura y se perdiese la persona de 35.000 aquí dejaríamos de 00:35:50
tenerla disponible entonces mientras haya alguien que esté apuntando a esa zona de memoria continuará 00:35:56
funcionando y si el recolector de basura ni liberará la memoria ni llamará al finalice 00:36:02
bueno entonces una posibilidad de devolver más de un valor a través de un método antes estábamos 00:36:06
contraponiendo lo a lo que decíamos antes cuando habíamos definido el método este y habíamos dicho 00:36:18
que hiciera un retorno en lugar de esto habíamos dicho un índice decíamos aquí solamente devuelve 00:36:24
el la edad si ponemos un string solamente devuelve el nombre no podemos devolver los 00:36:30
dos pues una técnica es si tenemos una clase en la cual tenemos varios atributos lo que devolvemos 00:36:36
es una referencia a un objeto de esa clase y podremos cargarlos con varios datos y luego 00:36:44
tenemos si tenéis dudas o no se entiende me decís vale que esto a las hablar de la memoria a veces 00:36:52
cuesta siempre un poco entonces mejor dejarlo claro aunque avancemos menos pero que lo que 00:37:00
avancemos pues que os vayáis enterando bien pero imaginaros que decimos esto me parece muy bien que 00:37:06
aquí devuelvas un objeto una persona pero es que yo quiero que el método recoger info me devuelva 00:37:17
si la ejecución de este método ha ido bien, yo quiero que me devuelva un código numérico 00:37:23
vamos a hacer otro método, diciendo que esto devuelva 00:37:28
un entero, int, con lo cual 00:37:35
si llega hasta aquí, la ejecución, que me devuelva un 0, o me devuelva 00:37:44
si ha habido un error en un momento dado, que me devuelva un 1, o otro tipo de error, un 2 00:37:48
es decir, quiero un código de errores numérico 00:37:52
y que me lo devuelva a través del return, en este caso, lo que haríamos sería 00:37:56
poner hacer la llamada a recoger info 2 en este caso y se lo cargaríamos y valor devuelto 00:38:00
a una variable de qué tipo tiene que esta variable de tipo entero porque porque hemos dicho que lo 00:38:16
devuelve que lo que devuelve es un entero como devuelve este método es entero a través de la 00:38:21
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. 00:38:27
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. 00:38:47
¿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. 00:39:05
Entonces decimos persona, vamos a llamarlo miPer aquí y voy a quitarla de aquí. 00:39:19
Entonces lo que podemos hacer aquí es coger y antes de la llamada definir una persona, 00:39:35
persona per tercera. 00:39:41
En este caso sí que hago una reserva de memoria, new persona. 00:39:47
entonces aquí estoy haciendo definiendo una persona 00:39:51
per tercera y vamos a suponer que 00:39:57
como estoy haciendo un new, el sistema operativo me devuelve 00:40:01
una zona de memoria donde reservar espacio 00:40:03
para esta tercera persona, vamos a suponer que es la posición 00:40:06
40.000, ya os digo que esto es simplemente 00:40:09
para seguir con el ejemplo y hablar de una referencia 00:40:12
de memoria RAM que será la que sea, la que es el sistema operativo 00:40:15
esta tercera persona la pasamos 00:40:18
por aquí como atributo, fijaros como 00:40:21
como parámetro fijaros como este método recibe un objeto una referencia un objeto de la clase 00:40:24
persona qué referencia es esta per tercera que es lo que valdrá per tercera punto y edad de momento 00:40:31
valdrá cero porque no hemos dado valores y p tercera punto ese nombre valdrá comillas comillas 00:40:41
está inicializado las dos variables probablemente pero eso es punto y edad y punto ese nombre pero 00:40:47
per tercera que vale una posición de memoria 40.000 qué es lo que pasa cuando le pasamos 00:40:55
parámetros a información a través de los parámetros de entrada a un método que la 00:41:00
información que tiene aquí se copia aquí si aquí cogemos y le pasamos por poner un segundo 00:41:08
parámetro que nos resulte más familiar, ponemos int p, pues resulta que este 2, ¿verdad?, se copia en el primero 00:41:14
de los atributos en la p, con lo cual p valdrá 2. ¿Qué sucede con mi per, que es una referencia, un puntero, 00:41:27
una clase persona? Pues que cogerá el valor que le estamos pasando, entonces aquí, que será el valor que tenga 00:41:35
per tercera, entonces aquí en el momento de ejecutar para estas dos variables que se reciben como parámetros 00:41:41
y actúan como variables locales dentro de este método, resulta que lo que tenemos es que p será igual a 2, 00:41:47
no vamos a utilizar p, pero bueno, lo he puesto por poner un segundo parámetro diferente al de persona, 00:41:56
y mi per será igual a 40.000. 40.000 vale mi per porque 40.000 hemos supuesto que es la zona de memoria 00:42:00
que ha asignado a la referencia per tercera a través del new del sistema operativo. 00:42:12
entonces y ahora pongo yo aquí mi per y edad sobre qué edad estará actuando 00:42:17
sobre la edad relacionada con un objeto de la clase persona 00:42:23
que en la memoria RAM está siendo apuntada por mi per 00:42:27
mi per es 40.000 y de la misma forma para un nombre 00:42:31
para una variable nombre que forma parte de los atributos de una clase persona 00:42:36
que está siendo apuntada por mi per 00:42:43
que en memoria RAM, según hemos visto, está en la posición 40.000. 00:42:45
Aquí devolvemos un return cero, que se devuelve por aquí y se carga aquí, ¿verdad? 00:42:51
Pues perfectamente, ahora podríamos decir aquí, if evalDef es igual a cero, 00:42:56
según el código que tengamos definido, pues aquí podríamos hacer una serie de cosas 00:43:05
como que la ejecución de este método ha ido bien. 00:43:09
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. 00:43:12
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í. 00:43:27
pues efectivamente lo tenemos en mi per y edad mi per ese nombre aquí que apuntaba al 40.000 00:43:52
una vez que termina esto, este punterito que apunta a memoria rana a la posición 40.000 00:43:59
ya no tiene sentido porque su ámbito de ejecución, estas variables hemos dicho que actúan como locales al método 00:44:07
dejará de existir esta referencia, pero a partir de la ejecución cuando llegamos aquí 00:44:13
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, 00:44:18
con lo cual por aquí sigue disponible. 00:44:30
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, 00:44:32
y aquí decimos per tercera, vamos a poner aquí esto para distinguerlo de los otros mensajes, 00:44:46
desejecutamos y fijaros como me dice que la edad es 10 y que el nombre es no A, 00:45:05
es decir, hemos hecho una pequeña trampa a través de un parámetro de entrada, 00:45:09
aprovechando que lo que se pasa es la referencia, la memoria RAM, cuando pasamos referencias a objetos, 00:45:14
para modificarlo aquí, que era donde correspondía recoger la información, 00:45:20
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í. 00:45:24
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. 00:45:38
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. 00:45:53
este que es un entero pues que copian esta variable p se copia un 2 con lo cual p vale 2 00:46:35
per tercera que es lo que vale pues per tercera vale una zona de memoria imaginaos que el sistema 00:46:42
operativo al hacer este niño como siempre ha dicho a partir de la posición 40.000 de memoria ram 00:46:49
tengo suficiente espacio como para reservar trocitos y meter las variables de la edad y 00:46:55
el nombre de esta persona que está 00:47:02
dando de alta. Entonces vamos a suponer que en el 00:47:04
mismo 40.000 00:47:06
está 00:47:08
a partir de esa posición, que es donde empieza 00:47:10
el espacio que ha reservado en memoria 00:47:13
RAM, es donde metemos la edad 00:47:15
y vamos a suponer, 00:47:16
no me acuerdo exactamente de qué espacio ocupa 00:47:18
un entero, pero vamos por hacer una 00:47:21
suposición también, que a partir del 40.020 00:47:22
es donde 00:47:25
se puede meter el nombre. 00:47:26
Si tú coges y haces 00:47:33
ahora aquí 00:47:34
un system of println 00:47:36
como este, cuando 00:47:40
vaya de la 00:47:47
edad de la per tercera, cuando vaya 00:47:49
aquí, se irá a la posición 00:47:51
empieza aquí el objeto 00:47:52
persona, la edad justo 00:47:55
en el punto donde empieza, pues irá a la posición 00:47:56
40.000, cogerá el valor del entero 00:47:59
que hay ahí y lo mostrará aquí 00:48:01
y cuando mostramos aquí per tercera 00:48:02
ese nombre, pues irá, dirá, vale 00:48:05
El 40.000, per tercera, empieza en la posición de memoria RAM 40.000. 00:48:06
Lo desplazo, lo que me ocupa un entero, que hemos hecho un supuesto de que es 20, ¿vale? 00:48:13
Y entonces me voy al 40.020, que es donde está el nombre, 00:48:17
y apoyándome en el 40.020, muestro el nombre que tenga. 00:48:21
Aquí, como no lo hemos modificado, todavía mostraría cero y comillas, comillas. 00:48:25
Como aquí lo que pasamos es la información que tiene, 00:48:32
la información que tiene se copia en el método, 00:48:36
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. 00:48:38
entonces mi per 00:48:51
valdrá 00:48:54
posición de memoria 40.000 00:48:55
donde debe haber una reserva para una 00:48:57
persona, entonces cuando yo pongo aquí 00:49:00
mi per punto y edad 00:49:02
pues irá a la posición de memoria RAM 00:49:04
40.000 y 00:49:06
con el desplazamiento de la edad que es lo 00:49:07
primero en la posición 40.000 00:49:10
40.000 que es 00:49:12
hiper, mi per 00:49:15
que coincide 00:49:17
con 00:49:19
per tercera, porque es el valor que se ha copiado aquí 00:49:21
como parámetro de entrada, más 00:49:26
el desplazamiento 00:49:29
de la edad, que hemos supuesto 00:49:31
que la edad justo está en la misma posición 00:49:35
parte del mismo punto en el que hemos reservado la memoria 00:49:38
pues en la posición 40.000 de la memoria RAM 00:49:41
está metiendo un 10, en la pos 00:49:44
40.000 está metiendo 00:49:47
un valor 10 con esta asignación 00:49:50
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. 00:49:53
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. 00:50:14
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. 00:50:30
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í. 00:50:53
por eso al imprimir aquí per tercera y edad nos saca este 10 y cuando imprimimos esto pues hemos 00:51:19
dicho que per tercera apunta a la posición 40.020 que justo coincide con la 40.020 donde habíamos 00:51:26
puesto no a y todo es consecuencia de que mi per es un puntero que está apuntando al mismo sitio 00:51:32
que per tercera que hemos definido aquí entonces por eso este nombre me muestra no no sé si aclara 00:51:38
vale pues nada esto es una posibilidad de en conclusión lo que hay que tener claro es que 00:51:50
como principio es que esta variable está apuntando al mismo sitio donde estaba apuntando está por lo 00:52:09
cual son dos deditos que apuntan a la misma posición de memoria los cambios que hagan una 00:52:17
pues se aplicarán a la otra fijaros un poco redundando ya por un poco más en las posiciones 00:52:22
de memoria quizás como previo a todo lo que os he contado aunque lo cuenta ahora después imaginaos 00:52:32
que tenemos una persona pero una persona este perú no digo y edad que tenga 20 años ahora digo persona 00:52:41
per 2 igual a per 1 falta el igual aquí si yo pongo aquí un system out lógicamente esto me 00:52:59
sacará un 20 no con este código define una persona le pongo que tenga de valor 20 y le digo con 20 00:53:29
pues ya está lógicamente sacar un 1 dentro de nuestras suposiciones del sistema operativo pero 00:53:34
no vamos a entender que va nos ha dado espacio en la memoria ram de la posición 40.000 o la 00:53:40
50.000, por decir una diferente a la de antes. 00:53:47
¿Por qué nos ha dado una zona 00:53:52
de memoria reservada? Porque le hemos hecho un new. 00:53:53
Si no le hacemos un new, no nos da 00:53:56
una zona de memoria reservada. 00:53:57
Si aquí yo cogiese e hiciese esto, 00:53:59
¿aquí qué estaríamos haciendo? Pues mirad, 00:54:09
aquí, por ejemplo, bajo nuestro supuesto 00:54:11
estaría per 1 apuntando a 50.000 00:54:13
y aquí 00:54:15
estamos haciendo otro new, 00:54:17
pues buscaría en memoria RAM y diría 00:54:19
que per 1 apunte ya 00:54:21
a otro espacio, a 55.000. 00:54:22
perderíamos la referencia de este per1. 00:54:25
Si aquí pusiésemos per1 igual a 20, 00:54:30
si hacemos esto, perdemos cualquier referencia 00:54:35
porque ya no tenemos nada que esté apuntando a per1. 00:54:37
No tendríamos la posibilidad de mostrar por pantalla este 20. 00:54:41
Si per1 apunta a 50.000 y le damos un valor a la edad de 20, 00:54:46
si per1 lo sobreescribimos y le damos otra posición de memoria, 00:54:51
le da otra posición de memoria al sistema operativo 00:54:55
porque le estamos haciendo otro new 00:54:58
¿qué posibilidad tenemos de recuperar este valor? 00:54:59
si lo único que teníamos para llegar a la edad 00:55:02
era que per 1 apuntaba a 50.000 00:55:04
lo habríamos perdido 00:55:07
en cambio si hacemos esto, fijaros 00:55:08
ahora per 2 00:55:12
¿a dónde estaría apuntando? 00:55:16
a per 1 00:55:19
per 2, ¿dónde estaría apuntando? 00:55:20
a 50.000 00:55:22
si hacemos un per 1 new 00:55:23
este per 1 lo perdemos 00:55:30
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é? 00:55:33
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. 00:56:07
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. 00:56:22
si yo cojo y hago persona 2 persona 2 sí que me indica que vale 20 porque porque es el que está 00:56:39
apuntando realmente a 50.000 poco la gestión de las posiciones de memoria cuando hacemos 00:56:51
asignaciones sin hacer news lo que estamos asignando es posiciones de memoria que es un 00:57:00
poquito lo que nos está pasando aquí está pasando la posición de memoria aquí por eso aquí dentro 00:57:05
trabajamos con el objeto del cual hemos hecho un new en esta fue en esta zona de código bien más 00:57:12
o menos bueno os cuento si no si no me paráis con esto no hace ninguna pregunta por ahí que 00:57:23
tengáis alguna duda os cuento otra de las cosas que hay por el código que es pasar variables por 00:57:35
argumento a un método bueno variables pasar un array métodos que admiten un número de parámetros 00:57:42
que no está definido el número no le ponemos título mejor vamos a hacerlo porque si no os 00:57:51
más lío, voy a limpiar esto 00:58:00
vamos a definir un public static 00:58:07
que no devuelva nada 00:58:11
numpar, bueno este método 00:58:14
nada nuevo nos dice verdad, un método 00:58:35
no devuelve nada, recibe un parámetro 00:58:39
para llamar este método 00:58:42
no estamos definiendo objetos para llamarle porque estamos llamándole 00:58:44
de un sitio static a otro sitio static 00:58:48
entonces hacemos numpar 00:58:50
Pasamos un 2, por ejemplo, como es un entero, se ejecuta y aquí nos muestra el 2, nada nuevo. 00:58:56
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. 00:59:02
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. 00:59:22
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. 00:59:32
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. 00:59:42
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, 01:00:14
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, 01:00:37
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. 01:01:01
¿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. 01:01:29
Entonces fijaros como para este me está compilando, me está gustando, le va bien 01:01:48
Bueno y este, incluso este, fijaros, este compila y funciona porque recibe, le pasa un número 01:01:52
Que se carga aquí en P y luego no le pasa ninguna cadena de caracteres, es decir, cero strings 01:02:02
Este le pasa un número y le pasa una cadena de caracteres 01:02:07
Pues el 2 y una cadena de caracteres 01:02:11
Y vamos a poner otro que le pase por ejemplo 2 01:02:20
¿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. 01:02:23
¿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. 01:02:35
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. 01:02:49
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. 01:03:07
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. 01:03:22
para los arrays puedes utilizar el bucle for each 01:04:06
bucle for each apareció 01:04:09
en una versión 01:04:11
a partir de una determinada versión de java 01:04:13
apareció la opción 01:04:15
del bucle for each, antes eran todos for 01:04:17
for each te recorre todos 01:04:19
los elementos de un array 01:04:21
o de una colección 01:04:23
el for te da la opción 01:04:25
de hacer lo mismo que el for each 01:04:27
y te da una posibilidad añadida porque con un 01:04:29
for each, imaginaros que 01:04:31
tienes un array con tres elementos 01:04:33
Para recorrer los tres elementos lo podéis hacer de esta forma. 01:04:38
Justo este bucle, ahora lo terminamos de completar, nos permitiría esto. 01:04:41
Con un for each te recorre esos mismos tres elementos, 01:04:47
que es por cada uno de los elementos del array, 01:04:50
pues hazme la ejecución y ejecuta para cada uno de los elementos 01:04:53
el código que se ponga aquí dentro. 01:04:57
Un for each te recorre todos, todos los elementos, 01:05:00
pero imaginaros que es perfecto, 01:05:02
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? 01:05:06
Pero imaginaos que solamente queréis recorrer del array uno sí y uno no. 01:05:14
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, 01:05:19
lo podréis hacer aquí, un i igual a i más 2, y directamente ya va dando saltos de 2 en 2. 01:05:32
O sea, el for te da un poquito más de versatilidad. 01:05:39
Pero el for each está bien también, no es que lo quiera demonizar. 01:05:43
Yo estoy muy acostumbrado a utilizar el for en lugar del for each, 01:05:48
porque como estaba desde antes y ya llevo unos cuantos años programando, 01:05:50
pues yo siempre se me va la mano al for, pero sería válido. 01:05:55
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. 01:05:57
la primera entrada en este for va a ser con el valor de inicializado a 0 y ahora lo voy a 01:06:27
utilizar como índice aquí en el array entonces para que me diga atributo 1 y no me diga atributo 01:06:33
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 01:06:38
aquí en lugar de poner un 0 un 1 o lo que sea para que me de siempre lo mismo pues aprovecho 01:06:54
la variable y que estoy utilizando en el bucle entonces aquí vamos a poner un system ahora aquí 01:06:58
primera llamada para diferenciarlos un poco y aquí pongo un barra n para dejar una línea entre medias 01:07:12
segunda llamada entonces si le damos aquí ejecutar pues nada fijaros en la primera la primera llamada 01:07:22
durante la primera llamada se hace con un par aquí le estoy diciendo que me muestre el valor de p 01:07:56
p es el entero este, me dice un 2 01:08:01
y no me muestra ningún string 01:08:04
¿por qué? pues porque no le pasó ninguno 01:08:06
la segunda 01:08:08
llamada, pues estábamos haciéndola 01:08:10
con p de nuevo, que vale 2 01:08:12
y dentro del bucle me dice el atributo 01:08:14
que está en la posición 0 01:08:16
aquí me muestra un 1 porque le he puesto 0 más 1 01:08:18
es el que 01:08:20
tiene este s como 01:08:22
array, que es el primero de los 01:08:24
que le hemos pasado aquí como 01:08:26
parámetro de los primeros strings 01:08:27
y luego ya en la tercera llamada que arranca por aquí me muestra el 2, fijaros el 2 por aquí de nuevo 01:08:30
y me dice, una vez que está dando la vuelta al bucle, me dice el atributo 1 sola, por aquí 01:08:40
y en la siguiente vuelta, fijaros que después de la primera vuelta incrementa ahí, pasa de valer 0 a valer 1 01:08:48
con lo cual ya el sistema que me muestra es 01:08:54
1 más 1, me dice que el atributo 2 es 01:08:57
el que se encuentra en el array en la posición S1 01:09:00
en la posición S1 es adiós, que lo hemos pasado por aquí 01:09:03
entonces esto es algo que me parece que aparece 01:09:07
en el temario como 01:09:12
var args, me parece en la teoría 01:09:15
algo así pone en var args 01:09:18
o sea, hace referencia a esto 01:09:22
¿Cuántas veces podemos poner para pasarle un número variable de parámetros a un método? 01:09:23
Lo podemos poner una vez, si ponemos aquí otros puntos, pues ya no compila, no le gusta. 01:09:29
Y tiene que ir al final, tiene que ser el último bloque de atributos. 01:09:35
Podría ser así, solamente él, ya no le gusta este, claro, no le gusta toda esta llamada porque no existe ese constructor. 01:09:41
puede ser con uno, podríamos tener 01:09:49
pues que 01:09:51
recibir aquí un objeto de la clase 01:09:53
persona p 01:09:55
y luego ya 01:09:56
p no, porque es como me llamo 01:09:59
a esta otra variable, sería el mismo nombre 01:10:03
j y luego ya pues un conjunto 01:10:05
de strings 01:10:07
y el tipo puede ser strings 01:10:08
o puede ser el que sea 01:10:11
siempre el último y solo uno 01:10:12
por ejemplo podríamos pasar un número de variable 01:10:14
de personas, pues ponemos tres puntos 01:10:17
y ya está pues este método recibiría en primer lugar un entero y luego un número de variables 01:10:19
de personas que podría ser 0 1 2 3 los que donde se determina el número pues se determina en la 01:10:25
llamada según el número de personas en este caso de string que pasemos aquí será el número que se 01:10:34
cargue en la en el array y cómo podemos saber cuántos se ha pasado en cada llamada pues con 01:10:40
el atributo Length que tienen todos los Arrays. ¿Cómo podemos recorrerlo? Pues con un for de este 01:10:46
tipo o un for each. Vamos a ver, vamos a rescatarlo y vamos a hacerlo con un for each, a ver si me 01:10:52
acuerdo bien de la sintaxis, string s, lo rescatamos y el equivalente a esto del for each, 01:11:01
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, 01:11:12
a la E mayúscula, no le voy a dedicar mucho tiempo a esto 01:12:13
lo miro un segundo más, a ver si lo localizo por aquí 01:12:39
se pone for, pero el for each es así, vale, string cadena 01:12:41
dos puntos, lista, ahí lo tenemos, entonces en cada una 01:12:47
de las vueltas, en lugar de ir con el i, para este array se va cargando 01:13:07
aquí en el la información, entonces aquí no existe 01:13:11
i ya, fijaros, pues aquí ya tendríamos un inconveniente de hacerlo así 01:13:20
y la variable que utilizamos es L, que L en cada una de las iteraciones 01:13:23
se va cargando con cada uno de los valores que tiene S 01:13:30
L es un string, esto es un array de strings 01:13:33
cada vez carga su string aquí, entonces si damos aquí una ejecución 01:13:41
pues fijaros como me funciona igual. Bueno, ¿alguna duda sobre el 01:13:44
var ars este? 01:13:52
Pues nada, os paso a contar otra cosa 01:14:02
en particular esto yo creo que 01:14:05
no sé si luego lo vemos 01:14:10
más formalmente en alguno de los 01:14:11
temas más adelante 01:14:14
pero bueno es interesante 01:14:16
verlo ahora yo creo y si hace falta 01:14:17
pues luego en otro tutorial lo volvemos a repasar 01:14:20
y más vale dos veces 01:14:22
que ninguna yo creo 01:14:24
mirad 01:14:25
se trata de otra de las etiquetas que yo creo 01:14:27
que aparece también por ahí que es la etiqueta 01:14:30
abstract para en los 01:14:32
métodos 01:14:34
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. 01:14:35
Y también podemos definir métodos que sean abstractos. Publiz, abstract, etiqueta abstract, voy a poner que despedirse es abstracto. 01:15:05
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, 01:15:24
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. 01:15:57
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. 01:16:23
¿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. 01:16:54
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? 01:17:14
entonces tiene todo el sentido de que no se pueden instanciar 01:17:31
objetos de clases abstractas 01:17:34
normalmente las clases son abstractas 01:17:36
cuando tienen métodos que son abstractos 01:17:38
¿y qué sentido tiene esto? 01:17:40
pues tiene que ver con algo que habíamos hablado 01:17:45
el otro día, que ya os digo 01:17:47
que lo volveremos a ver 01:17:48
en el código, que es una característica de la programación 01:17:50
orientada a objetos, que es la herencia 01:17:53
nosotros podemos querer 01:17:54
definir un conjunto de cosas 01:17:56
en una clase que sea 01:17:59
padre, pero luego no instanciar objetos 01:18:01
de esa clase. Es decir, personas, por ejemplo, en el ámbito 01:18:03
de una de nuestras clases, pues está persona del profesor, 01:18:06
persona de los alumnos. Cada uno, todos compartimos 01:18:10
cosas comunes como personas, pues esto, edad 01:18:14
y nombre. Podemos compartir mecanismos para 01:18:19
saludar, métodos, pues podemos saludar así como saludan 01:18:22
en general las personas, aunque luego en cada una de las clases, como decíamos 01:18:27
en otras de las tutorías podríamos sobrescribirlo para particularizar 01:18:30
los profesores o los alumnos la forma de saludar 01:18:34
y luego podemos querer obligar 01:18:36
a que todo aquel que actúe como una persona 01:18:39
por herencia, es decir, que coja las características de una persona 01:18:43
esté obligado a despedirse 01:18:46
pero podemos no querer decir 01:18:49
en la clase personal cómo se tienen que despedir 01:18:52
pero sí decir, si tú quieres 01:18:54
comportarte a grandes rasgos, aunque luego 01:18:57
tras tus particularidades como alumno, siendo una clase hija, comportarte como 01:19:00
una persona, quieres tener disponibles aquellos atributos y 01:19:04
métodos que tienen las personas por herencia, aunque no te voy a decir 01:19:08
cómo, sí que te obligo, es decir, fírmame aquí un contrato 01:19:12
que por ser una persona vas a implementar 01:19:17
un código de cómo despedirte. Y eso lo conseguimos 01:19:21
de esta forma. ¿Podemos instanciar objetos de la clase persona? No. ¿Por qué? Porque no se sabe 01:19:25
cómo se despiden. Pero todo aquel que sea hijo de una clase persona estará obligado a implementar 01:19:30
un método que sea despedirse, porque como persona te tienes que despedir, aunque no te voy a decir 01:19:37
yo cómo. ¿Cómo haríamos esto? Pues mirad, vamos a definir una clase alumno. La herencia, ya os digo, 01:19:41
volveremos a verla esto sería una clase alumno normal y podemos decir vamos a vamos a hacer que 01:19:56
este alumno sea hijo de la clase persona decimos aquí stands que es la etiqueta con la que 01:20:03
identificamos la herencia de la clase persona esto implica que los alumnos más allá de los 01:20:11
atributos y métodos que pongamos aquí tendrán disponibles los atributos y métodos que tienen 01:20:19
la clase persona. Podrán saludar, si no lo sobreescribimos, tal cual saludan las personas 01:20:27
y tendrán la posibilidad de todo objeto que definamos como alumno de asignarle una edad 01:20:33
y un nombre. Y por ser una clase abstracta persona y haberlo identificado aquí, hemos 01:20:38
obligado a que el alumno tenga sí o sí que implementar el método de despedirse. Si os 01:20:46
fijáis, esto todavía no compila. Veis que el alumno lo tengo en rojito y si me pongo 01:20:52
sobre él, me dice, añade los métodos no implementados. 01:20:57
Si lo doy aquí, fijaros qué método me añade, despedirse. 01:21:03
Me está obligando, sí o sí, a que defina dentro de la clase 01:21:06
alumno el método de despedirse. 01:21:11
¿Por qué? 01:21:13
Porque toda persona tiene que tener la posibilidad de 01:21:13
despedirse. 01:21:17
Alumno como hijo de persona también lo tiene que hacer. 01:21:18
¿Y cómo se tiene que despedir? 01:21:22
Pues de saludar, no me lo ha pedido, 01:21:24
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 01:21:26
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. 01:21:32
Respecto a saludar, otra de las características de la programación orientada a objetos, los alumnos ya podrán saludar, 01:21:46
podrán despedirse, tal cual ha dicho aquí, y podrán saludar, aunque no lo tengo definido en la clase alumno, 01:21:53
por herencia de la clase Persona, tal cual está identificado aquí. 01:22:00
Y si no me gusta cómo se despiden las personas en general siendo un alumno, 01:22:05
pues tengo la posibilidad de otra de las características de la programación orientada a objetos, 01:22:10
que es sobrescribir este método. 01:22:14
Entonces, un alumno que salude, ahora ya se fijaría en su propia definición, 01:22:24
que está sobrescribiendo la general de cómo se saludan todas las personas. 01:22:28
Y para despedirse, utilizaría el único código que tiene disponible, 01:22:33
porque en la clase persona no lo tenemos al ser abstracto si se entiende mirad imaginaos que 01:22:39
seguís ahí verdad eso sí vale bueno que seguís y que se hubiera perdido la conexión quería decir 01:22:59
mirad en relación a la herencia si definimos aquí otra clase vamos a poner la clase humano 01:23:11
la clase humano podríamos decir que tiene un método public void que sea saltar vamos a decir 01:23:19
no lo defino abstracto ni nada y aquí pondríamos el código system.out.println aquí pondríamos lo 01:23:31
que correspondería a un humano para estar saltando vamos a poner que muestra por pantalla que está 01:23:44
saltando podríamos suponer que un alumno aparte de ser una persona lógicamente es un humano entonces 01:23:49
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. 01:23:59
les podría poner aquí estén persona y podría poner aquí humano pero esto no es no me compila 01:24:17
a ver qué me dice me dice que era no sé qué bueno no me compila os cuento por qué la en java aunque 01:24:27
algunos lenguajes sí que bueno pues hacen sus artimañas para poder gestionarlo en java la 01:24:36
herencia es única solamente digamos una herencia implícita que podría ser desde la clase object 01:24:41
heredando o disponiendo de 01:24:49
métodos que están definidos en la clase object 01:24:51
y en nuestro código 01:24:53
solamente podemos poner una herencia 01:24:54
única, no podemos poner herencia desde diferentes 01:24:57
clases. ¿Cuál es el motivo? 01:24:59
Pues imaginaros que 01:25:02
en la clase persona 01:25:03
yo he definido un método 01:25:05
saludar y en la 01:25:07
clase humano yo defino 01:25:09
un método saludar. 01:25:13
Si Java nos permitiese hacer herencia 01:25:18
múltiple, poner 01:25:20
que herede de persona y de humano 01:25:22
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? 01:25:24
entonces esta coincidencia hace que haya una discrepancia que no le deja elegir a los alumnos 01:25:46
cómo saludar porque lo tiene disponible por herencia desde dos sitios diferentes 01:25:53
entonces no lo permite no deja la herencia múltiple java la herencia es simple herencia 01:25:58
simple ahora sigo contando más cosas 01:26:14
volvemos un momento a las 01:26:16
clases abstractas 01:26:18
las clases abstractas tienen métodos 01:26:19
que son 01:26:22
abstractos que obligan 01:26:24
a los hijos 01:26:26
de la clase a 01:26:28
implementarlos como despedirse 01:26:30
y tiene otros métodos 01:26:31
que tienen código pues este 01:26:33
no te obligó a implementarlo si tú lo quieres implementar 01:26:36
para sobrecargarlo me parece bien 01:26:38
y si no tienes este disponible 01:26:40
una clase abstracta 01:26:42
podría tener todos sus métodos abstractos como es abstracto no le pongo código y bueno pues he 01:26:45
añadido a ese a ese choque de manos en el cual habíamos firmado un acuerdo y obligado a que 01:26:57
todos los hijos ya no sólo tengan que implementar despedirse sino también están obligados a 01:27:03
implementar saludar salvo esto y fijaros como directamente ahora alumno deja de compilar me 01:27:07
tengo implementado despedirse, fijaros que me está diciendo aquí que está 01:27:14
sobrescribiendo uno que había definido en persona 01:27:18
que no estaba implementado, si me pongo aquí me vuelve a decir 01:27:22
que añada los métodos no implementados y que me dice 01:27:26
me mete a saludar que es el que tengo ahí en el acuerdo, fijaros en este caso estamos definiendo 01:27:30
la clase persona como algo que 01:27:41
no tiene código propio y que directamente 01:27:45
es, perdón aquí, y que directamente es un acuerdo 01:27:49
para implementar una serie de métodos. Y más si todavía 01:27:54
quitamos además esto. Fijaros, simplemente dos métodos aquí abstractos. 01:27:57
No podemos implementar objetos, instanciar objetos de la clase persona 01:28:01
porque no está desarrollado su código. Y sí que estamos obligados a que 01:28:05
todo aquel que quiera ser una persona, por lo menos disponga 01:28:09
de estas funcionalidades. Cuando todas 01:28:13
es decir una clase abstracta puede tener métodos abstractos y métodos desarrollados cuando una 01:28:17
clase abstracta todos sus métodos están son abstractos esto más lo considera java como 01:28:26
un interfaz entonces si nos venimos aquí fijaros y damos año una de las opciones que nos ofrece 01:28:35
es la de interface. 01:28:43
No sé en qué método, yo creo que esto 01:28:46
todavía no lo hemos visto en la teoría. 01:28:47
Cuando llegue ya lo llevéis un poco adelantado. 01:28:49
Entonces si yo defino aquí un interface, 01:28:53
vamos a poner 01:28:55
mi inter, como si estuviéramos 01:28:55
definiendo una clase. 01:28:58
Ahora, este en lugar de ser un 01:29:01
public class, 01:29:02
pues se define public class, o sea, 01:29:04
en lugar de ser public class, pues 01:29:07
es public interface. 01:29:09
Los interfaces 01:29:12
public void saludar fijaros como una interfaz no me compila si intento decir qué código tiene 01:29:13
un método como haríamos en una clase si me pongo por aquí me dice que lo cambia estático que borre 01:29:36
el cuerpo por ser ni siquiera hay que poner la etiqueta abstract por lo que veo si ponemos 01:29:46
public astra pues tiene la consideración de método abstracto y si no yo creo que no hace 01:29:58
ni falta por lo que veo porque también me compila aquí vamos a ponerlo vamos a poner un inter 01:30:03
saludar y un inter despedir una interfaz es un acuerdo de cosas que quien utilice 01:30:13
esta interfaz va a tener que desarrollar como métodos. 01:30:27
¿Cómo se identifican los interfaces? 01:30:32
Pues fijaros, la clase alumno puede ser que herede de la clase persona, 01:30:34
de una sola clase, herencia única, no permite herencia múltiple. 01:30:39
Y podemos, para los interfaces, utilizar la etiqueta Implements. 01:30:42
Dice, la clase alumno tiene sus propios métodos por aquí desarrollados, 01:30:49
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 01:30:55
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. 01:31:04
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, 01:31:19
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 01:31:28
que tenía una clase padre, en este caso de la clase alumno. ¿Veis? Un poco esa idea. 01:31:38
¿Para qué nos sirven los interfaces? En realidad, fijaros que no tiene código aquí desarrollado, pero es una forma de obligar 01:31:52
a que las clases consideren ciertas 01:31:59
funcionalidades. Imaginaos que la clase 01:32:02
alumno es un programa como para llevarlo 01:32:05
ahí a lo grande, como os digo otras veces, que tiene 01:32:08
muchas líneas de código, tiene 60 clases, hay 01:32:11
diferentes grupos de trabajo 01:32:14
y alguien dice, mira, desde el banco 01:32:15
que os hablo a veces, un cliente, el cliente del banco 01:32:20
y dicen desde nóminas, pues yo voy a necesitar 01:32:23
conocer el DNI 01:32:26
o yo qué sé, la dirección del cliente. 01:32:29
Entonces, pueden acordar un interfaz común 01:32:33
en la clase cliente dice que implements interfaz 01:32:36
y el acuerdo ese común que tienen 01:32:40
desde donde va a ser llamado el objeto del cliente 01:32:42
para conocer su dirección y de quien lo desarrolla 01:32:46
lo definen en una interfaz. 01:32:49
No desarrollan cómo el cliente va a coger su dirección. 01:32:51
¿Por qué? Porque a lo mejor quien esté haciendo 01:32:55
el desarrollo de la clase código cliente, pues sabes si esa información 01:32:58
está en una base de datos o vete tú a saber dónde está, en un fichero 01:33:02
o se la pide un operario manualmente. 01:33:06
Desde la otra parte, desde la parte esa de, no sé si había dicho nóminas antes, 01:33:10
desde la parte de nóminas, lo que quieren es el dato de la dirección. 01:33:15
Le da igual cómo lo consiga el cliente. 01:33:17
El cliente sabe que, es decir, quiere poder pedírselo por un método 01:33:19
y que le llegue. 01:33:23
Cómo lo vaya a conseguir la clase cliente, le da igual. 01:33:24
La clase cliente sí que sabe de dónde la puede coger, que será de la base de datos. 01:33:28
Entonces dicen, el cliente, yo voy a hacer el desarrollo del código para coger esa información de la base de datos. 01:33:32
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 01:33:39
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 01:33:44
que sea def info cliente y desde el otro sitio espera conseguirlo con red de recuperar info 01:33:51
cliente pues si uno crea el método def y otro red mal vamos como llegan un acuerdo común pues 01:34:00
hacen una interfaz en la interfaz define exactamente lo que hay sin decir cómo se 01:34:06
recupera que de eso ya se encargará el cliente y el cliente como en este caso el alumno implementa 01:34:12
esa interfaz y obligatoriamente tiene que desarrollar el método de devolver la dirección 01:34:17
del cliente. Se desarrolla, se pone el detalle de cómo se recupera esa información aquí en 01:34:22
la interfaz. No, es sólo el acuerdo. ¿Quién es quien tiene que saber cómo hacerlo? Pues en la 01:34:30
implementación del cliente, que en este caso sería el alumno aquí. Sería acceder a la base de datos 01:34:35
para obtener esa información mira las interfaces os cuento estoy con esto yo creo ya vamos terminando 01:34:39
si no tenéis otras dudas vamos a crear otras una segunda interfaz inter 2 vamos a poner este método 01:34:51
vamos a poner saludar debemos dicho despedirse saludar crear mira esta interfaz nos obliga a 01:35:10
quien implemente esta interfaz que la implementación de las interfaces se hace con implement y el nombre 01:35:23
la interfaz a desarrollar un método que sea inter saludar e inter despedir esta otra interfaz quien 01:35:29
la implemente está obligado a hacer un método que sea inter saludar e inter crear a propósito 01:35:37
puesto saludar igual que aquí y despedir diferente de aquí que es crear qué pasaba antes con un mano 01:35:43
y con persona para la herencia simple que habíamos dicho que si los dos implementaban un método que 01:35:51
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. 01:35:57
fijaros que la implementación 01:36:30
sí que me la permite 01:36:32
múltiple, cuando la herencia 01:36:34
tenía que ser sencilla 01:36:35
¿por qué es esto? pues bueno, pues tiene 01:36:37
una explicación 01:36:39
muy rápida 01:36:42
al fin y al cabo, ¿qué estamos haciendo con los interfaces? 01:36:42
los interfaces tienen todas sus clases 01:36:46
abstractas, todos sus métodos abstractos 01:36:48
no estamos diciendo cómo se 01:36:50
ejecutan, aquí lo que estamos diciendo 01:36:51
en el alumno, en la clase 01:36:54
alumno al implementar estos dos interfaces 01:36:56
es que tienen que 01:36:57
para desarrollar el código para cada uno de los métodos que están definidos en el interfaz. 01:37:00
¿Que hay uno que coincide el nombre? Pues me parece muy bien, me obligas por dos lados, 01:37:04
pero no tengo discrepancia de que en un interfaz y en otro haya código que sea diferente. 01:37:08
Lo único que desde dos sitios me estás diciendo, crea el método saludar. 01:37:13
Aunque me obligues desde dos sitios, el único código para saludar que tendrá el inter saludar 01:37:17
será el que ponga aquí, por mucho que me estés obligando desde aquí y desde aquí. 01:37:22
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. 01:37:26
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. 01:37:42
¿Qué tal? ¿Cómo lo veis? ¿Alguna preguntilla? 01:37:55
Esto 01:38:06
Nada más, yo creo que, ya os digo 01:38:06
creo recordar que la herencia y los 01:38:16
interfaces aparecen luego, volvemos 01:38:18
a hacer 01:38:20
un ejercicio igual que este para volver a repasarlo 01:38:22
¿Para este próximo examen? 01:38:24
Sí, para el de febrero entra 01:38:33
hasta el tema que abre mañana 01:38:35
No me acuerdo si está ahí 01:38:37
o está más adelante, si no está 01:38:39
ahí no entra, el último 01:38:41
tema para el de febrero 01:38:44
lo que tenéis ya visible a partir de mañana. 01:38:45
Bueno, no sé si tenéis alguna cosilla 01:38:54
que me queréis preguntar más 01:38:56
o si no lo vamos a ir dejando aquí, me parece. 01:38:58
Mañana os abro el nuevo tema 01:39:04
y bueno, pues por ahí ando por los foros pendientes 01:39:05
si tenéis algunas consultas que ir haciendo. 01:39:10
Respecto a alguna cosa que alguna vez me habéis preguntado, 01:39:17
el otro día nos pasó el coordinador Juanjo, 01:39:21
nos pasó un mensaje 01:39:23
bueno, como siempre se dan 01:39:25
justificantes de asistencia 01:39:27
al examen, lo que pasa es que yo no sé 01:39:29
yo no sé si otros años también ha sido así 01:39:32
en este examen de febrero, pero sí que era lo que 01:39:33
nos decía ahora, que los justificantes 01:39:35
para ahora sí que aparece que el examen 01:39:38
es voluntario, lo digo un poco 01:39:40
o sea que el justificante podríais tener 01:39:41
pero no sé si quedará en presa 01:39:43
el hecho de la coletilla esa de que el examen 01:39:46
es voluntario, os puede condicionar 01:39:47
para que os lo acepten 01:39:50
de alguna forma 01:39:51
si podéis arreglarlas 01:39:52
yo creo que es interesante que vengáis a ver el examen 01:39:55
porque ya os digo, el modelo luego 01:39:57
en la ordinaria, lógicamente las preguntas 01:39:59
son distintas, pero el modelo es igual 01:40:01
entonces para un poco 01:40:03
ya que a distancia todo es mucho más complicado 01:40:05
un mini entrenamiento 01:40:07
para ver cómo es el examen, os puede venir bien 01:40:09
pero bueno, nos vemos 01:40:11
más semanas antes de esto 01:40:15
y nada, poco más que contaros 01:40:16
por hoy, la semana que viene 01:40:21
vemos alguna otra cosita por aquí 01:40:23
que tengo a punto de este tema 01:40:25
y yo creo que haremos la tarea 01:40:26
de justo 01:40:29
que se cierra 01:40:31
esta noche, para revisarla 01:40:32
todos juntos y bueno, pues seguimos 01:40:35
ahí al pie de cañón 01:40:37
bueno, venga, pues nada 01:40:38
que tengáis buena semana si no tenéis más preguntas 01:40:42
luego 01:40:44
os subo la grabación 01:40:46
por si queréis volver a revisarla 01:40:48
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Primer Curso
Autor/es:
JM
Subido por:
Jose Manuel M.
Licencia:
Dominio público
Visualizaciones:
37
Fecha:
20 de enero de 2025 - 19:18
Visibilidad:
Clave
Centro:
IES ALONSO DE AVELLANEDA
Duración:
1h′ 40′ 51″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
204.00 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid