Saltar navegación

20250117 Clases Abstractas y polimorfismo - 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 17 de enero de 2025 por Stefano C.

12 visualizaciones

Descargar la transcripción

Vale, entonces, si habláis, me autorizáis a grabar vuestra voz, ¿vale? 00:00:00
Vamos a ver otra parte de este tema que estamos viendo, que son un poco... 00:00:06
La unidad se llama Usos avanzados de programación orientada a objetos, de clases y de objetos, ¿vale? 00:00:12
O sea, que en la primera parte, antes de diciembre, al fin y al cabo, hemos visto clases y objetos puros, 00:00:19
que era la programación orientada a objetos, y qué quiere decir objeto, qué quiere decir definir una clase, 00:00:26
a partir de eso estamos viendo las herramientas avanzadas, lo que se puede hacer con clases y objetos 00:00:32
que no se podía hacer antes con programación estructurada, imperativa estructurada básica. 00:00:41
Entonces, nosotros hemos visto el concepto de herencia, hemos visto que una clase puede especializar otra clase añadiendo algunas cosas, o si yo tengo muchas clases parecidas, puedo pillar la parte parecida y generalizarla en una clase de la que luego todas se herederán. 00:00:49
Y luego hemos visto que puedo jugar con esas cosas, ¿vale? Utilizando sobre todo que en una referencia de una superclase puedo en realidad poner una instancia, un objeto que sea instancia de una subclase, ¿vale? 00:01:08
Por ahora, los ejercicios que hemos hecho y la prueba que hemos hecho, principalmente nos hemos focalizado sobre el concepto de utilizar el instance of. 00:01:24
O sea, yo tengo un objeto que no sé qué instancia es y con InstanceOff puedo intentar entender cuál es la instancia real que está detrás de esta referencia para que luego pueda transformar este objeto en la clase correcta, en el tipo correcto, para poder utilizar todos los métodos y todas las variables que pertenecen a ese mismo objeto. 00:01:35
Como por ejemplo nosotros en el ejemplo de ayer teníamos figura geométrica y lo que hacíamos era, si la figura es tan soft de cuadrado, entonces podía transformar esta figura en un cuadrado, considerarlo un cuadrado y a ese punto que podía considerarlo un cuadrado podía calcular su área, podía calcular ver su lado. 00:02:00
Cosa que no podía hacer cuando era una figura geométrica. 00:02:19
De todas formas, ahora volveremos más con esto. 00:02:22
entonces, justo ayer cuando hicimos este problema, vimos que nos surgía un problemilla 00:02:26
este problemilla era relacionado con el hecho que la clase más genérica, la clase figura geométrica 00:02:34
no me permitía calcular el área, porque como de cada figura el área se calcula de una forma distinta 00:02:43
si yo no sé que figura es 00:02:52
si es un cuadrado, si es un rombo, si es un trapecio 00:02:55
si es un triángulo 00:02:57
etc, etc, no puedo 00:02:59
seleccionar la fórmula correcta para 00:03:00
calcular su área 00:03:02
pero sin embargo yo sé que todas las 00:03:03
figuras, sea cual sea las figuras 00:03:07
si tienen la posibilidad 00:03:09
de calcular su área 00:03:10
entonces 00:03:11
el concepto de figura geométrica 00:03:14
que tiene 00:03:17
una característica, un método 00:03:19
general, que yo sé que todas las figuras deberían tener, pero que no puedo implementar, porque no sé qué figura exactamente es, 00:03:20
y la fórmula cambia, se especifica en cada una de las figuras distintas, pues es un candidato perfecto para hacer una clase abstracta. 00:03:32
La clase abstracta es una clase que me define algunas cosas de un concepto que yo estoy modelizando, pero otras cosas yo no las puedo implementar. 00:03:41
Puedo definir que sí deberían estar, pero no tengo los mecanismos, no tengo los medios para implementarla en este momento. 00:03:58
Entonces, la dejo abierta, la dejo abstracta, diciendo tiene que estar, pero yo no te digo cómo es, hasta que tú, en un futuro, heredes de esta clase abstracta y implementes de forma concreta los métodos que yo había dejado con esto deberían estar, pero no sé cómo se hace. 00:04:07
¿Sí? Ejemplo más concreto 00:04:30
Si yo tengo una figura geométrica 00:04:33
Sé que toda la figura geométrica tendrá un número de lados 00:04:35
¿Vale? Eso lo puedo poner 00:04:38
Ya el círculo es complejo, pero bueno, imaginaos así 00:04:40
Polígonos, ¿vale? 00:04:43
Imaginaos que yo tengo la clase polígonos 00:04:45
Entonces sé que los polígonos tendrán que tener un cierto número de lados 00:04:48
¿Sí? Entonces yo podría implementar ya 00:04:51
Que esta clase tiene un int número de lados 00:04:55
Esto lo tiene que tener. 00:04:59
Y puedo hasta crearme un constructor que lo que hace es pasarme el número de lados 00:05:01
y yo pondré este número de lados dentro de mi variable número de lados. 00:05:06
Ese es algo concreto que puedo hacer ya. 00:05:10
Todas las figuras, todos los polígonos tendrán esta cosa. 00:05:14
Ahora, yo sé también que un polígono siempre tendrá un perímetro. 00:05:17
Y que un polígono siempre tendrá un área. 00:05:20
El problema es que, dado un polígono cualquiera, yo no sé su perímetro. 00:05:25
¿Por qué? 00:05:33
Porque además de saber el número de lados, tengo que saber el valor de estos lados. 00:05:34
Una cosa es si yo hiciera polígonos regulares. 00:05:41
Entonces, si yo soy pedígono regulares, o sea que todos los lados son iguales, 00:05:44
pues podría pedirte el número de lados y el valor de uno de los lados y ya sé calcularme el perímetro. 00:05:47
Pero en un polígono general, yo debería saber todos los valores de todos los lados, y no sé cuántos lados hay, entonces tengo un poco un problema. 00:05:54
¿Sí? A lo mejor podría hacer una rey, pero dejámoslo así. 00:06:07
Entonces, la parte que yo sé que tienen que existir, pero que no puedo generalizar, ¿vale? 00:06:11
Porque no hay una fórmula para calcular el área de cualquier polígono sin saber qué polígono es. 00:06:18
pues entonces lo voy a declarar como abstracto 00:06:23
voy a crear un método abstracto 00:06:27
que me dice, oye mira, yo aquí tendré que poner 00:06:29
el cálculo del área, el cálculo del perímetro 00:06:32
pero como no te puedo dar una cosa suficientemente general 00:06:35
para implementarla ya, para escribir el código ya 00:06:39
te voy a decir que tiene que existir 00:06:42
pero no existe 00:06:45
pero no se implementa 00:06:47
eso se llama un método abstracto 00:06:51
El método abstracto es un método que tiene que existir, pero no lo puedo implementar ahora, lo dejo allí, y en un futuro, cuando tú crearás una clase que hereda de esta clase de aquí, pues allí estará forzado a implementar este método que he dejado abstracto. 00:06:55
Si hay un método abstracto, la clase tiene que ser abstracta. 00:07:13
Entonces, en una clase abstracta coexisten dos cosas. Coexisten, por un lado, métodos ya implementados, ya existentes, y variables que ya existen implementadas, que ya he podido hacer, y métodos que tienen que estar, yo estoy seguro que tiene que haber un calcular área, pero todavía no sé cómo hacerlo. 00:07:20
Entonces, a veces hay clases que definen un concepto genérico con unas características y métodos 00:07:45
Que no se pueden concretar directamente 00:07:54
Por ejemplo, una figura geométrica tiene sentido que tenga un método para calcular su perímetro y su área 00:07:56
Pero cómo se calculan estos depende de la figura geométrica concreta 00:08:03
Entonces figura geométrica no me puede implementar estos datos 00:08:07
Otro ejemplo, un vehículo tendrá la capacidad de moverse 00:08:10
No tendría sentido un vehículo que no se mueve, ¿vale? Pero, como lo hace, dependerá del vehículo concreto, o sea, que barco tendrá una forma de moverse, avión tendrá una forma de moverse, tren tendrá una forma de moverse distinta. 00:08:14
Entonces yo puedo decir en vehículo que sea una clase abstracta con el método abstracto moverse y cuando luego crearé un barco que hereda de vehículo, entonces este barco implementará este método moverse diciendo estoy deslizando por encima del agua. 00:08:26
Si en vez es el avión, implementará este método de otra forma diciendo estoy volando por el aire. 00:08:45
¿Se entiende? 00:08:52
¿Sí? 00:08:53
Una clase abstracta puede declarar, además de métodos normales, esto es importante, también métodos abstractos. 00:08:54
O dicho de otra forma, si en una clase yo necesito poner y pongo un método abstracto, la clase tiene que ser abstracta también. 00:09:02
La tengo que marcar como abstracta. 00:09:13
Un método abstracto es aquel que no tiene más que la definición del mismo, sin su implementación. 00:09:16
Es decir, que le falta el cuerpo, le faltan las llaves. 00:09:24
Así es como se declara un método abstracto. 00:09:30
Public, abstract, palabra, ¿cómo se dice? 00:09:33
Palabra reservada que estará en rojo para decir que este es un método abstracto. 00:09:37
Inter, método abstracto, los parámetros que pedirá y directamente un punto y coma. 00:09:42
El cuerpo, la implementación no está. 00:09:49
¿Por qué? Porque es un método abstracto. Te estoy diciendo, esta clase debería tener este método, pero no lo tiene porque a este nivel de abstracción yo no te puedo definir cómo se hace este método. 00:09:53
un método abstracto debe ser obligatoriamente 00:10:05
redefinido en sus clases no abstractas 00:10:10
entonces si yo tengo vehículo, por debajo tengo coche 00:10:14
y coche no es abstracto, pues entonces esto tiene 00:10:19
que implementar sí o sí moverse, pero 00:10:23
si yo tengo vehículo, luego tengo por debajo vehículo terrestre 00:10:27
y por debajo tengo coche, vehículo terrestre 00:10:32
si es abstracto también 00:10:36
es una clase 00:10:38
que hereda de vehículo 00:10:39
pero es una clase abstracta 00:10:41
que hereda de vehículo 00:10:43
podría mantener su método 00:10:45
como abstracto 00:10:47
la clave es que mientras que un método 00:10:48
sea abstracto 00:10:51
mientras que haya al menos un método abstracto 00:10:53
la clase sigue siendo abstracta 00:10:54
¿lo das? 00:10:58
bueno, si 00:10:59
en la clase figura geométrica si 00:11:00
de hecho lo pone aquí 00:11:12
lo pone aquí, una clase abstracta 00:11:19
puede declarar además de métodos 00:11:21
normales, también métodos 00:11:23
abstractos, una clase 00:11:25
que no es abstracta no puede 00:11:31
poner un método abstracto, ¿por qué? 00:11:32
porque si hay al menos un método abstracto 00:11:34
la clase tiene que ser abstracta, eso lo hemos dicho 00:11:36
si tú tienes un método que no 00:11:38
puedes implementar y dices lo implementará 00:11:42
alguien más, esta clase 00:11:44
no puede ser una clase normal 00:11:46
tiene que ser una clase abstracta, porque 00:11:47
es un método que tú sabes que 00:11:50
tiene que tener calcular área pero no sabes cómo calcularla por lo tanto es como si lo dejaras 00:11:52
allí diciendo hoy mira existe sí pero tú puedes hacer una cadena de clases abstractas o sea 00:11:58
vehículo que era vehículo terrestre que hereda de vehículo y las dos sean abstractas y luego 00:12:08
este coche que hereda de vehículo terrestre que en vez es una clase concreta clase normal de la 00:12:14
que hemos visto hasta ahora. La clave importantísima de las clases abstractas es que justo combinan 00:12:21
estas dos cosas. Las clases abstractas tienen métodos que sí se han podido implementar 00:12:29
y métodos que no se han podido implementar. Porque si en mi clase todos los métodos son 00:12:36
abstractos, entonces es una interfaz. Pero lo veremos más adelante porque todavía no 00:12:44
sabemos que es una interfaz, lo veremos 00:12:49
aquí 00:12:51
pero no hemos llegado 00:12:53
¿sí? 00:12:54
entonces 00:12:59
un método abstracto debe ser obligatoriamente 00:12:59
redefinido en sus subclases 00:13:03
no abstractas, importante ese no 00:13:04
¿vale? 00:13:07
si la subclase sigue siendo 00:13:08
abstracta, no es obligatorio 00:13:11
redefinirlo, sigue allí 00:13:12
no lo ha implementado, luego haremos ejemplos 00:13:14
pero si yo el mover se lo tengo 00:13:17
en vehículo, luego tengo vehículo terrestre 00:13:19
y luego tengo coche 00:13:21
vehículo terrestre no ha implementado 00:13:22
el método moverse, pero 00:13:25
coche tendrá que hacerlo porque es el primero 00:13:27
en esta cadena que no es abstracto 00:13:28
permiten declarar en la superclase 00:13:31
un comportamiento que deberán 00:13:35
cumplimentar todas las subclases 00:13:37
¿vale? pero sin decir 00:13:39
nada sobre su implementación 00:13:41
te está diciendo, oye 00:13:43
mira, todos los hijos míos 00:13:45
todos los hijos de figura 00:13:47
Todos los hijos de vehículo 00:13:48
Tendrán que poder moverse 00:13:50
Tendrán que poder calcular su área 00:13:52
Pero no te estoy diciendo cómo se hace 00:13:53
Porque cómo se hace dependerá 00:13:56
De la implementación de la clase hija 00:13:57
¿Sí? 00:14:00
Entonces, las clases de geometría de astratos 00:14:07
Se escriben en cursiva, ¿vale? 00:14:09
Cuando vosotros veis un dibujo así 00:14:10
Sobre todo en UML 00:14:14
¿Habéis visto algo de UML? 00:14:16
Muy poco, pues veréis más, ¿vale? 00:14:20
En torno a los desarrollos, pues posiblemente empezaréis a ver algo de OML. 00:14:23
En particular está una cosa que se llama el diagrama de clase, donde las clases se especifican con cuadritos así. 00:14:28
Donde está el nombre, aquí están los atributos y aquí están los métodos. 00:14:35
En este tipo de cosas, si hay algunos métodos que se escriben en cursiva, es porque son abstractos. 00:14:39
¿Sí? Repito que en una clase abstracta, por eso en cursiva, pues puede haber algunos métodos que no son abstractos y algunos métodos que no son abstractos. 00:14:46
Una clase que no tiene métodos abstractos no debería ser abstracta. 00:14:59
Una clase que tiene al menos un método abstracto, pues tiene que ser abstracta. 00:15:05
¿Sigo? 00:15:10
Clases abstractas. Importante, en negrita, por eso es importante, ¿vale? 00:15:13
No se pueden instanciar clases abstractas 00:15:17
Si yo tengo vehículo que es abstracto 00:15:22
¿Puedo hacer vehículo X es igual a algo? 00:15:27
Si yo tengo 00:15:39
Esto se hace más grande 00:15:41
Si yo tengo la clase abstracta vehículo 00:15:43
¿Puedo hacer por algún lado vehículo X es igual a algo? 00:15:51
Sí. ¿Eh? Pero no me acabas de decir que no se puede hacer una instancia de una clase abstracta. 00:15:56
Sí, te lo he dicho. Entonces, ¿qué me estás contando? 00:16:06
Porque sí puedo hacer esto. Porque yo aquí no he creado ninguna instancia. 00:16:12
Esto no crea una instancia. ¿Cómo se crean las instancias? 00:16:25
con new, es la parte a la derecha 00:16:32
que crea la instancia, no esta de aquí, esta es una referencia 00:16:37
y yo no os he dicho no se puede crear referencias o variables de tipo 00:16:40
clase abstracta, eso si se puede hacer, lo que no se puede 00:16:45
hacer es crear una instancia, es decir 00:16:49
que esto es un error 00:16:53
pero no es un error esta parte, es un error esta 00:16:57
parte se entiende y si yo luego tengo la clase no abstracta que existo el coche 00:17:01
que hereda hereda hereda de vehículo si puedo hacer coche 00:17:18
c es igual año coche pero también puede hacer vehículo y es igual año coche 00:17:36
porque el coche es un vehículo porque hereda además estás creando una instancia 00:17:51
nuestra abstracta no yo estoy creando una instancia de coche no una instancia 00:18:08
vehículo y coche es una clase no abstracta y por lo tanto sí puedo crear un coche. A ver, cuando tú 00:18:15
crearás coche estás forzada a sobreescribir los métodos abstractos que tenías definidos en la 00:18:36
clase de arriba, por lo tanto cuando usarás en coche esos métodos que eran definidos arriba en 00:18:46
en realidad estarás utilizándolos de la instancia, o sea, estarás utilizándolos de coche. 00:18:52
Que es lo que quieres, porque en vehículo no están definidos, y en coche sí. 00:18:58
Simplemente sobreescribiéndolo. 00:19:09
¿Sabes cómo hemos hecho el overreading? 00:19:11
Misma cosa. 00:19:12
De hecho, el IDE te ayudará. 00:19:14
Si tú no has sobreescrito un método declarado abstracto en una clase que heredas, 00:19:17
te dirá, oye, mira, esta clase no está bien porque tienes que sobreescribir este método para hacerla concreta. 00:19:21
O dejarla abstracta. 00:19:28
Elige tú. Pero si quieres que no sea abstracta, estás obligatoriamente forzado a redefinir esos métodos. 00:19:29
Y entonces, en automático, lo que intentará hacer él, cuando haga una cosa así, hasta si yo estoy utilizando vehículo, 00:19:41
el vehículo tendrá moverse, pero cuando uso y.moverse, él en automático me va a usar la implementación de coche. 00:19:51
¿Y esto por qué? Por polimorfismo. 00:20:02
Nosotros todavía no lo sabemos que se llama así, pero es lo que hemos estado utilizando hasta ahora, cuando hemos hecho pruebas y cosas por el estilo. 00:20:06
Siempre se usa el método relacionado con la instancia, no con la referencia. 00:20:14
¿Os acordáis cuando hemos visto el overriding? Pues allí he hecho hincapié en cuando se usa este de aquí, se está utilizando el hijo. Si os acordáis, esta transparencia aquí está. 00:20:24
que yo tenía en el padre un imprimir y en el hijo un imprimir 00:20:45
y aquí usaba con una instancia de alumno, una referencia alumno, una referencia persona 00:20:52
y llamaba a.imprimir o p.imprimir, en los dos casos usaba el de la instancia, o sea, el de alumno. 00:21:01
¿Sí? Entonces, si esto fuera, si persona fuera abstracto, y yo imprimir aquí no lo defino, hasta cuando uso persona, ¿vale? En realidad haría p.imprimir, pero lo que hace Java es usarme este, no este. 00:21:09
¿Se entiende? 00:21:29
¿Por qué estoy utilizando? 00:21:50
¿Por qué? 00:22:02
Esto es también un... ¿Cómo se llama? 00:22:05
Un shadowing. 00:22:07
Y yo en la impresión de este de aquí estoy utilizando dis.nombre de la clase alumno. 00:22:11
Entonces cuando yo estoy haciendo este imprimir no estoy utilizando este que utilizaría dis.nombre de esta clase. 00:22:17
Además estoy utilizando este que usaría 00:22:24
Dis.nombre de esta clase 00:22:26
Porque la instancia 00:22:27
Es un alumno 00:22:30
De todas formas luego haremos ejemplos para que esto quede más claro 00:22:33
¿Dónde hemos llegado? 00:22:45
Hemos llegado aquí 00:22:49
Entonces es importante 00:22:50
No se pueden hacer instancias de clases abstractas 00:22:51
No puede hacer new 00:22:55
De una clase que sea declarada abstracta 00:22:56
¿Por qué no puede hacerlo? 00:22:58
Porque a esta clase le falta algo 00:23:00
Si creo una instancia de esa clase y tengo unos métodos que son abstractos, esos métodos no los podría usar porque no están definidos. 00:23:01
Y por lo tanto no puedo. 00:23:09
Pero sí puedo declarar una referencia de ese tipo, de clase abstracta. 00:23:11
Si entonces tengo publicAstractClassFigura con el concepto de dibuja, yo puedo dibujar esta figura, 00:23:19
pero no sé cómo se dibuja porque un triángulo se dibujará de una forma y el cuadrado se dibujará de otra. 00:23:26
Por lo tanto, no sé qué hacer, pero luego crearé el public class rectángulo que está en de figura y no es abstracto, 00:23:31
donde dentro aquí definiré el método que hace dibuja cuando dibuja un rectángulo 00:23:39
y la clase círculo que hace dibuja cuando se dibuja un círculo. 00:23:44
Entonces yo sé que todas figuras tendrán dibuja. 00:23:49
Sobre una referencia de tipo figura puedo llamar dibuja, porque sé que tiene que existir, 00:23:52
Pero dependiendo de la instancia que está dentro de esta referencia 00:23:57
Si es una instancia de rectángulo, usaré este dibujo 00:24:02
Si es una instancia de círculo, usaré este dibujo 00:24:06
¿Se entiende? 00:24:10
Se pueden instanciar clases heredadas siempre que no sean abstractas a su vez 00:24:11
Y se puede instanciar subclases utilizando la referencia a la clase padre 00:24:16
Por ejemplo, figura F es igual a año rectángulo 00:24:20
¿Dudas? 00:24:23
Entonces, ¿qué es esto del polimorfismo? 00:24:32
¿Vale? Se habla de polimorfismo cuando dos métodos tienen el mismo nombre, pero hacen funciones un poquito distintas, aunque similares, en objetos distintos. 00:24:35
Es decir, que este dibuja y este dibuja son polimórficos, porque se llaman iguales, hacen cosas parecidas, los dos dibujan una figura, 00:24:48
Pero esto hace cosas completamente distintas de esto 00:25:00
Esto dibuja un cuadro, un rectángulo 00:25:04
Y esto dibuja un círculo 00:25:06
Entonces tengo polimorfismo 00:25:08
Morfo es aspecto 00:25:11
Poli es mucho 00:25:15
Tiene muchos aspectos 00:25:17
Es la misma cosa, pero puede asumir aspectos distintos 00:25:18
Dependiendo del objeto sobre el que lo llamo 00:25:21
Siempre dibuja 00:25:24
Pero hará cosas un poquito distintas 00:25:25
Si lo llamo rectángulo, en círculo 00:25:28
Siempre se hará moverse, pero se moverá distinto si lo llevamos sobre un barco o sobre un coche 00:25:29
¿Se entiende? 00:25:36
No tendría sentido que dibuja un rectángulo, dibuja un rectángulo 00:25:42
Y dibuja en círculo, calcula el área del círculo 00:25:45
Eso no tendría sentido 00:25:49
Tienen que hacer cosas parecidas, tienen que hacer lo que el método te pide que haga 00:25:51
Normalmente en una clase de abstracto a quien dibuja se pone en algún lado una especificación de qué se entiende con dibuja 00:25:57
Dibujará gráficamente la figura, calculará el área de la figura, calculará el perímetro de la figura 00:26:06
Y luego cuando lo hago en rectángulo y me hago calcular el perímetro, pues me voy a leer esta especificación 00:26:17
me dice que este método tendrá que calcular el perímetro, entonces aquí será lado 1 por 2 más lado 2 por 2, 00:26:23
mientras que aquí será otra cosa, 2 pi greco y radio, ¿se entiende? ¿Dudas? 00:26:32
Entonces, un ejemplo de polimorfismo es el método calcular el rectángulo de círculo, 00:26:43
mismo método, mismo nombre, mismos parámetros, pero hacen cosas un poquito distintas, ¿vale? 00:26:48
Hacen funciones distintas, aunque similares en objetos distintos. 00:26:56
Esos son polimórficos. 00:27:01
¿Dudas? 00:27:04
Si hablamos de clases, el polimorfismo es lo que nos permite crear una clase con la referencia padre, 00:27:05
pero que apunte a una clase hija, ¿vale? 00:27:13
Como hemos visto anteriormente, o sea, esta cosa de aquí, estoy usando un poco de polimorfismo, 00:27:16
porque esta figura puede ser un rectángulo, pero puede ser también un círculo. 00:27:22
Los dos son figuras, son cosas parecidas, ¿vale? Pero hacen cosas distintas, ¿entiende? 00:27:26
Cuando se usa un método sobre un objeto, se usará el de la clase de la que ese objeto es instancia, la clase que se ha usado a hacer el new, ¿vale? 00:27:35
F.calcularA llamará el método calcularA de rectángulo, porque es una instancia de rectángulo. 00:27:45
De esta forma, figura podría hasta ser abstracta 00:27:53
Porque no voy a usar el calcularia de figura 00:27:59
Voy a usar el calcularia de la instancia 00:28:03
Y como he hecho una instancia, esto tiene que ser no abstracto 00:28:06
Entonces tiene que tener el método calcularia implementado 00:28:10
Entonces lo puedo usar 00:28:14
¿Se entiende esta cadena? 00:28:15
Podemos usar una superclase como parámetro formal 00:28:17
Y luego usar el método apropiado basándose sobre el objeto pasado como parámetro actual 00:28:24
O sea, yo en un método que me dice imprimearea 00:28:30
Podría usar como parámetro un figura x 00:28:34
Pero cuando luego paso un figura, este figura podría pasarle un rectángulo 00:28:39
Porque el rectángulo es un rectángulo 00:28:45
Entonces yo podría hacer 00:28:47
Un método 00:28:53
En nuestro ejemplo 00:28:55
Que sea un método 00:28:58
En algún lado 00:29:01
Hasta en otra clase 00:29:05
Que sea un 00:29:06
El método public 00:29:07
Void 00:29:10
Mueve 00:29:11
De vehículo 00:29:13
Y este método 00:29:18
Hacerle hacer 00:29:21
V.mover 00:29:22
V.mover 00:29:24
¿Sí? 00:29:27
Ahora, cuando lo llamo este método 00:29:30
Que sale en una clase, no lo sé 00:29:32
Me da igual 00:29:34
Yo estoy en otra clase y quiero usar mueve 00:29:34
Esta clase, la clase, no sé 00:29:38
Puedo usar mueve 00:29:40
New coche 00:29:43
O poder hacer coche, coche C es igual a año coche, y luego aquí pasarle C. 00:29:45
Oye, pero ¿qué me dices? Si este mueve, no recibe un coche, recibe un vehículo. 00:30:01
Y además vehículo es abstracto. 00:30:07
Si mayor no le pasaré un vehículo, le pasaré algo que puede ser un vehículo. 00:30:09
Oye, pero mover es abstracto. 00:30:16
Porque vehículo es abstracto, no puedo llamar v.mover 00:30:19
Sí, porque v será, apuntará a este señor de aquí 00:30:22
Porque esto es el parámetro, os acordáis, lo vimos 00:30:29
Este es el parámetro formal, esto es el parámetro actual 00:30:32
Este es un parámetro abstracto genérico 00:30:35
Pero actualmente este de aquí será asociado con este 00:30:38
Y este como instancia, como objeto, no es un objeto vehículo 00:30:42
Porque no pueden existir objetos vehículos, porque es abstracto. 00:30:47
Este es un objeto de tipo coche, es una instancia de coche. 00:30:51
Por lo tanto, cuando llamaré uva.mover, no voy a usar el mover de vehículo. 00:30:55
Voy a usar el mover de coche. 00:31:01
Creo C, que apunta a un coche. 00:31:20
Este es un coche. 00:31:25
También es un vehículo. 00:31:28
Cuando yo uso este método de aquí y le paso C 00:31:29
Dentro de este método se crea una variable V de tipo vehículo 00:31:37
Que apunta a esta cosa de aquí 00:31:42
Porque apunta a lo mismo que apuntaría C 00:31:45
Se hace una asociación entre C y V 00:31:48
Entonces cuando yo ahora hago V.mover 00:31:51
V me direcciona a este señor de aquí 00:31:56
Y esta es una instancia de coche 00:31:59
por lo tanto me usará el mover de coche 00:32:04
porque ahora yo mueve 00:32:08
lo puedo llamar sobre coche 00:32:15
lo puedo llamar sobre barco 00:32:17
lo puedo llamar sobre tren 00:32:19
lo puedo llamar sobre cocodrilo 00:32:20
con cualquier cosa que sea un vehículo 00:32:22
realmente es para que tú puedas crear un método 00:32:24
que te pille cualquier tipo de vehículo 00:32:31
sin que tú sepas cómo se mueve el vehículo 00:32:34
porque el vehículo no lo sabes 00:32:36
pero las implementaciones de vehículos 00:32:37
sí que sabrán cómo moverse. 00:32:40
Entonces aquí noté, si tú no usaras esto, deberías hacer mueve de coche, 00:32:44
mueve de tren, mueve de avión, y cuando mañana crean una astronave, 00:32:49
tú no lo puedes hacer, porque tu astronave no tiene el método mueve-astronave. 00:32:55
Shadowing no. 00:33:04
Si tú haces herencia y creas una nueva clase astronave que hereda de vehículo, 00:33:07
ya puedes usar tu astronave en cualquier método 00:33:12
que use un vehículo, entonces es muy potente 00:33:16
de cara también al modificar tu proyecto sin tener que 00:33:19
modificar el resto del proyecto, entonces 00:33:24
esto del polimorfismo es lo que hemos usado por ejemplo cuando hemos hecho 00:33:35
una array de que eran empleados y luego dentro ponía 00:33:42
empleados y gerentes, al principio lo hemos 00:33:46
hecho sin polimorfismo, entre comillas, en el sentido que estábamos utilizando 00:33:50
de preguntándome, maestro, ¿es un gerente? Si es un gerente, haz una cosa distinta. 00:33:54
Y luego después hemos visto una forma de hacerlo, oye, no, mira, si hago el método 00:33:58
coste o algo 00:34:02
por el estilo, mi coste, pues él en automático, tú 00:34:06
pones un empleado o un gerente y él sabrá cuál utilizar porque él sabrá 00:34:10
cuál es la instancia real. Entonces 00:34:14
te permite hacer arrays de empleados y calcular todo, cada uno utilizará su propia implementación, la implementación específica para eso, y si mañana tú necesitas una nueva figura, además de empleado y gerente que es administrador, no tienes que volver a tocar todos los métodos para añadir que existe este método también para administrador, 00:34:18
El administrador es un empleado, simplemente cuando llegará allí y tendrá que calcular el coste del administrador, pues tú habrás definido en administrador, especificado en administrador, cómo se hace, cuál es el cálculo para el administrador y cuál es el cálculo para el gerente y cuál es el cálculo para el empleado. 00:34:39
y como hemos visto en ese ejemplo concreto 00:34:56
pues todos son empleados, por lo tanto 00:34:58
empiezan de una base común 00:35:00
que es hacer lo que hace el empleado 00:35:02
calcular el coste de un empleado 00:35:04
pero el gerente le añade un bonus 00:35:06
y el administrador le añade la... no lo sé 00:35:08
¿no? porque 00:35:10
empleado podría ser 00:35:14
una clase abstracta 00:35:17
y podría hacer que todos míos son empleados 00:35:19
pero haya empleado simple 00:35:21
empleado gerente 00:35:22
empleado no sé qué 00:35:25
Y todos mis métodos lo hago con empleados, pero luego cuando va a hacer algo, pues lo hará con sus métodos. 00:35:26
Y si luego hay un método no definido en empleado que solo puede utilizar los gerentes, pues allí tendré que hacer la cosa de list and soft, downcastearlo, o sea, hacer el casting a gerente y a ese punto lo podré utilizar. 00:35:35
las dos cosas no se excluyen 00:35:50
pero 00:35:53
si yo hago un diseño bien hecho 00:35:55
pues me resuelvo muchos problemas 00:35:57
sobre todo de cara al futuro 00:35:59
porque mi sistema 00:36:01
no debería funcionar ahora, debería funcionar 00:36:02
siempre, y cuando mañana 00:36:05
me doy cuenta que además hay un empleado 00:36:07
temporal que no había metido 00:36:09
no quiero volver a cambiar 00:36:11
el entero sistema 00:36:13
que he hecho antes, quiero añadirlo 00:36:15
le pongo que es un empleado también 00:36:18
y ya está, ya eso funciona. 00:36:19
Si lo he hecho bien. 00:36:22
Cuando tenemos que crear un objeto 00:36:26
de una clase heredada, podemos utilizar como clase 00:36:27
referencia a la del padre o del hijo. 00:36:30
Tenemos una clase padre 00:36:32
y una clase hijo, que hereda de padre. 00:36:33
Puedo hacer padre objeto es igual a 00:36:36
new hijo, padre objeto es igual 00:36:37
a new padre. Lo puedo hacer 00:36:39
solo si padre es no abstract. 00:36:41
Si padre no es abstracto, 00:36:44
puedo crear tranquilamente como hacía con empleado. 00:36:45
Pero si padre es abstracto, esto no lo puede hacer. 00:36:48
E hijo es igual a new hijo, también lo puede hacer. 00:36:53
Entonces las referencias, en un cierto sentido, son más libres con respecto a la instancia. 00:36:56
La instancia es única. 00:37:02
Cuando yo creo un new hijo, ese es un hijo. 00:37:03
Cuando yo creo un new padre, ese es un padre. 00:37:05
Y eso no va a cambiar. 00:37:07
Pero como lo referencio, sí que puede hacer que lo referencie como un padre o lo referencie como un hijo. 00:37:09
si yo lo referencio como un padre tendré acceso a todos los métodos del padre 00:37:14
si yo lo referencio como un hijo tendré acceso a todos los métodos del hijo 00:37:20
si yo lo referencio como un padre luego lo puedo transformar en un hijo 00:37:25
si es de la clase correcta, en este caso no podría hacerlo, en este caso sí 00:37:30
y si comparten métodos, es decir que hijo sobrescribe métodos de padre 00:37:34
Al usar ese método siempre se usará el de la clase específica, el del que estancia 00:37:42
Este usará hijo y este usará padre 00:37:48
Ahora hacemos ejemplo 00:37:52
Hay tres formas posibles de estanciarlas 00:37:54
Este de aquí, hijo barra es igual a año hijo 00:37:58
Creo una referencia hijo con una instancia hijo 00:38:03
Padre es igual a año padre 00:38:07
Creo una referencia tipo padre 00:38:10
Con dentro un padre 00:38:12
Y luego esta cosa de aquí que en términos técnicos se llama 00:38:13
Upcasting 00:38:16
Que es, hago un padre, una referencia padre 00:38:17
Pero dentro tiene un hijo 00:38:20
Y eso es posible porque el hijo es un padre 00:38:22
Entonces no hay problema 00:38:24
En realidad esto es mucho lo que se hace 00:38:25
Aquí 00:38:29
No, en cierto sentido 00:38:32
Aquí estoy haciendo un upcasting 00:38:37
Porque es como si aquí dentro yo estuviera 00:38:38
Haciendo que v es igual a c 00:38:42
¿Sí? 00:38:43
Entonces, en realidad estoy haciendo que un vehículo 00:38:46
Una referencia vehículo 00:38:50
Es un coche 00:38:53
¿Sí? 00:38:55
Solo podemos acceder a los del hijos 00:39:00
Y hacemos un downcasting explícito 00:39:02
O sea, que cuando hago esto 00:39:04
Luego barache me dará solo los métodos del padre 00:39:05
Lo hemos visto ayer con alguna de estas 00:39:08
Ahora tanto lo volvemos a ver 00:39:10
Si quiero los métodos propios del hijo 00:39:11
Tendré que hacer un downcasting 00:39:14
Esto es un downcasting 00:39:16
Lo hemos hecho. 00:39:18
Pero cuidado que si yo hago un downcasting o hago un casting a algo que no es verdad, 00:39:22
pues me va a lanzar un class cast exception. 00:39:28
Va a decir, esto no lo puedes hacer. 00:39:31
Y hemos visto también eso. 00:39:33
Si una clase abstracta tiene solo métodos abstractos, 00:39:36
pues en realidad probablemente es una interfaz. 00:39:40
Pero esto la próxima semana. 00:39:44
¿Dudas hasta aquí? 00:39:47
Ejemplito. 00:39:49
O ejemplitos. 00:39:50
Ah, recreo. 00:39:51
Vale, sí, entonces después de recreo, ejemplos. 00:39:56
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Primer Curso
Autor/es:
Stefano Chiesa
Subido por:
Stefano C.
Licencia:
Reconocimiento - No comercial
Visualizaciones:
12
Fecha:
17 de enero de 2025 - 12:42
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
40′ 01″
Relación de aspecto:
16:10 El estándar usado por los portátiles de 15,4" y algunos otros, es ancho como el 16:9.
Resolución:
1152x720 píxeles
Tamaño:
103.13 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid