Saltar navegación

20250121Interfaces Teoria - 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 21 de enero de 2025 por Stefano C.

16 visualizaciones

Descargar la transcripción

Voy a grabar esta clase, por lo tanto si habláis me dais consentimiento para poder grabarlo, ¿vale? 00:00:00
Entonces estamos viendo clases abstractas, polimorfismo, interfaces y lo que sea, ¿vale? 00:00:06
Entonces las clases abstractas hemos entendido que son, hemos empezado a trabajar con ellos, 00:00:11
hemos visto el concepto de que puedo tener el mismo método en clases distintas 00:00:16
y que Java en automático selecciona cuál es la mejor implementación de ese método 00:00:20
en base a la instancia del objeto mismo 00:00:28
no en base a la referencia 00:00:31
hemos visto que yo puedo hacer un downcasting 00:00:32
para utilizar métodos de un hijo 00:00:35
desde una referencia que es de tipo padre 00:00:41
pero la instancia de tipo hijo 00:00:47
y para saber si esta referencia de tipo padre 00:00:49
eso no es una instancia de tipo hijo 00:00:52
siempre tengo la posibilidad de usar el 00:00:56
instance of 00:00:57
y hoy vamos a ver 00:00:58
la última parte de esto 00:01:01
que son las interfaces 00:01:03
hemos dicho que 00:01:05
en Java 00:01:07
no existe la herencia 00:01:08
múltiple, eso quiere decir que yo 00:01:11
cuando heredo de otra clase 00:01:13
tengo que decidir 00:01:15
una sola clase y desde 00:01:17
esa heredo, me importo todos los 00:01:19
digamos que heredo todos los 00:01:21
métodos, las variables, etc. 00:01:23
Pero no puedo, en ningún caso, heredar desde dos clases a la vez. Puedo hacer una cadena, esto hereda de esto, que hereda de esto, que hereda de esto, pero no puedo una misma clase decir hereda de la clase A y hereda también de la clase B. 00:01:25
pero hay veces en el que esto podría ser útil 00:01:40
hay veces en el que yo digo 00:01:45
sí, esta clase debería hacer cosas que hace la clase A 00:01:47
y también debería poder ser capaz de hacer cosas 00:01:50
que hace una clase B 00:01:54
entonces para intentar solucionar esto 00:01:56
en otros lenguajes de programación como C++ 00:02:00
se puede hacer herencia múltiple 00:02:03
pero Java como no lo permite 00:02:05
Pues introduce otro mecanismo parecido, pero un poquito distinto, que son las interfaces, ¿vale? Es un concepto parecido a las clases abstractas, ¿vale? Es decir, defino una estructura formal de métodos, una serie de métodos, un conjunto de métodos, que mi clase seguramente va a tener. 00:02:07
Voy a crear un contrato en el que digo, oye, mira, yo soy la interfaz algo 00:02:31
Cualquier clase que diga que va a utilizar, ahora veremos cómo se dice técnicamente 00:02:42
La interfaz algo, tendrá necesariamente que implementar este método, este método, este método 00:02:50
De esa forma, si yo sé una clase cualquiera, esté donde esté 00:02:57
Si usa, si hace algo, se implementa, se dice, la interfaz a algo, seguramente sobre esta clase puedo llamar estos tres métodos. 00:03:03
¿Por qué? Porque es un contrato. La interfaz me dice, si quieres implementar esta interfaz, necesitas haber implementado estos tres métodos. 00:03:14
Es lo mismo que la clase abstracta en un cierto sentido, solo que la clase abstracta podía también tener una parte concreta y luego tener algunos métodos abstractos. En vez, en una interfaz es como si fuera una clase abstracta donde todos los métodos son abstractos. 00:03:24
¿Sí? Esto me permite que en una clase yo pueda extender, entonces heredar de una clase, pero implementar otras, otras interfaces. 00:03:38
Yo puedo implementar cuantas interfaces me da la gana, ¿vale? 00:03:57
Entonces, si yo tengo mi clase, le digo implementas esta interfaz, esta otra y esta otra, 00:04:01
y yo sé que tendrá que tener los métodos de las tres interfaces, los métodos definidos como abstractos en las tres interfaces que yo voy a implementar. 00:04:05
Se parecen a las clases abstractas, pero a diferencia de estas, todos sus métodos son obligatoriamente abstractos. 00:04:19
Y como los métodos son obligatoriamente abstractos, no se pone abstracto. 00:04:26
se da por hecho 00:04:30
¿vale? porque es la primera vez 00:04:32
ahora lo veremos, que cuando yo defino 00:04:35
una interfaz, no la defino 00:04:37
como public class 00:04:39
la defino como public interface 00:04:40
entonces es una cosa distinta de las clases 00:04:43
las clases son clases, estas son interfaces 00:04:47
si yo estoy definiendo una interfaz 00:04:49
en automático sé que 00:04:51
todas las declaraciones de sus métodos 00:04:53
van a ser abstractas 00:04:55
y como sé que tienen que ser abstractas 00:04:56
no hace falta poner que son abstractas, así como no hace falta poner que la interfaz es abstracta, ¿vale? 00:04:58
Es una forma, digamos, de simplificar el concepto de la clase abstracta, de decir, en vez de ponerte abstracta por todo lado, 00:05:06
pues te doy esta forma de hacerlo, que es con la interfaz, si tú estás haciendo una clase que sólo tendría métodos abstractos, 00:05:13
en vez de hacerte la clase abstracta con todos los métodos abstractos, hazte una interfaz declarando los métodos, 00:05:21
Y estos serán los métodos abstractos que se tendrán que implementar. 00:05:26
Entonces está la clase concreta, está al lado opuesto la interfaz, donde todos los métodos son abstractos, 00:05:32
y luego está la clase abstracta, que es una mezcla de los dos. 00:05:39
Es una clase que puede tener una parte concreta y puede tener una parte abstracta. 00:05:43
Entonces, dependiendo de lo que necesito yo, uso una cosa u otra. 00:05:47
Si todos mis métodos son abstractos, ¿puedo hacer una clase abstracta cuyos métodos son todos abstractos? 00:05:52
Sí. ¿Por qué no es una buena idea? 00:05:59
Lo mismo en la interfaz. 00:06:02
Porque si yo hago una clase abstracta, estoy bloqueando la clase que estoy creando, la esfuerzo a heredar de mí. 00:06:09
Y entonces no puede heredar de otra. 00:06:17
Y si mi clase no le proporciona nada porque todo es abstracto, es mejor hacer una interfaz. 00:06:19
Así desbloqueo la herencia y mi clase puede heredar de otra clase si quiere o necesita y implementar mis métodos gracias a la implementación de la clase abstracta, de la interfaz. 00:06:24
Hay una pregunta, si y no, porque si tú defines que está la variable número de lados, que nosotros pusimos, entonces no es una interfaz, porque has concretizado algo. 00:06:38
y si tú le pones en 00:07:00
figura geométrica un 00:07:02
descripción que 00:07:03
implementa con 00:07:06
soy una figura de enhelados 00:07:08
¿vale? pues entonces 00:07:10
ya no es un interfaz 00:07:12
si tú lo consideras 00:07:14
como le quitas a ese ahí 00:07:16
y le pones solo calcular área, calcular perímetro 00:07:18
calcular no sé qué 00:07:20
que vale para todas las cosas, pues sí, podría ser 00:07:22
un interfaz 00:07:24
¿sí? 00:07:25
entonces 00:07:26
Entonces, tres niveles de abstracción, entre comillas 00:07:27
La clase es todo concreto 00:07:32
La clase abstrata, algo concreto y algo abstrato 00:07:34
La interfaz, todo abstrato 00:07:37
En Java se declaran utilizando la palabra interface en lugar de class 00:07:39
O sea, en vez de public class hago public interface 00:07:47
Para crear una clase que escriba código para los métodos 00:07:49
indefinidos aún, porque son abstractos 00:07:53
de una interfaz, pues lo que hago 00:07:57
es usar la palabra reservada implements 00:08:00
en vez que extends 00:08:02
entonces public class mi clase 00:08:04
implements mi interfaz 00:08:09
se pueden declarar referencias a objetos 00:08:13
cuyos tipo sea una interfaz en lugar de una clase 00:08:20
o sea, como antes yo podía hacer 00:08:23
una variable de tipo clase abstracta, 00:08:26
ahora puedo hacer una variable 00:08:29
que como tipo tenga una interfaz. 00:08:31
¿Sí? 00:08:35
Estoy hablando de la referencia, de la variable. 00:08:36
No puedo hacer un new de una interfaz. 00:08:38
¿Por qué no puedo hacer un new de una interfaz? 00:08:41
Porque todos sus métodos son abstractos 00:08:44
y mientras que no haya una concretización de esos, 00:08:45
no puedo hacerlo. 00:08:48
Pero sí puedo hacer mi interfaz x 00:08:49
es igual a new 00:08:52
mi clase, asumiendo 00:08:54
que mi clase implements 00:08:57
mi interfaz 00:08:59
¿si? 00:09:00
entonces, la interfaz 00:09:03
se vuelve un comodín 00:09:04
para decir, oye mira, cualquier 00:09:06
objeto de tipo mi interfaz 00:09:08
puede ser referenciado 00:09:10
o sea, puede hacer una referencia 00:09:12
de tipo mi interfaz a cualquier 00:09:14
objeto que implemente esta 00:09:16
interfaz, entonces sé que allí 00:09:18
dentro tendrá los métodos abstractos 00:09:20
que yo he definido en mi interfaz. Si mi interfaz definía los métodos dibuja y escribe, pues 00:09:22
cualquier objeto de tipo interfaz tendrá dibuja y escribe. Si no, no habría implementado 00:09:30
la interfaz. Esta forma de proceder tiene sentido para definir un objeto en función 00:09:36
del tipo más genérico para utilizar mecanismos como el polimorfismo. Aquí también estamos 00:09:43
utilizando polimorfismo, de ello te declaro que hay el método calcularia como interfaz 00:09:48
y luego todos los que implementan la interfaz que se llama se puede calcular área, pues tendrán que tener el método calcular área. 00:09:53
Su principal función es establecer y estabilizar las interfaces como prototipo de métodos de una clase para poder desarrollar y así coordinar varios equipos de trabajo. 00:10:04
¿Qué quiere decir esto? 00:10:15
Yo puedo, por un lado, crear una interfaz y decir, oye, mira, 00:10:17
estas clases, la clase que implementa esta interfaz tendrán que tener estos métodos. 00:10:23
Una vez que he definido esta interfaz, yo puedo dividir el trabajo entre 00:10:29
personas que implementarán la clase A que implementa esta interfaz. 00:10:34
Entonces, ¿dónde se dará el cuerpo de estos métodos? 00:10:40
Pero al mismo tiempo, yo puedo decir a otro grupo de trabajo, oye, mira, tú tendrás en un futuro una clase que implementa esta interfaz. Ahora, tú puedes ya desarrollar utilizando objetos de tipo esta interfaz y usar sus métodos como si ya estuvieran implementados. 00:10:44
Luego en un futuro se implementarán con el trabajo que ha hecho el otro equipo 00:11:05
Pero ya tú puedes seguir trabajando 00:11:11
Asumiendo que el método calcular área, por ejemplo 00:11:13
De la interfaz se pueden calcular áreas 00:11:17
Pues calculará el área, funcionará 00:11:19
Ahora tú lo puedes ya utilizar en tu código 00:11:22
Después hacemos un ejemplo para entender lo que estamos diciendo 00:11:26
Pero tú ya lo puedes utilizar 00:11:28
Luego cómo lo hará y qué funcionará lo veremos más adelante 00:11:30
Cuando ya estará lista el otra clase. Y si tú necesitas sí o sí un objeto de la otra clase por algún lado, pues te puedes crear un objeto mock, un objeto falso, un objeto ficticio que usarás en tu programa por ahora, que da un resultado siempre fijo sin saber qué hace. 00:11:35
y cuando en un futuro ya estará listo el trabajo del otro equipo, pues lo integramos y funciona. 00:11:55
Ahora luego probamos a hacer un pequeño ejemplo sobre este tema para que entendáis qué quiero decir. 00:12:01
Veamos un poco. El equipo que debe utilizar... Bueno, esta es la explicación misma. 00:12:08
El equipo que debe utilizar objetos que implementan dicha interfaz, basta con que declaren en su código una referencia a dicha interfaz, 00:12:12
aunque no esté todavía compilada ninguna clase que la implemente. 00:12:20
Yo tengo una referencia de tipo esta interfaz, pero no tengo una implementación de esta interfaz. La tendré en un futuro. Y aquí en mi código yo puedo usar tranquilamente esta interfaz haciendo lo que me haga gana con esa interfaz. 00:12:25
los equipos que creen clases que implementan 00:12:37
esta interfaz están a su vez 00:12:41
desacoplado de los equipos 00:12:43
que la utilizan, esto es para que 00:12:45
me permita trabajar 00:12:47
en paralelo entre grupos 00:12:49
de trabajo 00:12:53
en términos técnicos es desacoplado 00:12:54
yo no dependo de ti y tú no dependes 00:12:57
de mí, en un futuro 00:12:59
podremos funcionar juntos 00:13:01
porque hemos definido esta interfaz 00:13:03
este punto de contacto, los métodos 00:13:05
que se pueden utilizar, están definidos aquí 00:13:07
y yo los utilizo 00:13:09
sin saber 00:13:10
qué harán adentro y al mismo tiempo 00:13:12
por otro lado 00:13:15
tú lo estás implementando 00:13:16
sin saber quién los utilizará 00:13:19
y cuándo lo utilizará 00:13:20
los equipos 00:13:24
que creen 00:13:27
este es el concepto 00:13:28
de mock, si en algún 00:13:31
momento, pero yo necesito 00:13:33
por alguna razón, necesito 00:13:35
una implementación, necesito hacer un new 00:13:37
para hacer algo 00:13:39
pues lo que puede hacer es crearme un objeto 00:13:41
falso, un objeto mock 00:13:43
¿vale? que es una clase donde 00:13:44
los métodos, los implementos, pero que hagan 00:13:47
nada, si es un método que tiene que calcular el área 00:13:49
y yo lo implemento con return a 3 00:13:50
cada vez que calcularé el área 00:13:53
pues me devolverá 3 00:13:54
pero lo puedo utilizar, puedo crear objetos de esos 00:13:56
pero claramente serán inútiles 00:13:59
¿sí? 00:14:01
ejemplo, ¿vale? 00:14:05
para que entendamos un poquito 00:14:06
esta, por ejemplo, existe 00:14:08
la interfaz comparable 00:14:10
la interfaz comparable 00:14:12
me transforma mi 00:14:14
objeto en un objeto 00:14:16
comparable 00:14:18
¿qué quiere decir? cuando yo 00:14:19
tengo un objeto, el objeto 00:14:22
gato 00:14:24
y quiero saber 00:14:25
y quiero implementar la interfaz comparable 00:14:28
entonces gato implements 00:14:31
comparable, la comparable 00:14:32
me dice que obligatoriamente 00:14:35
tengo que implementar el método 00:14:37
int compareTo 00:14:39
objeto, está este método que yo tengo que implementar. ¿Y qué me dice? Pues si yo 00:14:40
implemento este objeto, implemento este método, tengo que hacer que si mi objeto, el gato 00:14:48
dice, es más grande que el objeto pasado por aquí, pues yo te tengo que devolver un 00:14:55
número positivo. Si es más pequeño, te tengo que devolver un número negativo. Y si son 00:15:05
iguales, pues te tengo que devolver cero. O sea que este es un método general. Yo no 00:15:12
sé cómo se comparan dos gatos. Se podrían comparar por edad, se podrían comparar por 00:15:19
tamaño, se podrían comparar por, no lo sé, por color, qué sé yo. Pero yo estoy diciendo 00:15:24
quiero poder comparar gatos 00:15:31
para poder comparar gatos 00:15:33
yo lo que voy a hacer es 00:15:35
implementar la interfaz comparable 00:15:37
y la interfaz comparable me obliga 00:15:39
a implementar este método 00:15:42
a partir de ahora 00:15:43
¿vale? 00:15:46
yo, mis objetos 00:15:47
gato en este caso 00:15:49
pues son comparables entre ellos 00:15:51
los puedo ordenar 00:15:53
¿sí? 00:15:55
entonces, esto me permite 00:15:57
por otro lado, utilizar otra clase que pilla objetos, sean cual sean, pueden ser gatos, 00:15:59
pueden ser cocodrilos, me da igual, y los ordena de mayor a menor. ¿Qué tipo tendrán 00:16:09
estos objetos? Repito la pregunta. Por un lado tengo mi clase gato, que implementa, 00:16:16
Comparable, hemos dicho 00:16:33
Entonces, eso quiere decir que la clase gato 00:16:37
Por algún lado tendrá que implementar compare to 00:16:41
Y a partir de que ha implementado este método 00:16:46
Yo puedo comparar gatos 00:16:53
Puedo decir si este gato es más grande que esto 00:16:57
Si este gato es más pequeño que esto 00:16:59
Si este gato es igual de... 00:17:00
¿En base a qué? 00:17:03
En base a lo que yo sé de los gatos. Es un problema mío de yo estoy creando el objeto gato. Entonces, yo quiero poderlos comparar. Yo sé cuando un gato es mayor que otro gato o un gato es menor que otro gato. Lo defino aquí dentro. 00:17:04
Si es por edad, pues diré, si el gato Dís tiene más años que el gato que me has pasado aquí como objeto, 00:17:21
pues entonces devuelve, no lo sé, 30, que es un número positivo. 00:17:31
Si tiene la misma edad, devuelve 0. 00:17:37
Si el Dís tiene una edad menor que el gato que me has pasado aquí como parámetro, devuelve menos 30. 00:17:40
he hecho las especificaciones que me pide aquí 00:17:47
ahora, por otro lado 00:17:53
completamente sin saber que el gato 00:17:55
implementa el comparable, yo puedo hacer una clase 00:17:59
que lo que hace es ordenar objetos 00:18:02
entonces, si aquí tendré objetos 00:18:04
y lo que quiero decir es 00:18:08
ponme primero el menor, que por ejemplo es este aquí 00:18:11
luego el siguiente menor, luego el siguiente menor 00:18:13
¿Vale? Para poder hacer esto yo tengo que comparar los objetos entre ellos. Y cuidado, no sé cómo se comparan los objetos. Porque no sé si estos objetos serán gatos, serán cocodrilos, serán personas. ¿Vale? No lo sé. 00:18:15
yo quiero hacer una cosa tan genérica 00:18:36
que me dice, tú dame objetos 00:18:38
y yo te los ordeno 00:18:40
ahora, estos objetos 00:18:41
para que esto funcione 00:18:44
¿qué tipo tendrán que tener? 00:18:46
tú me dices, tipo gato 00:18:50
entonces me funcionaría solo como gato 00:18:51
con gatos 00:18:53
no me funcionaría con persona 00:18:54
¿qué tipo le doy a estos señores? 00:18:56
¿le doy object? 00:18:59
porque si yo hago perro 00:19:02
que no implementa comparable 00:19:04
no puedo comparar dos perros 00:19:06
entre ellos, entonces object 00:19:08
es demasiado genérico, ¿qué tipo le doy? 00:19:10
ya, pero el método 00:19:22
estará aquí 00:19:23
esto es lo que me permite 00:19:24
compararlo 00:19:27
solo que si yo aquí le digo gatos 00:19:28
o sea que estos son gatos, son 00:19:31
objetos de tipo gato, pues entonces 00:19:33
solo me funcionaría entre gatos 00:19:35
no quiero, quiero que sea más genérico 00:19:37
entonces le digo, le pongo object, así le puedo poner 00:19:39
lo que me da la gana, pero el problema 00:19:41
que vosotros, todos los objetos que habéis hecho hasta ahora, no tienen el método para compararlo. 00:19:43
Las personas, vosotros no las podéis comparar. 00:19:50
Los instrumentos musicales, vosotros no los podéis comparar. 00:19:54
No podéis decir si un instrumento musical es mayor o menor que otro. 00:19:57
Entonces, ¿cómo puedo estar seguro que estos objetos sean comparables? 00:20:03
Es decir, que el tipo que uso para este objeto será tipo comparable. Esto. Estoy usando como tipo la interfaz. Esto me garantiza que, sea lo que sea, implementará comparable. Y si implementa comparable, tengo un método para compararlo. 00:20:10
entonces son gatos, pues perfecto 00:20:37
entonces podría hacer compare tú con este 00:20:39
compare tú con este, compare tú con este 00:20:41
y ordenarlos 00:20:43
son barcos 00:20:44
pero los barcos implementan 00:20:47
compareable, por lo tanto lo puedo 00:20:49
usar aquí, pues quiere decir que tendré un método 00:20:51
para comprobar cuál de estos 00:20:53
barcos es mejor, cuál de estos barcos es mejor 00:20:55
cuál de estos barcos es mejor y ordenarlo 00:20:57
se entiende la potencia de esto 00:20:59
cualquier método 00:21:02
que tú tengas con parable lo podrás usar con este método de ordenación que he creado que es genérico 00:21:06
que no tendré que reescribir una vez para ordenar gato una vez para ordenar barco una vez para 00:21:13
ordenar string una vez para ordenar todos los objetos que tengan comparable son ordenables 00:21:19
entiende esta es la potencia de la interfaz yo me hago una interfaz luego hago programas que 00:21:25
se basan sobre la interfaz 00:21:34
y cualquier clase que implemente 00:21:36
esta interfaz puede usar 00:21:38
estos métodos 00:21:40
¿sí? ahora hacemos ejemplos 00:21:46
con comparable 00:21:48
¿sí? 00:21:48
nota, comparable es una clase que existe 00:21:51
que es importante 00:21:54
¿vale? y que cuando vosotros 00:21:56
implementáis comparable 00:21:58
hay una parte que te dice 00:22:00
que si son iguales 00:22:02
tiene que dar cero 00:22:03
¿sí? esta cosa de aquí 00:22:05
tiene que ser consistente con la implementación 00:22:08
del equals. ¿Os acordáis del método de Equals? 00:22:12
¿Vale? El método de Equals te da true si dos objetos son 00:22:16
cero. Y te da false, perdón, si dos objetos son iguales. 00:22:20
Y te da false si dos objetos no son iguales. ¿Vale? Entonces, si dos 00:22:24
objetos te dan equals true, te deberían 00:22:28
dar compare to cero. Y si te dan 00:22:32
un compare to que no es 0 00:22:37
no te deberían dar 00:22:39
equals true. Si tú has 00:22:41
hecho una implementación de equals en una implementación 00:22:44
de compare to que hacen estas cosas 00:22:46
que acabo de decir, pues los has implementado 00:22:48
mal. Porque estás 00:22:51
diciendo que dos objetos son iguales pero 00:22:52
este es mayor que esto. Entonces no son iguales. 00:22:54
No. 00:23:16
Si el método ya está implementado 00:23:17
pues ya está implementado. 00:23:19
O dicho de otra forma, si yo tengo 00:23:21
si yo tengo la clase 00:23:23
gato que implementa 00:23:25
ya comparable y luego 00:23:27
la extendo con la clase minino 00:23:29
la clase minino implementa 00:23:31
comparable 00:23:34
si yo le pongo implements comparable me dirá 00:23:34
pero normalmente 00:23:39
se tende a sobre escribirlo 00:23:43
con los datos propios 00:23:45
claro, clase padre 00:23:46
es instrumentos musicales 00:23:58
generales, entonces no los puedes 00:24:00
comparar entre ellos porque no sabes como se 00:24:02
comparen, pero luego 00:24:04
entre pianos sí sabes cómo 00:24:06
se comparan, entre guitarras sabes cómo se comparan 00:24:08
por lo tanto, guitarra extends 00:24:10
instrumentos 00:24:12
musicales, implements 00:24:14
comparable 00:24:16
de hecho 00:24:18
es más probable, cuando la clase 00:24:20
se abstracta de esta forma 00:24:22
es más probable que la clase 00:24:24
abstracta no pueda implementar comparable 00:24:26
porque no sabes cómo comparar 00:24:28
por ejemplo, en figura 00:24:29
tú puedes decir, mi comparación es 00:24:32
Dependiendo de los números de lados 00:24:33
Entonces ya la clase abstracta podría implementar 00:24:35
Reconpervo 00:24:38
Vale, entonces ejemplo de aquí 00:24:38
Yo tengo una interfaz animal 00:24:43
¿Vale? 00:24:46
La interfaz animal no puedo construir objetos de tipo animal 00:24:47
Pero sé que cuando eres un animal 00:24:50
Lo que puedes hacer es hablar 00:24:52
Porque me estáis definiendo aquí 00:24:54
Una public interface animal 00:24:56
Con void habla 00:24:58
¿Sí? Fijaos que aquí no hay abstract por ningún lado 00:24:59
Pero este es todo abstract 00:25:02
Porque cuando es interfaz, este de aquí es considerado abstracto 00:25:04
Y de hecho, está punto y coma 00:25:07
¿Sí? Vale 00:25:09
Entonces, luego tengo la public class perro que implementa animal 00:25:12
¿Vale? 00:25:16
Y entonces estoy forzado a sobreescribir habla 00:25:17
Entonces hace guau 00:25:20
Por otro lado está la clase gato que implementa animal 00:25:21
Y habla hace miau 00:25:24
¿Están de acuerdo con esto? 00:25:26
Vale, entonces 00:25:29
¿Cómo? 00:25:30
Dímelo tú, ¿por qué pone implements en vez de extends? 00:25:32
Porque se extenden clases 00:25:42
Se implementan interfaces 00:25:43
¿Sí? 00:25:45
Entonces, implements es el 00:25:47
Lo dice aquí 00:25:50
Aquí lo hemos dicho antes 00:25:51
No, me he pasado 00:25:53
Por algún lado aquí lo dice 00:25:55
¿Aquí? Sí, implements 00:25:56
Entonces, esto me está diciendo 00:26:00
Oye, cuidado, perro podría extender otra clase 00:26:04
No está ahora bloqueado 00:26:06
si está implementando animal por lo tanto puede extender otra cosa puede extender es 00:26:07
ser vivos si quiere vale y puede implementar todas las heredar una sola implementar cuántas 00:26:13
interfaces te da la gana 678 lo pondrías aquí implements animal coma no sé qué coma no sé 00:26:21
cuánto entonces el main dentro del main yo puedo crear una referencia de tipo animal fijaos animal 00:26:27
es una interfaz, ¿vale? Es como si estuviera 00:26:34
creando una interfaz, una 00:26:36
referencia a una clase abstracta 00:26:38
donde todos los métodos son abstractos 00:26:40
¿sí? Pero cuando voy 00:26:42
a hacer la new, no puedo hacer un new 00:26:44
animal, porque la interfaz no se 00:26:46
puede, porque no tendría 00:26:48
las cosas implementadas, entonces dentro de 00:26:50
animal pongo perro y dentro de animal pongo gato 00:26:52
¿vale? Y ahora puedo hacer 00:26:54
dog.habla y cat.habla 00:26:56
¿existe habla dentro de animal? 00:26:58
Sí, pero 00:27:00
por polimorfismo, cuando 00:27:02
hago dog.habla, estará 00:27:04
haciendo esto, y cuando 00:27:06
hago cat.habla, como es un 00:27:08
gato, hará esto. 00:27:10
¿Sí? La misma cosa que 00:27:14
hemos aprendido con las 00:27:16
clases abstractas. 00:27:19
¿Dudas? 00:27:21
Puedo crear una 00:27:22
array de animales 00:27:24
y luego 00:27:25
poner dentro 00:27:27
estos objetos de aquí, y luego 00:27:29
hacer un método que hablen todos, que lo que 00:27:32
hacen es recorrerme este 00:27:34
Array de animales y decirle 00:27:36
Habla 00:27:38
Fijaos que aquí estoy usando solo animales 00:27:38
Pero sé que 00:27:42
Cualquier 00:27:44
Clase que implemente animal 00:27:45
Puede ir aquí 00:27:48
Y si ahora me creo una clase 00:27:49
Pájaro 00:27:52
Que implementa animal 00:27:59
Y que cuando habla 00:28:01
Dice pío 00:28:03
Las puedo 00:28:04
Poner dentro de este array 00:28:07
Y hacerlo trabajar 00:28:09
Porque es un animal. Esto no cambiaría. 00:28:10
Aquí he creado un método que trabaja sobre animales. 00:28:15
Entonces, me da igual qué animales luego hay adentro. 00:28:19
Yo sé que si eres un animal, si eres de tipo animal porque hay la interfaz animal, 00:28:23
los objetos que andrán aquí dentro tendrán que implementar la clase animal. 00:28:29
Y si implementan la clase animal, tienen que tener el método habla. Y por lo tanto, que sea un gato, un perro, un pájaro o un cocodrilo, pues tendrá su función habla, y yo lo puedo llamar. 00:28:36
Entonces he creado un método muy abstracto que funciona para cualquier animal. A partir de ahora tú estás en tu sistema, puedes añadir los animales que te da la gana, y sin tocar esta clase aquí, yo los hago hablar. 00:28:53
¿Entiendes? ¿Dudas? Vale. 00:29:10
Ahora, hasta aquí todo claro. 00:29:18
Ahora, existe una forma, en mi experiencia relativamente poco utilizada, 00:29:20
para que una interfaz que tiene todos los métodos abstractos, 00:29:28
tenga algunos métodos implementados. 00:29:33
O sea, una clase normal implementa todos los métodos. 00:29:38
La clase abstracta es un pasito hacia el abstracto diciendo, implemento casi todo, pero dejo algunos métodos para implementar, ¿vale? 00:29:44
La interfaz es el opuesto, todos los métodos son abstractos, pero te da, para tener flexibilidad, la posibilidad de decir, sí, pero un método, ¿vale? 00:29:54
este método de aquí, que es abstracto, que no debería estar, pero te voy a dar una implementación por defecto. 00:30:07
O sea, te voy a dar un consejo, una generalidad, que si luego tú implementas esta interfaz y no quieres implementar esto, 00:30:16
pues es como se hace por defecto, ¿vale? Por ejemplo aquí, por defecto tengo un método corre, ¿vale? Dentro de la interfaz, que lo que hace es decir que el animal corre, no define nada de cómo corre, si corre veloz, corre lento, corre a cuatro patas, corre a dos patas, no lo sé, porque no sé qué animal es, 00:30:27
Pero en general un animal corre, ¿vale? Tendrá que tener corre. Y si tú cuando implementas la interfaz animal no me defines como corre, pues tendrás esta implementación por defecto, la implementación por default. 00:30:49
Y esto, en un cierto sentido, se solapa con las clases abstractas. Pero no os olvidéis, la clase abstracta es una clase y la interfaz es una interfaz. Y la clase abstracta hereda solo uno, o sea, se puede heredar solo uno, mientras la interfaz puede heredar desde donde le dé la gana. 00:31:05
Entonces, sostancialmente aquí hacen un poco lo mismo, pero por un lado lo estoy haciendo con interfaces y por otro lado con clases. Y por lo tanto, es como una forma de decir, oye, mira, se puede hacer, si lo necesitas una vez, lo puedes hacer, si no lo quieres utilizar, no lo utilices. 00:31:26
¿sí? 00:31:46
como solo usando clase 00:31:48
puede hacer métodos concretos 00:31:50
y abstractos, utilizando 00:31:52
interfaces puede hacer métodos abstractos 00:31:53
que es lo más común y lo más obvio 00:31:55
pero en algunos casos concretos 00:31:57
si me ocurre, pues puedo hacer 00:32:00
un método por defecto, una implementación 00:32:01
por defecto, esto es como decir 00:32:04
corre, lo tienes que implementar 00:32:05
pero si decides que no, esta será la implementación 00:32:07
que usas, yes 00:32:10
tiene que tenerlo todo abstracto 00:32:15
Pero es exactamente el concepto. 00:32:21
No, con todo el método que quieras. 00:32:25
Pero estamos en interfaces. 00:32:28
Es para no pillarse los dedos. 00:32:30
Imagínate que tú tienes una clase que ya hereda de otra 00:32:32
y ahora tiene que heredar de otra clase abstracta. 00:32:35
¿Lo puedes hacer? 00:32:38
No. 00:32:40
Entonces tendrías un problema. 00:32:41
Pero yo quiero heredar de algo que tenga algunas cosas abstractas 00:32:43
y algunas cosas concretas. 00:32:47
Y no puedo heredar de otra clase. 00:32:49
Pues tengo esta interfaz con los métodos por defecto 00:32:51
Ya está, he encontrado una solución 00:32:53
Tengo que poner, ah, sí 00:32:55
Esto estoy definiendo un método 00:32:58
Por defecto 00:33:01
Una implementación por defecto de corre 00:33:02
Entonces todos los animales 00:33:04
Tendrán corre 00:33:06
Con su implementación por defecto 00:33:07
A menos que tú en emperro 00:33:10
O en gato, por ejemplo 00:33:12
Sobrescribas 00:33:15
Corre 00:33:16
Entonces en este caso se utilizaría la tuya 00:33:17
Porque la soy escrita por polimorfismo, usaría esta. 00:33:21
Pero perro que implementa animal, entonces necesita que haya habla y corre. 00:33:25
Háblalo tiene que implementar sí o sí, porque es abstracto y si no daría error. 00:33:30
Corre decidido no implementarlo y por lo tanto uso la implementación por defecto. 00:33:35
Es muy parecido a lo que es la clase abstracta. 00:33:40
Pero no estamos hablando de clases, aquí estamos en el mundo de las interfaces. 00:33:42
Principalmente. 00:34:00
es un contrato 00:34:00
oye mira 00:34:05
haz lo que te da la gana 00:34:06
pero yo te digo que tu objeto 00:34:08
tiene que hacer estas cosas 00:34:11
y te puedo decir 00:34:13
tiene que hablar, correr, comer 00:34:14
y saltar 00:34:17
pues tú cuando implementes mi interfaz 00:34:18
esto lo tiene que hacer, es un contrato 00:34:20
si no, no funciona 00:34:22
pero te puedo decir 00:34:23
oye mira, tiene que hablar, correr 00:34:25
y saltar 00:34:27
pero correr te voy a dar yo una implementación por defecto que si tú no quieres implementarla 00:34:29
es así pero si tiene sentido que en tu propio animal pues haga una cosa un poquito distinta 00:34:39
pues entonces modifica me la tú lo puedes hacer pero si no lo haces ya lo tienes como un contrato 00:34:46
pero opcional vale las que son así sin por defecto son vinculantes obligatorias esa la 00:34:54
tiene que hacer la que te dado ya yo una vía de salida es opcional la puedes sobreescribir 1 00:35:04
de acuerdo mal y por eso ahora la pregunta obvia es si vale muy bien muy bonita la casa 00:35:13
abstracta, muy bonita las interfaces, pero ¿qué diferencia hay cuando uso 00:35:22
una clase abstracta cuando uso una interfaz? Entonces aquí 00:35:26
tenemos una comparativa de cosas entre 00:35:30
clase abstracta e interfaz, que a lo mejor no son tan 00:35:34
obvias al principio porque parecen mucho la misma cosa, pero 00:35:38
la primera en absoluto es esta cosa de que yo puedo heredar solo de una clase 00:35:42
pero puedo implementar cuantas interfaces me da la gana y por lo tanto ya 00:35:46
Ya es suficiente como distinción para que existan las dos cosas, ¿vale? 00:35:50
Pero vamos a ver otras cosillas. 00:35:56
Si diferencian en propósito, ¿vale? 00:35:59
Una clase abstracta se utiliza para proporcionar una estructura básica para una jerarquía de clases, 00:36:03
mientras que una interfaz se utiliza para definir un contrato que debe cumplirse por una clase que implementa la interfaz. 00:36:11
O sea, cuando yo hago una clase abstracta y implemento esa clase abstracta, la estoy metiendo en mi jerarquía de herencia. 00:36:17
Es un anillo de mi jerarquía de herencia. 00:36:28
La interfaz no tiene nada que ver con mi herencia. 00:36:31
¿En qué sentido? 00:36:37
Yo puedo tener aquí mis instrumentos musicales y cosas por el estilo y puedo hacer que algunos de estos instrumentos musicales sean comparables. 00:36:38
Aquellos que quiero que sean comparables, implementarán la interfaz comparable. 00:36:47
Los que no tiene sentido que sean comparables, no la implementarán. 00:36:51
Pero eso es fuera de la estructura. 00:36:55
La estructura comparable no entra dentro de la jerarquía de herencia. 00:36:58
Es fuera, es otra cosa. 00:37:05
Entonces, la herencia me define la estructura de mis elementos, 00:37:08
mis entidades dentro de mi programa. 00:37:14
Entonces tengo persona, de persona heredada empleado, empleado tiene gerente, y de persona también alumno, y de empleado también profesor, qué sé yo. Y tengo mi estructura. Y luego, aparte, tendré mis, algunas de estas tendrán algunas interfaces, algunas de estas no, pero no son dentro de esta estructura jerárquica. 00:37:16
¿Sí? Cosa separada. 00:37:39
Implementación de métodos. 00:37:43
Una clase abstracta puede proporcionar una implementación para alguno de sus métodos, 00:37:45
mientras que la clase que la hereda anda debe implementar los métodos restantes. 00:37:49
Por otro lado, en una interfaz los métodos son solo declaraciones y no tienen una implementación, 00:37:54
a menos que no sean métodos default. 00:37:59
Esto es un poco tirar por los pelos. 00:38:00
Pero en general, una clase abstracta es una mezcla de abstracto y concreto, 00:38:03
una interfaz debería tender 00:38:09
al más abstracto posible 00:38:11
herencia 00:38:13
una clase puede extender 00:38:17
solo una clase abstracta mientras puedes hacer 00:38:20
múltiples interfaces, esto es lo que 00:38:22
hemos dicho al principio que es una de las cosas 00:38:24
más importantes, puedo 00:38:26
implementar cuantas interfaces quiero 00:38:28
extender una sola clase 00:38:29
y luego variables, esta es una cosa que no os he dicho 00:38:31
pero está por allí, dentro de una clase 00:38:34
abstracta yo puedo poner 00:38:36
variables 00:38:38
variables estáticas y no estáticas. 00:38:40
O sea, yo podía hacer dentro de figura número lados, 00:38:43
y luego número lados pertenece al objeto, 00:38:47
y cuando creo cuadrado, él tiene el campo número lados propio de ese objeto, 00:38:49
porque es un atributo del objeto, no de la clase. 00:38:56
Es no estático, no es estático. 00:38:59
¿Sí? 00:39:02
Sin embargo, en una interfaz no puedo poner variables no estáticas. 00:39:02
En una interfaz estoy forzado a poner o variables estáticas o finales, o sea, constantes. 00:39:11
En una interfaz no puede tener una variable del objeto. 00:39:19
Esto es una diferencia bastante importante. 00:39:25
si yo cuando creo, estoy pensando así 00:39:27
en hacer algo abstracto, que tenga métodos abstractos 00:39:30
y necesito ponerle un valor 00:39:32
a este objeto 00:39:35
que esté allí y que luego hereden 00:39:36
todos sus objetos, no puedo utilizar 00:39:38
una interfaz, tengo que utilizar una clase abstracta 00:39:40
y luego están cosas 00:39:44
malvadas 00:39:49
y muy muy muy complejas 00:39:51
¿Cómo son las interfaces funcionales? 00:39:54
Interfaz funcional es un monstruo de este tipo 00:40:00
Que me dice que hay ejecutar 00:40:02
Que hay una interfaz operación que tiene el método ejecutar 00:40:07
Y yo lo que hago es que cuando hago una operación como por ejemplo suma 00:40:11
Le paso aquí la definición de este ejecutar 00:40:16
Y entonces, luego, cuando uso suma, hago suma, ¿dónde está? 00:40:22
Suma punto ejecutar tres cinco, ejecutar tres cinco, aquí le he pasado la definición de qué tiene que hacer. 00:40:29
Es decir, que no le estoy pasando un valor, me lo estoy pasando una función. 00:40:39
Y esto gracias a mi amigo lambda cálculo. 00:40:46
No. 00:40:55
Es como si tú tuvieras un math.hazalgo 00:40:59
y antes de utilizar el math.hazalgo 00:41:01
le definas qué tiene que hacer. 00:41:04
Le dices, recibirás dos parámetros, a y b, 00:41:07
y lo que tienes que devolver, 00:41:11
y aquí te haces tú el cálculo para calcular la potencia. 00:41:12
Entonces te calcula la potencia cuando dices haz algo. 00:41:16
Si en vez le defines la suma, 00:41:18
cuando dice haz algo, pues te hará la suma. 00:41:20
Si le pasas como definición. 00:41:22
la función que tú quieras 00:41:25
él en automático hará esa cosa 00:41:28
pero son cosas 00:41:30
complejas 00:41:32
existen 00:41:33
y si usáis chat GPT 00:41:35
lo veis esta cosa aquí, la flecha 00:41:37
cuando veis la flecha, tremblad 00:41:40
¿os acordáis al principio de clase 00:41:42
de este curso 00:41:48
cuando todavía erais pequeños 00:41:49
y yo os hablaba 00:41:51
de distintos 00:41:54
tipos de lenguajes 00:41:56
yo os decía que hay los lenguajes 00:41:58
imperativos y nosotros vamos a trabajar 00:41:59
con lenguajes imperativos y luego hay los 00:42:02
lenguajes funcionales 00:42:04
y los lenguajes lógicos 00:42:06
¿sí? 00:42:08
como Prolog, Lisp 00:42:10
pues esto 00:42:11
intento de hacer en Java 00:42:17
que es imperativo 00:42:20
cosas de lenguaje 00:42:21
funcional 00:42:24
Como los lenguajes funcionales algún tipo de problema lo solucionan mucho más rápidamente 00:42:24
Mucho más eficientemente que la programación imperativa 00:42:34
Pues lo que ha hecho Java en las últimas versiones 00:42:37
Es introducir una posibilidad de usar un pseudo lenguaje funcional 00:42:41
Dentro del marco del lenguaje imperativo que es Java 00:42:47
En lenguaje funcional se basa sobre el concepto que tú puedes pasar como parámetros funciones 00:42:51
Porque esto de aquí son directivas al precompilador 00:42:58
Para que el precompilador sabe que esta no es una interfaz normal 00:43:16
Es una interfaz que da dolor de cabeza a los estudiantes 00:43:20
Y esto es todo lo que veremos de la interfaz funcional 00:43:24
Claramente caerá en el examen porque somos malvados 00:43:31
dudas 00:43:34
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:
16
Fecha:
21 de enero de 2025 - 12:39
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
43′ 41″
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:
106.55 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid