2025-01-20-Programacion - Contenido educativo
Ajuste de pantallaEl ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:
Tema 5 - Método finalize, método varargs, herencia e interfaces, información devuelta por métodos
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
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