Teoría 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, esta clase está siendo grabada, si habláis me dais el consentimiento de grabaros, ¿vale?
00:00:00
Entonces, aquí tenemos, hoy empezamos con, vamos a ver qué es el concepto de clase abstracta y polimorfismo, ¿vale?
00:00:08
En realidad el polimorfismo ya lo conocemos, pero no sabemos qué se llama así,
00:00:17
en realidad sabemos también qué se llama así, porque ya os lo he nombrado varias veces, ¿vale?
00:00:21
Pero ya hablaremos de ello.
00:00:25
Hoy el verdadero tema nuevo es la clase abstracta.
00:00:27
¿Por qué es una clase abstracta?
00:00:30
¿Habéis pensado alguna vez, ahora, mientras estabais haciendo estos ejercicios de herencia,
00:00:31
que en determinados casos hay algunos métodos que tienen sentido en las clases hijas,
00:00:39
¿vale? En las clases hijas está claro, ¿vale?
00:00:50
Pero en la clase padre, la clase de donde se hereda, tienen menos sentido de existir.
00:00:53
Por ejemplo, vamos a hacer un ejemplo sencillo
00:01:00
¿Os acordáis dispositivo?
00:01:05
Nosotros teníamos una clase dispositivo, uno de los primeros ejemplos de herencia que hemos hecho
00:01:08
Ese dispositivo tenía sus métodos, sus funcionalidades, etc.
00:01:13
Como por ejemplo, encender y apagar
00:01:17
¿Tiene sentido que un dispositivo se encienda o se apague?
00:01:20
Sí, tiene bastante sentido
00:01:26
Es una cosa que cualquier dispositivo, sea el dispositivo que sea
00:01:28
Tiene sentido que se pueda encender y que se pueda apagar
00:01:33
Estaría bien, como se dice, implementar, crear, codificar este método aquí en el dispositivo
00:01:36
Ahora, cuando luego voy al estado
00:01:49
Si os acordáis, nosotros estado lo utilizamos como ejemplo para luego en el móvil volver a sobreescribirlo
00:01:52
Pero si lo pensáis, el estado, o sea, cómo se encuentra ahora el dispositivo o lo que tiene que hacer un dispositivo
00:02:05
Es algo que depende mucho del dispositivo mismo
00:02:14
Me explico. Un móvil tendrá un funcionamiento, podrá hacer cosas, podrá...
00:02:18
El estado de un móvil, imaginándonos lo que puede ser, es cómo está la pantalla, o su RAM, o su potencia de cálculo, qué sé yo.
00:02:24
Otros dispositivos distintos, como por ejemplo una televisión, podrían tener un estado completamente distinto.
00:02:35
O un teléfono, no sé, una lavadora
00:02:42
¿Es siempre un dispositivo? Sí
00:02:47
Pero mientras que el concepto de encendido y apagado se aplica bien a cualquier dispositivo posible
00:02:49
Ya el concepto de estado depende mucho de la instancia concreta del dispositivo que yo tengo
00:02:57
O sea que a nivel de dispositivo, a nivel de esta clase
00:03:04
A lo mejor la implementación del estado es una cosa demasiado genérica, demasiado abstracta para implementarla aquí.
00:03:09
Cuando ya estaré en el móvil, pues sé qué hacer para definir el estado del móvil.
00:03:22
Cuando estaré en televisión, pues sabré el estado de la televisión.
00:03:30
Pero en dispositivo, a lo mejor esta implementación que he hecho es demasiado genérica
00:03:34
No me hace falta
00:03:39
La idea de la clase abstracta es exactamente esta
00:03:40
Es decir, oye, mira, como este método de aquí
00:03:44
A este nivel de jerarquía de herencia
00:03:46
Es demasiado abstracto
00:03:51
Yo te pongo aquí que este método existe
00:03:53
Pero no te doy la implementación
00:03:57
Dejo aquí la existencia de todos los dispositivos tienen un método estado
00:03:59
Pero no te digo el código del método estado
00:04:08
Dejo este método como un método abstracto
00:04:12
¿Y qué es un método abstracto?
00:04:18
Quiere decir que como no existe el código no lo puedo utilizar
00:04:20
De hecho, como existe un método abstracto, también esta clase será abstracta
00:04:23
Y cuando una clase es abstracta, no se puede implementar
00:04:29
No puedo crear objetos de esa clase, no puedo crear objetos dispositivos como tales
00:04:32
Voy a hacer mi dispositivo
00:04:38
Porque habría una parte que no está codificada, no está implementada
00:04:39
Pero a la vez te digo que cualquier clase que extenda dispositivo
00:04:47
Entonces, cualquier clase que sea un dispositivo tendrá que tener este método y tendrá que implementarlo, sobreescribiéndolo.
00:04:52
Entonces, desde abstracto se transformará en real.
00:05:02
Entonces, lo que estoy obligando es que cualquier clase que extenda dispositivo tendrá estado.
00:05:07
Entonces, yo podré utilizar estado en cualquier objeto que sea de una clase que extenda dispositivo.
00:05:15
Sé que tiene que existir, porque te lo he puesto aquí como abstracto.
00:05:22
Tu ron será de implementar este método.
00:05:26
Pero el dispositivo por sí mismo, como no sé cómo implementarlo,
00:05:29
porque es demasiado genérico, pues no lo voy a implementar yo.
00:05:33
Lo voy a dejar a los implementadores de las clases que estenden este dispositivo.
00:05:36
¿Sí? ¿Se entiende más o menos el concepto?
00:05:44
Ahora lo repasamos varias veces, ¿vale?
00:05:46
Y entonces, ahí está la introducción.
00:05:49
Que es una clase abstracta, ¿vale?
00:05:51
Que a veces hay clases que definen un concepto muy genérico, ¿vale?
00:05:54
Y que tienen características y métodos que en ese nivel no se pueden concretar, ¿vale?
00:06:00
Un ejemplo típico que vosotros habéis hecho, que habéis implementado, pero a lo mejor os habréis dado cuenta de eso allí, es la figura geométrica.
00:06:07
Cualquier figura geométrica tiene, por ejemplo, un perímetro y un área.
00:06:16
¿Justo? Pero es que cada figura geométrica tiene su forma de calcular el perímetro y la área.
00:06:21
Son formas distintas.
00:06:30
Entonces, ¿es justo decir cualquier figura geométrica, bueno, sumamos cualquier polígono, tiene un área?
00:06:32
¿Y tendrá que tener un método para calcular el área?
00:06:41
Sí, tiene sentido.
00:06:44
¿Y cuál es este método?
00:06:47
Pues no lo puedo saber
00:06:48
Hasta que tú no me digas si es un triángulo, un cuadrado, un círculo o un hexágono
00:06:50
Yo no sé cómo calcular su área
00:06:55
Entonces la idea es que mi clase de figura geométrica
00:06:57
Que algunos de vosotros ya habrán hecho en los ejercicios
00:07:02
Pues la hago como abstracta
00:07:05
Creo esta figura geométrica como clase abstracta
00:07:09
le digo que como métodos abstractos tendrán que tener cálcula área y cálcula perímetro
00:07:13
y por lo tanto estoy diciendo que cualquier clase que herede de figura geométrica
00:07:20
tendrá que tener el método cálcula área y el método cálcula perímetro
00:07:26
que pero serán concretos de la clase que creo
00:07:31
cuando crearé la clase triángulo que extiende figura geométrica
00:07:35
Yo sé que tendrá que tener un método
00:07:39
Calcular área o un método
00:07:42
Cálcula perímetro
00:07:44
Pero como sé que es un triángulo
00:07:46
Lo haré adaptado al triángulo
00:07:48
¿Make sense?
00:07:50
Un ejemplo entonces es
00:07:55
Sí
00:07:56
No
00:07:57
De hecho, el ejemplo que hemos hecho antes
00:08:01
En el ejemplo de dispositivo, encender y apagar
00:08:04
No son abstractos, están implementados
00:08:07
Hacen algo
00:08:09
Porque todos los dispositivos
00:08:10
Hacen lo mismo independientemente que sea un móvil
00:08:13
Que sea una lavadora
00:08:16
Tú lo puedes encender y apagar
00:08:17
Nuestro ejemplo muy sencillo
00:08:19
¿Vale?
00:08:21
Lo que cambia es lo que hace de verdad
00:08:22
El haz algo
00:08:24
El darme tu estado
00:08:26
¿Vale?
00:08:30
Entonces tú en una clase astrata
00:08:30
Puedes implementar la parte genérica
00:08:32
Que tú sabes que es igual en todos tus
00:08:35
En todos los dispositivos que heredarán de ti
00:08:38
Puedes implementar algunos métodos
00:08:43
Que luego sabes
00:08:47
Que algunos dispositivos que heredan de ti
00:08:48
Sobrescribirán
00:08:51
¿Por qué no?
00:08:52
Y luego habrá algunos métodos que dices
00:08:53
Mira, este de aquí
00:08:56
A este nivel de generalización
00:08:57
A nivel de dispositivo
00:08:59
No sabría qué poner
00:09:00
Porque es demasiado concreta la idea
00:09:01
Para poder ponerla a este nivel
00:09:04
Seguro que si lo pongo aquí en implementación
00:09:06
Vale para algunos dispositivos y para algunos otros no
00:09:08
Entonces lo que hago es
00:09:11
Poner un
00:09:13
Método abstracto, ¿vale?
00:09:14
Decir, todos tienen que tener este método
00:09:16
Todos tienen que tener el método de estado
00:09:19
Pero cada uno lo implementará
00:09:21
Según sus necesidades
00:09:23
¿Sí?
00:09:24
Entonces otro ejemplo
00:09:28
Podría ser que un vehículo
00:09:29
En general tiene la capacidad de moverse
00:09:31
¿Vale? O sea que
00:09:33
Tiene que tener un método muévete, un método transporte, un método deslízate, qué sé yo.
00:09:35
Pero, como luego se hace este método, depende mucho de qué tipo de vehículo es.
00:09:42
Si es un barco, un avión, un tren, un coche, una bicicleta o lo que sea.
00:09:48
Por lo tanto, vehículo podría ser una clase abstracta con algunos métodos y algunas características
00:09:54
que son propias de todos los vehículos, entonces los implementa allí, y algunos métodos que son abstractos, que sé que todos los vehículos
00:10:02
lo tienen que hacer, pero cómo lo hacen depende del vehículo concreto, o sea, de la subclase que estenda el vehículo, ¿sí?
00:10:10
Entonces, una clase abstracta puede declarar, además que métodos normales, como los que hemos conocido nosotros, métodos abstractos,
00:10:22
Métodos que no tienen las paréntesis, las llaves
00:10:30
¿Vale? No tienen cuerpo
00:10:36
Te estoy diciendo que este método existe
00:10:37
Pero no te estoy diciendo cómo se implementa
00:10:40
Lo tendrás que implementar tú cuando me extendes
00:10:42
¿Vale?
00:10:44
Un método abstracto es aquel que no tiene más que la definición del mismo
00:10:49
Sin su implementación
00:10:54
Como por ejemplo, esta cosa aquí que veis
00:10:56
¿Vale?
00:10:59
public abstract int
00:10:59
método abstracto, tipo 1 para 1
00:11:02
tipo 2 para 2, etc
00:11:04
punto y coma, define
00:11:06
un método abstracto, vale
00:11:08
es esta aquí la clave
00:11:10
que nos da, vale, este abstract
00:11:12
cuando yo pongo abstract
00:11:13
el modificador abstract en un método
00:11:16
estoy diciendo que este método
00:11:18
no me espero que esté implementado
00:11:19
por lo tanto al final no me espero
00:11:21
una llave, el cuerpo del
00:11:24
método y luego otra llave
00:11:26
Que lo cierra diciendo, este bloque aquí es el cuerpo de este método.
00:11:28
Porque no lo voy a implementar, es un método abstracto.
00:11:31
¿Sí?
00:11:36
Vale.
00:11:37
Un método abstracto debe ser obligatoriamente redefinido en sus subclases no abstractas.
00:11:38
¿Vale?
00:11:45
Si yo heredo desde la clase vehículo que tiene un método abstracto,
00:11:45
heredo esta clase, creo coche que hereda de vehículo,
00:11:51
pues coche tiene dos opciones.
00:11:54
O es abstracto él también, es una clase abstracta él también, entonces puede dedicar algunos métodos abstractos.
00:11:57
O si esa clase, si la subclase no es abstracta, es una subclase como toda la que hemos dicho nosotros,
00:12:05
tiene que implementar todos los métodos abstractos.
00:12:11
De esta forma yo me aseguro que cualquier subclase de una clase abstracta tiene esos métodos.
00:12:17
A lo mejor no hace nada con esos métodos
00:12:23
A lo mejor devuelve null
00:12:24
A lo mejor es abierta la llave
00:12:26
Cerra la llave
00:12:29
Que sería muy mala programación
00:12:30
Pero algo tiene que hacer
00:12:31
Puede ser nada
00:12:35
Puede ser imprimir algo en pantalla
00:12:36
Puede ser hacer una base de datos
00:12:38
No lo sé, pero algo tiene que hacer
00:12:41
Tengo que implementar
00:12:42
Esa cosa
00:12:45
Ese método abstracto
00:12:46
¿Sí?
00:12:50
Se permite declarar en la superclase un comportamiento que deberán cumplimentar todas las subclases.
00:12:53
Es decir, si os acordáis, en la orientación a objetos, los métodos definen comportamientos.
00:13:02
Definen qué puede hacer este objeto.
00:13:09
Una clase abstracta me está definiendo que cualquier subclase mía podrá hacer una determinada cosa sin definir cómo se hace esa determinada cosa.
00:13:11
Yo te digo que cada vehículo podrá moverse, pero no te digo cómo.
00:13:23
Cómo dependerá de la subclase que eres.
00:13:28
La subclase coche implementará moverse de una forma distinta a la clase barco.
00:13:30
Pero las dos tendrán el método moverse.
00:13:35
Figura geométrica tendrá calcular área, pero cómo se calcula esta área depende de la subclase.
00:13:39
La subclase triángulo tendrá una implementación de calcular área distinta de la clase cuadrada.
00:13:45
Que tendrá, porque heredan los dos
00:13:51
De figuras geométricas, tendrá que calcular área
00:13:54
Pero se calculará de forma distinta
00:13:56
¿Dudas?
00:13:58
Nosotros no hemos hablado mucho de UML
00:14:07
¿Lo habéis visto en algún lado?
00:14:10
UML, todavía no
00:14:11
Universal Modeling Language
00:14:13
Es un lenguaje
00:14:17
Universal
00:14:18
Para poder hablar
00:14:20
De programación
00:14:22
Cuando se tiene que dar las especificas
00:14:23
De un sistema
00:14:26
¿Vale? Sobre todo esto en el mundo de la ingeniería del software
00:14:27
¿Vale? Se necesita ser formalmente completos
00:14:31
Para que vosotros entendáis cuál es el ejercicio
00:14:37
Es un poco como si yo os dijera en un examen
00:14:40
Hazme una clase que hace cosas
00:14:42
Y tú te pones y haces tu clase que hace cosas al azar
00:14:44
Y te digo, no, no era lo que habías pensado
00:14:47
¿Vale? Cero
00:14:49
Pues no puede ser, ¿vale?
00:14:51
Entonces, a nivel nuestro de ejercicios sencillos
00:14:53
Ponemos una descripción sencilla
00:14:57
Cuando se llega a tener que hacer sistemas muy, muy complejos
00:14:58
Pensad a un sistema como un sistema operativo
00:15:03
¿Vale?
00:15:06
Que tiene un mogollón de módulos
00:15:06
Un mogollón de clases
00:15:08
Un mogollón de cosas que se puedan interlazar entre ellas
00:15:09
Y que tienen que tener vínculos entre ellos
00:15:13
Hablarlo en lenguaje natural, normal, castellano y cosas por el estilo
00:15:15
después se va a ver un caos.
00:15:22
Entonces, existe una forma de hacer lo que son los UML,
00:15:24
que sustancialmente proporciona una serie de diagramas,
00:15:29
una serie de modos formales, ¿vale?
00:15:32
Métodos formales para definir cómo están hechas las clases,
00:15:36
qué tienen que tener, cómo tienen que relacionarse.
00:15:40
A veces, estos cuadraditos que os he hecho yo, que ponían tres celdas,
00:15:44
Una celda ponía el nombre
00:15:49
Una celda ponía los atributos
00:15:50
Y una celda ponía los métodos
00:15:52
Pues ese es un OML
00:15:54
Es el diagrama de clases de OML
00:15:55
¿Vale?
00:15:58
Tiene el diagrama
00:16:00
De clases de OML
00:16:02
Si alguna vez veréis
00:16:05
Unos diagramas hechos como parecidos a estos que veis ahora mismo
00:16:06
Si quiero hacer una clase abstracta
00:16:09
La pongo en cursiva
00:16:11
O pongo específicamente
00:16:13
Un modificador que pone abstract
00:16:15
¿Sí?
00:16:17
Esto es para que tengáis una idea de que es OML muy muy básica
00:16:19
Luego hay asignaturas que lo que hacen es profundizar en los 12 o 13 diagramas que proporciona OML
00:16:24
Que sustancialmente sirven para organizarnos
00:16:33
Es documentación
00:16:36
La idea es que cuando he documentado bien un plano OML o un documento OML
00:16:37
Luego lo puedo dar a todos los grupos de trabajo implicados en el mismo sistema y todos saben que hace lo de todo.
00:16:44
Y qué métodos hay en cada clase, cómo interaccionan las clases y cómo se relacionan.
00:16:52
¿Os acordáis la flechita que utilizábamos para conectar una subclase a una superclase?
00:16:57
No sé si la habéis visto en los dibujos.
00:17:05
Cuando yo os decía, esta es una relación, es un, y la clase, la otra clase, eran conectadas por una flechita.
00:17:07
Porque la flechita es como ML indica la relación de herencia.
00:17:15
Si yo conecto dos clases con una flechita, estoy diciendo que esta hereda de esta otra.
00:17:21
Entonces, aquí, por ejemplo, en este diagrama de clases que vemos aquí,
00:17:27
vemos que la clase subclase hereda de la clase superclase,
00:17:31
Que es una clase abstracta porque está escrita en cursivo
00:17:35
Y que la clase superclase tiene el método 1 y el método 2
00:17:37
Y entonces la subclase tendrá también el método 1 y el método 2
00:17:43
Y el método 2, si no me equivoco, está en cursiva
00:17:47
Por lo tanto, el método 2 es el abstracto
00:17:52
Y tendrá que ser reimplementado
00:17:55
O mejor, implementado en la subclase
00:17:58
Mientras el método 1
00:18:01
Si no está en cursiva
00:18:04
Pues entonces es un método no abstracto
00:18:06
Es un método real
00:18:09
Entonces la subclase puede
00:18:10
O no hacer nada
00:18:12
Y entonces lo hereda directamente desde la superclase
00:18:13
Porque ya está implementado
00:18:16
O reescribirlo
00:18:17
Con la sobrescriptura que hemos visto el otro día
00:18:19
Si es que quiere añadir algo
00:18:22
Con respecto a lo que hace
00:18:26
La superclase
00:18:27
¿Sí? Bueno, esto para que lo veáis
00:18:30
De vez en cuando
00:18:33
A lo mejor volverá a salir
00:18:36
Esto de un L en algún diagrama
00:18:37
Y cosas por el estilo, ¿vale?
00:18:39
Es porque en algún momento teníamos que empezar
00:18:41
A hablar de él, pues hoy
00:18:43
Es ese
00:18:45
¿Vale? Entonces, cosas
00:18:46
Sobre las clases abstractas
00:18:51
Vamos a ver el ejemplo y luego vemos que se puede hacer
00:18:53
Y que no se puede hacer, ¿vale?
00:18:55
Aquí tenemos public abstract class figura
00:18:56
¿Vale?
00:18:59
Con pables astrat void dibuja
00:19:00
¿Vale?
00:19:03
Entonces, esta de aquí podría ser una clase astrata
00:19:04
Es una clase que no tiene una implementación
00:19:07
Y tiene el método dibuja
00:19:09
Cualquier clase que extenda figura
00:19:11
Tiene que implementar el método dibuja
00:19:15
Pero claro, dibujar una figura
00:19:20
Una figura dependerá de qué figura eres
00:19:22
No es lo mismo dibujar un cuadrado
00:19:24
Que dibujar un triángulo
00:19:26
asumiendo que sepamos dibujar
00:19:27
formas como
00:19:30
si no aquí podría ser calcular
00:19:31
entonces veremos que por ejemplo
00:19:33
la public clase rectángulo
00:19:37
está en la figura
00:19:38
pues tendrá que implementar dibujo
00:19:39
pregunta para vosotros
00:19:42
¿rectángulo es una clase abstracta?
00:19:44
¿por qué no?
00:19:48
porque no pone abstract
00:19:50
entonces si no es abstracta
00:19:51
tiene que implementar
00:19:55
Todos los métodos abstractos
00:19:56
De la clase que estende
00:19:58
No los puede dejar sin implementación
00:20:00
Si no, da un error
00:20:03
¿Ok?
00:20:05
Ahora, si yo pusiera public abstract
00:20:08
Clase rectángulo extensa figura
00:20:10
¿Podría dejar
00:20:13
Dibuja sin implementar?
00:20:14
Sí, tranquilamente
00:20:17
Porque estoy extendiendo, pero sigo siendo
00:20:18
Abstracto
00:20:21
Porque a lo mejor por debajo del rectángulo hay
00:20:22
Rectángulo normal
00:20:25
Y cuadrado, que es un rectángulo especial
00:20:28
Y también
00:20:31
Esta public class círculo está en la figura
00:20:36
Que igualmente tendrá que implementar dibujas
00:20:39
Cada uno tendrá su propia implementación
00:20:41
Esto es como si fuera
00:20:43
Un menú, ¿vale?
00:20:45
La parte abstracta, donde te digo
00:20:46
Mira, las figuras abstractas
00:20:49
Lo que pueden hacer es esto, esto, esto, esto
00:20:51
¿Cómo lo hacen?
00:20:52
Depende del hijo
00:20:54
¿Vale? Dependerá de
00:20:56
Que figura es en concreto
00:20:58
Pero toda la figura tiene que poder
00:21:00
Calcular el perímetro, calcular el área
00:21:02
Y calcular su volumen
00:21:05
Si la extrapolo
00:21:07
Aquí hago todos los
00:21:08
Posibles comportamientos de una figura
00:21:11
Sin implementarlo
00:21:13
Porque no se implementarlo
00:21:16
Una figura es demasiado genérica para implementarla
00:21:17
Entonces
00:21:19
Asumiendo que sepa hacer
00:21:21
Más o menos una clase abstracta
00:21:23
¿Qué puede o no puede hacer
00:21:25
Con las clases abstractas?
00:21:27
Cosa fundamental e importante
00:21:28
No se pueden instanciar clases abstractas
00:21:30
No puede hacer figura x es igual a new figura
00:21:34
¿Por qué no?
00:21:37
Porque tendría un objeto con un método cuyo cuerpo no existe
00:21:40
Entonces cuando luego llamo x.dibuja, ¿qué debería hacer si su método no existe?
00:21:50
Una figura abstracta no puede ser concreta
00:21:56
No puedo crear un objeto
00:21:59
Concreto a partir de una clase
00:22:01
Abstract
00:22:03
Se pueden instanciar clases herederas
00:22:04
Siempre que no sean abstractas a su vez
00:22:11
Es decir, nadie me prohíbe
00:22:13
Hacer rectángulo X
00:22:15
Es igual a un rectángulo
00:22:16
Rectángulo es ten de figura
00:22:18
Pero lo que habrá hecho es implementar
00:22:20
Todos los métodos abstractos
00:22:22
Entonces ahora
00:22:24
Podré tranquilamente crearme un objeto
00:22:25
Rectángulo o un objeto círculo
00:22:28
Y la cosa divertida es que se pueden instanciar su clase usando la referencia a la clase padre
00:22:30
Es decir, si puede hacer figuraX es igual a newRectangulo
00:22:39
Que en un cierto sentido ya lo hemos hecho
00:22:46
Cuando nosotros hacíamos un array de personas y poníamos dentro los empleados
00:22:51
Empleados o gerentes, que todos eran personas
00:22:58
Pues aquí lo estaba haciendo
00:23:01
Porque la referencia de mi array
00:23:03
Cada celda puede tener una persona
00:23:06
Pero yo dentro de la persona ponía un empleado
00:23:08
Un new empleado
00:23:11
Estaba haciendo esto
00:23:13
Figura f es igual a new rectángulo
00:23:15
¿Por qué puedo hacerlo?
00:23:18
Porque la relación de extend de herencia
00:23:21
Me dice que un rectángulo es una figura
00:23:29
Oye, pero ahora tengo un problema
00:23:32
Si yo lo considero como figura, esto es abstracto
00:23:37
No, porque su instancia es un rectángulo
00:23:40
Yo he hecho ni un rectángulo
00:23:46
Entonces, ¿os acordáis de eso?
00:23:47
De que cuando luego llamo el método dibuja
00:23:50
Se aplica a la instancia
00:23:52
Por lo tanto, se aplicará el dibuja de rectángulo
00:23:55
Que sí tiene implementación
00:23:58
No el dibuja de figura que no tiene implementación
00:24:00
y esto es el polimorfismo
00:24:04
que ahora le pasa
00:24:08
dudas hasta aquí
00:24:09
por ahora tiene que quedar claro que
00:24:11
hay clases abstractas y clases no abstractas
00:24:13
la clase no abstracta la conocéis
00:24:16
la habéis hecho mil veces
00:24:18
las clases abstractas pueden indicar
00:24:18
métodos abstractos
00:24:22
métodos que yo no te digo que hace
00:24:23
pero te digo que si tiene que existir
00:24:25
en el momento en que yo soy una clase abstracta
00:24:27
no puedes crear instancias mías
00:24:30
No puedes hacer new de esa clase abstracta
00:24:33
¿Vale?
00:24:37
Si figura en una clase abstracta no puede hacer new figura
00:24:37
Porque no se puede
00:24:40
Porque hay partes que no son concretas
00:24:41
Que no existe código
00:24:44
¿Vale?
00:24:45
A partir de una clase abstracta puedes heredar en otras clases
00:24:47
Puedes hacer subclases
00:24:52
¿Vale?
00:24:53
Estas subclases pueden ser abstractas a su vez
00:24:54
Entonces crear una cadena de clases abstractas
00:24:58
Pero lo más normal es que las clases que heredan de una clase abstracta sean concretas, sean normales.
00:25:02
Y entonces, la obligación que tienen es que todos los métodos abstractos los tienen que implementar.
00:25:08
¿Y los métodos no abstractos?
00:25:14
No tiene por qué.
00:25:19
Si no lo reimplementa, heredará el del padre, tal y cual.
00:25:22
Y si lo reimplementa, lo estará sobrescribiendo el del padre.
00:25:28
Como hemos sobrescrito alguna vez
00:25:32
Algunos métodos en clases anteriores
00:25:34
¿Sí?
00:25:37
Sí, te da un error
00:25:39
Te da un error Java
00:25:44
Diciéndote, oye mira, tú aquí
00:25:46
Estás diciendo que está en desfigura
00:25:47
Figura tiene este método de astrato
00:25:49
Y tú no lo has implementado
00:25:51
Un error que se puede detectar
00:25:52
A tiempo de compilación
00:25:56
O sea, antes de ejecutarlo
00:25:58
El Java, el Eclipse
00:25:59
Os pone la raíta roja debajo
00:26:02
Diciendo que aquí falta algo
00:26:04
Lo veréis ahora
00:26:05
Hacemos un ejemplo
00:26:08
Y ponemos
00:26:09
No lo ponemos este de aquí
00:26:10
Oye, mira, aquí falta
00:26:13
Y
00:26:15
Puedo hacer
00:26:17
Instancias de las clases
00:26:20
Hijos
00:26:22
Y la cosa
00:26:23
Un poquito más interesante es esta de aquí
00:26:26
Puedo crear una instancia
00:26:28
De la clase hijo
00:26:30
Pero guardarla
00:26:32
en una referencia de la clase
00:26:34
piada, ¿vale? A este punto
00:26:36
dos o tres veces
00:26:38
ya lo hemos dicho de la diferencia entre
00:26:40
referencia e instancia
00:26:42
¿sí? Si queréis
00:26:43
lo repasamos un segundo
00:26:45
para que nos entendamos, ¿vale?
00:26:48
Pero la idea es que cuando yo hago una new
00:26:52
de algo
00:26:53
¿qué bien escribo?
00:26:56
Lo que estoy haciendo es crear por algún
00:26:59
lado en la memoria un objeto algo que tendrá dentro sus propios parámetros y
00:27:03
que podré hacer sobre él lo que sea vale si yo hago sólo algo creo este
00:27:13
objeto que en automático se destruye porque no tengo lo que se llama un
00:27:19
manejador un handler no tengo forma de acceder a este trozo de memoria con algo
00:27:26
Y nada más, he creado el objeto
00:27:33
Y ahora no tengo forma
00:27:35
De acercarme a él
00:27:37
De referenciarlo
00:27:38
Necesito por algún lado
00:27:40
Un
00:27:42
Trozo de memoria
00:27:43
Que me diga dónde ir
00:27:46
Para encontrar el objeto
00:27:48
Su referencia
00:27:50
Esta es la referencia
00:27:52
Aquí está la referencia
00:27:54
¿Cómo lo hacemos nosotros esto normalmente?
00:27:55
Decimos que existe una referencia
00:27:58
De tipo algo
00:28:00
Que puede contener algo
00:28:01
Que se llama X por ejemplo
00:28:03
Que es igual a esta cosa de aquí
00:28:05
Esta línea de código
00:28:07
Me crea dos cosas en memoria
00:28:10
Por un lado
00:28:13
X que es una referencia a un objeto
00:28:14
Y por otro lado
00:28:17
Una instancia de la clase algo
00:28:20
Que es el objeto mismo
00:28:23
Entonces cuando yo hago
00:28:24
Super algo
00:28:28
Entendido como super algo, una clase padre de algo
00:28:33
Algo extende super algo
00:28:40
Este x de aquí en realidad como referencia es un super algo
00:28:41
Pero como instancia sigue siendo una instancia de algo
00:28:48
Es lo que se está diciendo aquí en este parrafito de antes
00:28:59
Que yo puedo crear una instancia de una subclase
00:29:04
Y referenciarla con una superclase
00:29:08
Tener una variable de tipo superclase
00:29:12
Que apunte a un objeto de tipo subclase
00:29:16
Y esto lo puede hacer porque algo es un superalgo
00:29:21
Porque lo excede
00:29:25
Al revés no podría
00:29:26
¿Dudas?
00:29:28
¿Preguntas?
00:29:32
Esta parte de aquí
00:29:37
Se puede instanciar subclase
00:29:38
Utilizando la referencia a la clase padre
00:29:40
La clase padre es figura, la subclase es rectángulo
00:29:43
Puedo crear una nueva instancia de rectángulo
00:29:48
Referenciándola con una figura
00:29:51
¿Dudas?
00:29:54
Entonces, aquí subentra el concepto de polimorfismo
00:29:59
Para poder utilizar estas cosas
00:30:07
Asumiendo que yo pueda tener referencias
00:30:08
que me dicen, este objeto
00:30:12
como referencia es
00:30:14
una figura, pero en realidad
00:30:16
dentro es un rectángulo
00:30:18
y cosas por el estilo, a ver
00:30:20
esto
00:30:22
a qué me expone
00:30:22
y qué implica y qué puedo hacer con ello.
00:30:25
¿Vale? En general
00:30:28
cuando hablamos de polimorfismo
00:30:30
¿Vale? Desde el griego poli
00:30:32
muchos morfos
00:30:34
que es forma, creo.
00:30:36
Muchas formas, creo.
00:30:37
Dos métodos.
00:30:40
son polimórficos
00:30:41
si con el mismo nombre
00:30:43
hacen funciones distintas
00:30:45
aunque similares
00:30:48
en objetos distintos
00:30:49
yo tengo el método
00:30:51
moverse
00:30:53
que tiene el mismo nombre
00:30:54
pero hace cosas distintas si yo lo uso
00:30:56
sobre un tren que si yo lo uso
00:30:59
sobre un coche
00:31:01
tengo el cálculo área
00:31:02
que es el mismo nombre, el mismo método
00:31:04
pero hace cosas distintas
00:31:07
si yo lo llamo sobre un triángulo
00:31:09
O si yo lo llamo sobre un cuadrado
00:31:11
¿Sí?
00:31:13
El objetivo es el mismo
00:31:15
Es calcular el área
00:31:17
¿Vale? O sea que la operación abstracta
00:31:18
Es la misma
00:31:22
Pero la forma
00:31:23
La implementación de esa
00:31:25
De cómo se hace esa cosa
00:31:27
Depende del aspecto sobre el que lo llamo
00:31:29
¿Sí?
00:31:31
Un ejemplo, el método del ritmo es
00:31:33
Calcular áreas de rectángulos de círculo
00:31:35
¿Vale? El método se llama igual
00:31:37
Pero hace cosas distintas en rectángulo y círculo
00:31:39
Para obtener la misma cosa
00:31:42
Que es calcular el área
00:31:44
Si hablamos a nivel de clase
00:31:46
El polimorfismo es lo que nos permite
00:31:50
Crear una clase con la referencia padre
00:31:53
Que pero apunta a una clase hija
00:31:55
Lo que decíamos antes
00:31:57
De figura F es igual a new rectángulo
00:31:58
Es esta cosa aquí
00:32:00
Utilizando el polimorfismo
00:32:02
Utilizando que figura
00:32:05
si tiene el objeto
00:32:07
el método
00:32:10
abstracto
00:32:11
entonces lo puede utilizar, moverse
00:32:13
pero luego dentro estará implementado
00:32:15
de otra forma, de forma de rectángulo
00:32:17
de forma de círculo
00:32:20
pues es donde digamos
00:32:21
nos interesa tener el polimorfismo
00:32:23
cuando se usa un método sobre un objeto
00:32:25
se usará el de la clase del que el objeto es instancia
00:32:30
esta es la clave
00:32:33
fundamental del
00:32:35
polimorfismo
00:32:36
cuando yo llamo el método
00:32:38
cálculo área sobre una
00:32:40
variable, sobre una referencia
00:32:43
no es la referencia
00:32:45
que manda, sino
00:32:47
la instancia a la que se referencia
00:32:49
la que manda
00:32:51
es decir que
00:32:52
si yo tengo
00:32:54
una cosa del estilo y
00:32:57
llamo x.método
00:32:58
se utilizará
00:33:01
el método método
00:33:03
De super algo o de algo
00:33:04
De algo
00:33:07
Porque no obstante
00:33:09
X sea un super algo
00:33:11
Entonces x.método1
00:33:12
Debería llamar algo de super algo
00:33:15
El método de super algo
00:33:17
Pues en realidad
00:33:19
La instancia es algo
00:33:21
He hecho un new de algo
00:33:23
Por lo tanto yo voy a buscar la implementación
00:33:24
De este método en la clase algo
00:33:27
No en la clase super algo
00:33:29
En la clase i
00:33:31
No en la clase a
00:33:32
Acabo la práctica
00:33:33
Ahora hay ejemplos
00:33:43
Y luego después
00:33:44
Acabo la teoría
00:33:46
Creo que hay un ejemplo
00:33:48
Luego lo hacemos
00:33:53
Pero ya lo hemos hecho
00:33:58
Cuando hemos hecho empleado y gerente
00:34:01
Y llamábamos el mismo método
00:34:05
Sobre empleado excedente
00:34:06
Aquí hemos hecho otro enfoque
00:34:07
No hemos hecho
00:34:12
Os explico la teoría y luego os hago la práctica
00:34:13
Sino os he hecho hacer alguna vez
00:34:15
En la práctica, os he dado ejemplos ya
00:34:17
En días anteriores y ahora os estoy explicando
00:34:18
La teoría detrás de eso
00:34:21
De esta forma sí, luego os voy a hacer unos ejemplos
00:34:22
¿Dónde estábamos?
00:34:24
Aquí, sí
00:34:27
¿Cuántos euros al mes?
00:34:28
Esto es lo que decía
00:34:29
Entonces cuando yo llamo
00:34:32
Un método sobre una diferencia
00:34:33
Sobre una variable
00:34:37
Voy a mirar en realidad
00:34:38
La instancia interna de esta materia
00:34:40
Si no fuera así
00:34:42
En una situación
00:34:44
Como esta
00:34:47
Figura f igual a un rectángulo
00:34:48
Si ahora llamara f.calcularia
00:34:50
Si mandara figura
00:34:53
Figura me iría
00:34:55
Al método calcularia abstracto
00:34:57
Entonces me diría
00:35:00
No, no tienes una implementación
00:35:00
No puedes hacer nada
00:35:02
Sin embargo, como lo que se usa es el rectángulo
00:35:03
Pues entonces él dice, vale, no importa
00:35:09
Aún si tú estás usando una referencia figura que es superclase
00:35:11
Yo sé que lo que estás utilizando es un objeto rectángulo
00:35:17
Voy a llamar el método del rectángulo
00:35:20
La implementación que sí existe dentro del rectángulo
00:35:23
Y si yo tuviera figura f es igual a new figura
00:35:27
y ahora hiciera f.calcularia
00:35:31
¿qué pasaría?
00:35:34
me grita
00:35:39
no puedo
00:35:40
no puede existir figura f
00:35:42
es igual a newfigure
00:35:45
no puedo crear una instancia
00:35:46
de una clase abstracta
00:35:48
vale, entonces podemos usar
00:35:51
una superclase
00:35:57
como parámetro formal y luego
00:35:58
usar el método apropiado
00:36:00
basándose sobre el objeto pasado
00:36:02
como parámetro actual
00:36:04
Es decir, que esta cosa del polimortismo
00:36:05
Y de que puedo mezclar padres e hijos
00:36:11
En un cierto sentido
00:36:15
Me permite también utilizarse a nivel de métodos
00:36:16
Yo puedo declarar un método
00:36:20
Que como parámetro pilla un figura
00:36:22
Esto sería el parámetro formal
00:36:26
Que cuando lo defino digo
00:36:28
Public void
00:36:31
Calcula área
00:36:33
de entre paréntesis figura
00:36:35
X
00:36:38
y a la hora de utilizar este
00:36:38
método, llamarlo
00:36:42
con un rectángulo
00:36:44
hacer cálcula
00:36:45
área entre paréntesis
00:36:47
de mi rectángulo
00:36:50
no se que más
00:36:51
haría lo mismo que aquí
00:36:52
estoy asociando
00:36:55
una figura como referencia
00:36:57
a un objeto que en realidad es un rectángulo
00:37:00
pero eso me abre
00:37:02
un mundo, que yo pueda hacer
00:37:04
operaciones, pueda hacer métodos
00:37:06
sobre figuras en general
00:37:08
y luego pasarle
00:37:10
como parámetros
00:37:12
rectángulos, cuadrados, círculos
00:37:12
triángulos, lo que me da la gana
00:37:16
porque yo lo que estoy haciendo es sobre
00:37:18
rectángulos, yo estoy llamando
00:37:20
allí dentro y utilizando
00:37:22
cosas abstractas
00:37:23
dibuja, calcula
00:37:26
área, cosas por el estilo, como si fuera
00:37:28
una figura, lo que me permite hacer
00:37:30
un figura, pero luego cuando
00:37:32
le paso el parámetro, no le paso
00:37:34
un figura, le paso un rectángulo
00:37:36
entonces estaré utilizando todos estos métodos
00:37:37
que he utilizado, que existen abstractos
00:37:40
en figuras y que ahora están
00:37:42
implementados en rectángulos
00:37:44
entonces me funciona
00:37:45
entonces puedo hacer cosas abstractas con las figuras
00:37:47
y luego cada
00:37:50
figura se
00:37:52
implementará y hará el trabajo
00:37:54
como figura propia
00:37:56
si es un rectángulo hará lo que hace un rectángulo
00:37:57
si es un cuadrado hará lo que hace un cuadrado
00:37:59
Cuando tenemos que crear un objeto de una clase de dada
00:38:01
Podemos utilizar como clase diferenciada la clase del padre o la del hijo
00:38:11
¿Vale?
00:38:15
Tenemos una clase padre y una hijo
00:38:15
¿Vale?
00:38:18
Es decir, que todos estos tres métodos, estas tres cosas pueden pasar
00:38:18
¿Sí?
00:38:22
Si yo tengo una clase padre
00:38:24
Que es padre
00:38:26
Y una clase hijo que estén de padre
00:38:27
Estas tres cosas me valen
00:38:30
¿Vale?
00:38:32
Padre object es igual a new hijo
00:38:33
Me vale
00:38:36
Padre object es igual a new padre
00:38:37
Me vale
00:38:41
Siempre y cuando
00:38:42
No sea abstracto
00:38:43
Padre no sea abstracto
00:38:46
Solo si padre no es abstracto
00:38:47
Si a padre es abstracto
00:38:50
Esto no me funciona
00:38:52
Y también puedo hacer
00:38:53
Hijo objecto es igual a new hijo
00:38:55
Lo que no puedo hacer es
00:38:56
Hijo objecto es igual a new padre
00:38:59
Porque hijo no es un padre
00:39:01
Perdón, porque padre no es un hijo
00:39:03
Estas son las tres cosas
00:39:05
Que puede hacer
00:39:11
A nivel de herencia
00:39:14
¿Sí? Y cuando digo padre
00:39:15
Digo padre, abuelo, tatarabuelo
00:39:17
Lo que sea
00:39:19
¿Sí? Eso no importa
00:39:20
A nivel de herencia
00:39:23
Si tengo A que hereda de B que hereda de C
00:39:24
Pues C es un A
00:39:27
C es un B que es un A
00:39:28
¿Sí?
00:39:31
Entonces, estas son las cosas que puedo utilizar
00:39:34
Acordaos de esto
00:39:37
O sea, que quiere decir que
00:39:38
Yo cuando tengo un hijo y utilizo poligonfismo
00:39:40
Lo que hemos hecho hasta ahora
00:39:43
Hasta antes de ver las clases abstractas
00:39:45
Era esta cosa aquí
00:39:47
¿Vale? En el sentido que nosotros o los padres
00:39:48
Era una clase normal y corriente
00:39:50
Que podía instanciar
00:39:52
Porque no tenía métodos abstractos
00:39:54
Y luego en el hijo si quería sobreescribía
00:39:56
Y eso es perfectamente legítimo
00:39:59
Lo puede hacer
00:40:01
Las clases abstractas
00:40:02
Añaden un pasito más
00:40:04
Que es, ok, mas si yo tengo un método
00:40:06
Que en la clase padre
00:40:08
Sé que tiene que estar
00:40:10
Pero no puedo definir
00:40:11
Prácticamente el método
00:40:13
Crea
00:40:16
Calcular área de la figura
00:40:18
¿Vale? ¿Cómo puedo decir
00:40:20
Oye mira, todas las figuras pueden poder
00:40:22
Calcular su área, pero sin decir
00:40:24
Cómo se hace
00:40:26
¿Sí?
00:40:27
And finally
00:40:30
El morfismo
00:40:33
Downcasting
00:40:36
La última cosa
00:40:37
Que ya he utilizado
00:40:39
Es lo que se llama el downcasting
00:40:41
El downcasting es cuando
00:40:44
Yo tengo una referencia
00:40:46
Y la quiero
00:40:48
Tratar como si fuera un hijo
00:40:49
Yo tengo figura
00:40:52
Y quiero, oye, mira
00:40:54
Pero esta figura X
00:40:56
En realidad es un rectángulo
00:40:58
Y como necesito un método que solo existe en rectángulo
00:40:59
Y no existe en figura
00:41:03
Quiere hacer un downcast
00:41:04
De este objeto
00:41:06
Desde padre a hijo
00:41:08
Y como se hace
00:41:10
Nosotros esto ya lo hemos hecho
00:41:11
Hemos hecho algunas veces
00:41:14
Que tenía una referencia a persona
00:41:16
Y quería utilizar un método de empleado
00:41:18
Entonces decía, oye mira
00:41:20
Esta referencia de aquí, tráetamela como un empleado
00:41:22
Y a este punto le puedes sacar
00:41:25
Todos los métodos de empleado
00:41:26
Entonces ya lo hemos hecho
00:41:28
Como se llama, downcast
00:41:30
Cuidado que si intentáis hacer un downcast
00:41:32
Y los tipos no son correctos
00:41:35
Puede hacer una class cast exception
00:41:37
¿Vale?
00:41:39
Una excepción de tipo cast
00:41:40
Class cast
00:41:42
¿Sí?
00:41:44
Y aquí
00:41:46
Esto era lo que hizo lo de empleado
00:41:47
En una array que metías
00:41:54
Hay historias
00:41:55
Y para saber si tal metías lo de nistel
00:41:56
Para saber que tal y a partir de ahí el cast
00:41:59
Sí, interesante
00:42:01
Cuando hacéis un downcast
00:42:02
Deberíais
00:42:05
Antes comprobar
00:42:07
Que lo que queréis
00:42:09
Downcastar es una instancia
00:42:11
De lo que queréis
00:42:13
Hacer
00:42:15
¿Sí? Entonces, ¿cómo sería esto?
00:42:15
If var h
00:42:19
Instance of hijo
00:42:20
Entonces, trátame var h
00:42:22
Como hijo y haz lo que quieras
00:42:25
Si te da false
00:42:27
Quiere decir que esta variable aquí
00:42:28
No es una instancia de hijo
00:42:31
Entonces no puedes hacer
00:42:32
Un downcast
00:42:34
Porque si lo haces saltaría
00:42:36
Ahora probamos todas esas cosas
00:42:37
Con ejemplitos
00:42:42
- Autor/es:
- Stefano Chiesa
- Subido por:
- Stefano C.
- Licencia:
- Reconocimiento - No comercial
- Visualizaciones:
- 12
- Fecha:
- 30 de enero de 2023 - 13:36
- Visibilidad:
- Clave
- Centro:
- IES ROSA CHACEL
- Duración:
- 42′ 47″
- Relación de aspecto:
- 1.78:1
- Resolución:
- 1280x720 píxeles
- Tamaño:
- 357.83 MBytes