20250117 Clases Abstractas y polimorfismo - 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:
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
V
00:29:16
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
De
00:29:42
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