Saltar navegación

Clase 22-04-2024 - 1 - 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 22 de abril de 2024 por Raquel G.

10 visualizaciones

Descargar la transcripción

Vale, pues nuestra arquitectura de clases 00:00:00
Aplicación que tiene una interfaz gráfica 00:00:03
Repito, la interfaz gráfica lo único que aporta es 00:00:07
Que mi forma de introducir datos 00:00:10
Y mi manera de ver los resultados 00:00:12
Va a ser distinta al escáner y al System Outprint LN 00:00:15
Todo lo demás es igual 00:00:20
Si nosotros tenemos que trabajar con alumnos 00:00:22
Con profesores, con clientes, con facturas 00:00:25
Esas clases seguirán estando y seguiremos teniendo nuestras colecciones de facturas de clientes que tendremos que recorrer, con las que tendremos que hacer cosas, con las que tendremos que hacer sumas. Todo eso seguirá estando. Lo único que cambiará es la forma en la que nosotros introduzcamos los datos desde fuera y la manera en la que veremos los resultados. Pues la suma del total de facturas, la nota de un alumno, es lo único que va a cambiar. 00:00:28
¿Vale? Es lo único que va a cambiar 00:00:52
Bueno, pues entonces 00:00:54
Una aplicación que tiene una interfaz gráfica 00:00:56
Que hemos decidido que tiene una interfaz gráfica 00:00:59
Tendrá entonces 00:01:01
Como elemento para 00:01:02
Recoger datos y mostrar resultados 00:01:04
Un JFrame 00:01:07
Que es lo que vimos el otro día 00:01:08
Pero un JFrame básico 00:01:10
Normal y corriente, no hombre, no 00:01:13
Uno personalizado 00:01:14
Uno personalizado 00:01:16
Al aspecto que nosotros queremos 00:01:19
Entonces, personalizar un JFrame básico es hacer una clase nuestra que hereda de él, ¿vale? Que hereda de él. Bueno, pues entonces, la arquitectura, la arquitectura básica, una de ellas, vamos, para mostrar una aplicación en swing es, me voy a hacer mi JFrame personalizado, es decir, heredero de JFrame. 00:01:21
Y ahora, este JFrame cuando se construye, este JFrame se construye cuando arranca la aplicación, obviamente, en mi main, aquí se construye, cuando arranca la aplicación en el main se construye aquí, ¿no? Aquí, pues aquí es lo que estoy haciendo, construirlo cuando arranca la aplicación, luego además le doy un tamaño, el que yo quiera, y lo hago visible para que se vea, ¿vale? 00:01:44
Y podría hacer más cosas con él porque V, por ser JFrame, tiene un montón de métodos para hacer cosas que uno se puede poner a investigar 00:02:10
y trabajar con Swim al nivel de profundidad que le dé la gana. 00:02:19
Vale, pues entonces, pero se construye aquí en el constructor. 00:02:24
Por eso decíamos, vale, pues en el constructor, que es este, en el constructor, es donde yo tengo que poner todo el rollo, 00:02:28
Todo el rollo patatero de 00:02:34
¿Qué componentes quiero? 00:02:36
Añadírselos a algún panel del frame 00:02:40
¿Vale? 00:02:42
Porque recordad que los componentes 00:02:44
Que son los que reciben y muestran datos 00:02:46
Botones, áreas de texto 00:02:48
Los componentes 00:02:50
No van directamente al frame 00:02:52
El frame es como el marco raíz 00:02:55
Al frame van paneles 00:02:57
Y los paneles ya llevan los componentes 00:02:59
¿Vale? 00:03:01
Pues entonces, nosotros decidimos qué componentes me interesan en este ejemplo 00:03:02
Queríamos una etiqueta 00:03:07
Simplemente para mostrar el texto e introduzca el año 00:03:10
Un área de texto 00:03:13
Para poder introducir yo el dato 00:03:15
Una etiqueta para mostrar el resultado 00:03:19
Y un botoncito para decir, calcula a ver si es bisiesto 00:03:21
Una vez decidido lo añadíamos a un panel 00:03:25
¿A cuál? Podría hacerle un panel si me daba la gana 00:03:27
un jPanel 00:03:30
pero podemos trabajar con el que ya me da el frame 00:03:31
que me da uno por defecto 00:03:36
que yo lo puedo sacar con este método 00:03:37
con este método 00:03:39
podíamos sacar el panel por defecto 00:03:41
del frame 00:03:43
y a ese panel por defecto le añadimos los componentes 00:03:45
si añadimos los componentes y más 00:03:48
¿qué ocurría? que se ponían unos 00:03:51
encima de otros, no íbamos a ver ninguno 00:03:53
nada más que el último 00:03:55
entonces a ese panel hay que darle 00:03:56
un gestor de ubicación 00:03:59
que él use 00:04:01
para decidir 00:04:04
donde van los componentes, gestores de ubicaciones 00:04:05
miles, para hacer gestión de ubicación 00:04:07
hay mil clases, mil rollos, mil historias 00:04:09
que uno no pasa nada, se coge un libro 00:04:11
se lee las 500 primeras páginas 00:04:13
y con esas 500 primeras páginas, pues ya conoce 00:04:15
todos los gestores de ubicación 00:04:17
como nosotros no nos vamos a meter por ese camino 00:04:18
pues por ejemplo 00:04:21
vamos a fijar un gestor 00:04:23
de ubicación que era este 00:04:25
el de tipo flow layout, este 00:04:27
lo instancio y le digo al panel 00:04:29
oye, que este es tu jefe, este es tu gestor 00:04:32
de ubicación y a partir 00:04:34
de ahí ya los componentes 00:04:36
se van colocando como el jefe 00:04:38
flow layout manda 00:04:40
y el jefe flow layout como manda 00:04:41
pues manda uno detrás de otro 00:04:43
¿vale? 00:04:45
entonces en cuanto a la construcción del aspecto 00:04:48
de la vista, eso es lo más sencillo 00:04:50
ahora la vista se tiene que comportar 00:04:52
cuando yo haga algo 00:04:54
tienen que pasar cosas 00:04:56
entonces hay que decidir 00:04:57
qué tipo de acciones 00:04:59
sobre la interfaz, qué tipo de acciones 00:05:01
me interesan a mí 00:05:04
capturar, qué tipo de acciones 00:05:05
en nuestra aplicación 00:05:07
la única acción que nos 00:05:09
interesaba 00:05:12
capturar 00:05:16
era la de darle al botón 00:05:17
era la única acción que nos interesaba calcular 00:05:22
luego entonces, la arquitectura 00:05:24
¿cuál era? pues la arquitectura 00:05:26
era, para capturar 00:05:28
un evento 00:05:30
para capturar un evento y darle al botón es un evento 00:05:31
estirar una ventana es un evento 00:05:34
que el ratón navegue es otro evento 00:05:36
pues para capturar un evento 00:05:40
tenemos que hacer una clase 00:05:43
que sea capaz de permanecer a la escucha de ese evento 00:05:45
y dentro de esa clase 00:05:49
metemos el código de respuesta al evento 00:05:52
entonces una clase que sea capaz de permanecer 00:05:54
la escucha de un evento no es una clase 00:05:58
cualquiera, tiene que ser una clase 00:06:00
con ese comportamiento 00:06:02
comportamiento, ser capaz de escuchar 00:06:03
a ver si pasa esto 00:06:06
ser capaz de estar atento, eso no es una 00:06:08
clase cualquiera que se pueda programar 00:06:10
así como así, porque implica programar 00:06:12
muchas cosas raras, implica programar 00:06:14
estar yo pendiente del ratón, ¿de cómo programamos eso? 00:06:16
no sabemos programar eso 00:06:19
pero afortunadamente hay una 00:06:20
interfaz ya hecha que es Action Listener 00:06:22
que tiene todo eso hecho 00:06:25
estupendo, me hago yo una clase que implemente esa interfaz 00:06:26
¿vale? que es lo que hicimos aquí 00:06:30
me hago yo una clase que implemente esa interfaz 00:06:39
magnífico, ya tengo una clase que es capaz de estar pendiente 00:06:42
de escuchar los eventos que ocurran sobre la interfaz 00:06:46
bueno, y ahora ya, dentro de esa clase 00:06:50
la parte de programar, ser capaz de estar pendiente, no tengo que hacerla 00:06:54
esa ya la coge de lo que esté por defecto 00:06:58
hecho en Action Listener, ya lo coge de ahí 00:07:01
yo solo tengo que añadir 00:07:02
el que, solo tenemos que añadir 00:07:04
el código de respuesta 00:07:06
a el evento 00:07:08
escuchar el evento ya lo hace ella sola 00:07:09
por ser Action Listener, ya lo hace sola, estará ahí pendiente 00:07:12
solo tenemos que ponerle 00:07:15
y cómo vas a responder 00:07:16
cuando ese evento ocurra, cómo vas a responder 00:07:18
porque cada aplicación 00:07:20
querrá responder de su manera 00:07:22
bueno, pues ese cómo vas a responder 00:07:24
esa respuesta lo metíamos en este método que había que sobreescribir obligatoriamente 00:07:27
este método. Entonces en nuestro caso nuestra respuesta era 00:07:31
coger el año que habíamos metido, si es bisiesto 00:07:34
poner el texto en la etiqueta y si no lo es poner este otro texto 00:07:38
en la etiqueta. Entonces para hacer el código de 00:07:42
respuesta necesitábamos el text fill 00:07:47
de la ventana, esta, este de aquí y también 00:07:50
necesitábamos 00:07:59
la etiqueta 00:08:00
esto de aquí 00:08:02
esta, como eran variables 00:08:04
locales al main teníamos un problema 00:08:09
pero nosotros 00:08:10
sabemos resolver eso pasando 00:08:13
por parámetro lo que un método necesite 00:08:15
¿vale? 00:08:17
entonces esta clase necesita 00:08:18
estas propiedades ¿vale? se las paso 00:08:21
al constructor por parámetro 00:08:23
se las paso por parámetro 00:08:24
aquí las tengo pasadas por parámetro 00:08:26
las uso para inicializar 00:08:28
variables de esta clase 00:08:30
ahora ya las que pase por parámetros 00:08:32
son estas, las mismas 00:08:34
porque las he inicializado 00:08:36
y ya está, y ya las tengo 00:08:38
y ya puedo trabajar con ellas, etc. 00:08:40
¿vale? 00:08:44
bueno, pues esto es lo que se supone 00:08:47
que tenía que estar claro a día de hoy 00:08:48
y cualquier 00:08:50
y la que os dije de hacer la suma 00:08:51
la resta era hacer esto mismo 00:08:54
pero cambiando el código de respuesta 00:08:55
nada más, y cambiando la vista 00:08:57
bueno, pues 00:08:59
el que no lo haya hecho que lo haga 00:09:01
porque es repetir esto de aquí 00:09:04
vale, pues a ver 00:09:05
seguimos avanzando un poco 00:09:09
bueno, pues en este caso 00:09:12
el código de respuesta 00:09:23
para mi 00:09:26
ah bueno, y se me ha olvidado decir 00:09:28
que esta clase, ActionListener 00:09:30
que es una clase que es capaz de escuchar 00:09:32
y además ofrece un código de respuesta 00:09:34
esta clase 00:09:37
el objeto 00:09:38
que instanciemos hay que decirle a qué componente 00:09:40
tiene que escuchar, claro, porque 00:09:42
si no, ¿qué evento 00:09:44
escuchamos? ¿El que haces en el ratón? ¿El que haces 00:09:46
en la área de texto? ¿Cuál? ¿A cuál escuchas? 00:09:48
Hay que decirle, oye tú, 00:09:50
objeto de esta clase 00:09:52
de quien tienes que estar pendiente es de este. 00:09:53
¿Vale? 00:09:56
Luego los objetos que se instancian de estas 00:09:58
clases, esos objetos 00:10:00
van a estar pendientes 00:10:02
de los componentes que nosotros le digamos. 00:10:04
pero hay que decirles de qué 00:10:06
componentes tiene que estar pendiente 00:10:09
si no decimos de qué 00:10:11
componentes tiene que estar pendiente, no va a estar pendiente de nadie 00:10:13
eso como lo hacíamos 00:10:15
pues decíamos, oye tú, botón 00:10:17
botón 00:10:19
como el componente, como esa clase 00:10:21
escuchadora, esa clase capturadora 00:10:23
tiene que estar pendiente del botón 00:10:25
porque el evento 00:10:27
que nos interesa es este 00:10:29
del botón 00:10:31
¿vale? 00:10:32
Como el objeto de la clase capturadora 00:10:34
Tiene que estar pendiente de este 00:10:38
Pues hay que decirle 00:10:40
Oye tú, botón 00:10:44
Va a estar pendiente de ti 00:10:46
Y eso se le decía mediante el método 00:10:49
AddActionListener 00:10:50
Va a estar pendiente de ti 00:10:52
Un objeto de esta clase 00:10:53
¿Vale? 00:10:55
Que instanciábamos aquí 00:10:56
Pasándole los datos que necesitábamos, etc. 00:10:57
Si esto no lo hacemos 00:11:00
Porque se nos olvida 00:11:02
Pues entonces ya podemos tener clase 00:11:03
Escuchadora 00:11:06
Podemos tener lo que nos dé la gana 00:11:07
Ahí he cerrado la esta 00:11:09
Pero no he 00:11:14
Ahí está la consola 00:11:15
Aquí 00:11:21
Ahí, vale 00:11:22
Vale, si a mí se me olvida esto 00:11:26
Ejecuto 00:11:31
Y ahora ya puedo darle al botón 00:11:32
Todo lo que me dé la gana 00:11:34
Que esto no hace nada 00:11:35
¿Por qué? Porque el botón no tiene asociado 00:11:36
un objeto de la clase 00:11:40
capturadora, no va a hacer nada 00:11:42
pero no lo tiene asociado 00:11:44
entonces tendríamos que 00:11:45
cuando hagamos esto 00:11:53
ahora ya si, este botón tiene asociado 00:11:55
un objeto de esa clase 00:11:58
luego ahora ya si, cuando yo 00:11:59
ejecute esto, pues ahora ya si 00:12:01
tendrá respuesta, vale 00:12:05
vale, bueno, alguna duda 00:12:07
no, verdad 00:12:17
bueno, pues todo es práctica 00:12:17
todo es práctica, volver a hacerlo 00:12:24
volver a hacer lo mismo de clase 00:12:26
y luego volver a hacerlo cambiando una cosita 00:12:29
que a mí se me ocurra, pues en lugar de que muestre 00:12:31
si es bisiesto, que muestre no sé qué 00:12:33
pues ahora que me muestre dos cosas 00:12:34
cambiando cositas, esa es la única manera 00:12:36
¿vale? práctica 00:12:38
vale, pues a ver 00:12:39
seguimos 00:12:42
aquí en este caso 00:12:43
el código de respuesta 00:12:46
al hecho de 00:12:49
pulsar al botón 00:12:51
pues bueno, era cortito 00:12:52
Era tocar solamente 00:12:53
Un text field para sacar el dato 00:12:56
Y tocar una etiqueta 00:12:59
Para poner ahí el resultado 00:13:01
Era un código cortito 00:13:03
Y solo necesitaba dos cosas 00:13:05
De la interfaz, dato y result 00:13:07
Solo necesitaba eso 00:13:08
Entonces el hecho de que no pudiera acceder 00:13:09
A ellas, el hecho de que no pudiera acceder 00:13:12
Lo hemos solucionado 00:13:14
Relativamente fácil diciendo 00:13:15
Bueno, pasaselo al constructor 00:13:18
Vale, pasaselo al constructor 00:13:19
inicializas esto, con esos datos 00:13:22
que has pasado ya puedes trabajar con ellos 00:13:25
pero hombre, es un poco engorroso 00:13:26
es un poco engorroso 00:13:29
porque si 00:13:31
el código de respuesta, el evento 00:13:32
tuviera que tocar un montón 00:13:35
de cosas de la interfaz, un montón 00:13:37
te podría ocurrir un montón 00:13:39
y poner un desplegable nuevo y añadir 00:13:40
un slider, vete a saber, igual el código de respuesta 00:13:43
de un botón es hacer un montón de cosas 00:13:45
y tiene que tocar un montón de 00:13:47
componentes de 00:13:49
la clase frame 00:13:51
pues esta solución es un rollo, porque tenemos que hacer 00:13:52
un constructor al que le pasemos ahí un montón 00:13:55
de cosas, no es la solución 00:13:57
habitual, que normalmente uno 00:13:59
uno utiliza 00:14:01
o uno ve, no es la solución habitual 00:14:03
¿vale? 00:14:04
entonces, ¿cuál es 00:14:07
la estructura más cómoda? 00:14:09
para que desde aquí 00:14:11
desde esta clase capturadora 00:14:13
podamos acceder 00:14:15
a todo lo que hay en el frame 00:14:17
¿Qué será nuestro problema, verdad? 00:14:18
Desde aquí acceder a todo lo que hay en el frame 00:14:22
¿Cuál es la forma más sencilla? 00:14:25
Bueno, pues la forma más sencilla es 00:14:28
incorporando una nueva estructura de clases 00:14:30
que se usa bastante por las ventajas que ahora podemos ver 00:14:35
que es la estructura de clases internas 00:14:39
¿Vale? 00:14:42
Clases internas, lo hemos imaginado hasta ahora, ¿verdad? 00:14:44
es una de las cosas que dice 00:14:46
cuando yo os digo una clase puede tener dentro 00:14:49
propiedades y métodos 00:14:51
y luego siempre a veces decía, bueno os miento un pelín 00:14:53
pero os tengo que mentir porque bueno 00:14:55
aparte de propiedades y métodos puede tener otra clase 00:14:57
¿vale? 00:14:59
y entonces el hecho de que 00:15:02
una clase pueda tener otra 00:15:03
dentro y ahora veremos lo que significa eso 00:15:05
nos facilita el diseño un montón 00:15:07
en un montón de situaciones 00:15:09
en una de ellas cuando 00:15:11
trabajamos con interfaces gráficas, es básico 00:15:13
Es básico, ¿vale? El poder hacer una clase dentro de otra 00:15:15
Vamos a 00:15:18
A entender un poco eso de las clases internas 00:15:19
Porque se usa muchísimo 00:15:25
En un montón de contextos 00:15:26
No solo en interfaces gráficas 00:15:28
Vamos a intentar entenderlo 00:15:30
Vale 00:15:34
A ver 00:15:37
Esto si alguien lo ve ya se habrá dado cuenta 00:15:39
De que se ve en espejo 00:15:44
Pero es que no sé cambiarlo 00:15:45
Y da igual, tampoco 00:15:48
Se entiende de igual 00:15:50
Quien quiera entenderlo va a entender igual 00:15:51
A ver 00:15:53
Pues venga, clases 00:16:07
Vamos a ver un poquito 00:16:11
Sin volvernos locos tampoco 00:16:12
Vale, pues a ver 00:16:14
Nosotros cuando hemos hecho una clase 00:16:41
Hasta ahora 00:16:43
Porque hemos tenido que definir una clase 00:16:44
Silencio 00:16:47
Una clase cliente, una clase factura 00:16:50
Una clase producto, porque nuestra aplicación 00:16:53
Trabajaba con eso 00:16:55
¿Vale? Pues 00:16:56
Imaginaos la clase A 00:16:59
¿Vale? Nuestra clase 00:17:04
¿Qué tenía? Tenía siempre 00:17:07
Propiedades que son 00:17:09
Las que van a caracterizar 00:17:11
Los objetos de esa clase 00:17:14
¿No? La clase factura 00:17:15
Pues puede tener, ¿Qué caracteriza una factura? 00:17:18
Su número, su concepto 00:17:20
¿Qué caracteriza a un cliente? 00:17:21
Su NIF, su nombre, bueno las propiedades 00:17:23
Lo de toda la vida, ¿no? 00:17:26
¿Sí? 00:17:28
lo que fuera, además una clase que tenía los métodos 00:17:30
que es los objetos de esa clase a qué código pueden invocar 00:17:37
normalmente ese código para hacer cosas con los datos de ese objeto 00:17:41
con parámetros que ese objeto recibe y hacer ahí funcionalidades 00:17:45
pues una factura puede llamar a métodos para hacer funcionalidades 00:17:49
relacionadas con calcular el importe con IVA, lo que sea 00:17:53
¿vale? entonces dentro de esos métodos el constructor, claro, etc. 00:17:56
eso era la otra cosa que tenía una clase 00:18:00
los métodos, es decir 00:18:05
¿qué funciona? ya el código de la aplicación 00:18:07
¿qué quiero yo 00:18:09
que haga esa aplicación? 00:18:11
esa aplicación lo que va a hacer lo metemos en métodos 00:18:12
que son los que hacen las cosas 00:18:15
pues obtener el resultado de no sé qué 00:18:16
calcular la edad 00:18:19
del cliente, lo que fuera, lo que yo quiero 00:18:21
que haga la aplicación va a ir en los métodos 00:18:23
correspondientes que trabajan con las propiedades 00:18:25
de la clase 00:18:27
para que cada objeto pueda 00:18:28
llamar al método, trabajando con sus propias propiedades 00:18:31
etcétera, lo de siempre, vale 00:18:33
bueno, pues una clase 00:18:35
además de todo esto 00:18:37
propiedades y métodos puede tener también 00:18:39
dentro, lo pongo ahí para que no me 00:18:41
cabe, una o más clases dentro 00:18:45
de ella, una o más clases 00:18:47
directamente tal cual, imaginaos que esta 00:18:48
tiene además dentro 00:18:51
otra clase 00:18:53
de nuevo con sus propiedades 00:18:54
y sus métodos, me da lo mismo 00:19:00
vale, pues a ver que implicaciones 00:19:02
tiene que una clase esté dentro de otra. 00:19:16
A ver, tenemos que verlo de alguna manera 00:19:20
como de esta clase se instanciarán objetos 00:19:22
y de esta otra se instanciarán otros 00:19:25
que son distintos, ¿vale? 00:19:27
No es que el hecho de que esta clase esté dentro 00:19:31
signifique que cuando yo hago un objeto de esta clase 00:19:35
va a tener dentro un objeto de esta otra, no. 00:19:40
Para que esta clase, cuando yo instancie un objeto de esta 00:19:43
tenga dentro un objeto de esta otra 00:19:46
pues tendría que hacer una propiedad así 00:19:48
¿no? 00:19:50
entonces si yo le hago una propiedad 00:19:53
así, esta clase 00:19:54
tiene dentro cuando yo la instancie 00:19:56
además de un entero A y un entero B 00:19:58
tiene dentro un objeto de esta otra 00:20:00
entonces cuando yo quiero que una clase 00:20:02
un objeto de una clase tenga dentro 00:20:04
un objeto de otra 00:20:06
esto no es un rollo de clases internas 00:20:07
yo lo he hecho siempre así 00:20:10
declaramos una propiedad 00:20:11
cuyo tipo sea esa otra clase y ya está 00:20:13
Y esa es la relación de composición de toda la vida. 00:20:16
Un cliente puede tener dentro un objeto pedido, por ejemplo. 00:20:19
Pues el cliente tiene su objeto pedido dentro. 00:20:26
Y cuando instancie un cliente, ese cliente tendrá dentro un objeto pedido 00:20:28
que también habrá que instanciar, lo que hemos trabajado siempre. 00:20:33
Bueno, pues lo de las clases internas no es eso. 00:20:36
No es que un objeto de la clase A tenga obligatoriamente un objeto de la clase B. 00:20:39
No, estos se instancian por separado. 00:20:43
El que sea una clase interna, la implicación que tiene es conceptual, en realidad, es conceptual y es, oye, yo puedo instanciar objetos de A cuando me den la gana y no necesito saber nada de la clase interna B, nada, puedo instanciar objetos de A cuando yo quiera, ¿vale? 00:20:46
Por ejemplo, puedo instanciar un objeto de la clase A como lo instancio de toda la vida. 00:21:05
Y ya está. 00:21:17
Y este objeto, a este objeto B no le interesa nada. 00:21:18
No le interesa para nada a este objeto. 00:21:23
Ni es consciente de su existencia, ni tiene ningún objeto B dentro, nada. 00:21:26
Vale, pero ¿ahora qué pasa con B cuando yo quiero instanciar objetos de la clase B? 00:21:32
Bueno, pues esto es un tema conceptual. 00:21:37
estos objetos se supone que son objetos 00:21:38
que por diseño de la aplicación 00:21:42
solo tiene sentido que existan 00:21:43
si existe un objeto de la clase A 00:21:45
previo, si existe un objeto 00:21:48
¿vale? por ejemplo 00:21:50
imaginaos que hay una aplicación en la que 00:21:52
hay 00:21:54
pues clientes 00:21:55
¿vale? y hay pedidos 00:22:04
y yo quiero 00:22:06
y solo tiene sentido que exista un pedido 00:22:08
si existe un cliente 00:22:10
Solo tiene sentido que está un pedido si existe un cliente. 00:22:12
Entonces, yo podré instanciar un pedido si existe un cliente previamente, 00:22:15
pero eso no significa que mi cliente tenga dentro ese pedido. 00:22:19
No lo tiene dentro. 00:22:22
Es otra forma de relacionarse. 00:22:24
Yo puedo instanciar mi cliente, no tiene ningún pedido dentro. 00:22:26
Y luego, para instanciar la clase pedido que está dentro, 00:22:29
para instanciarla, la tengo que instanciar si existe un cliente previamente. 00:22:32
Y entonces, la primera implicación que ocurre es 00:22:38
Que esta clase no se llama así. 00:22:40
Esta clase, su nombre, por ser clase interna esta, 00:22:43
su nombre es más complejo, es esta. 00:22:47
Esta clase no se llama así. 00:22:50
Y siguiente implicación. 00:22:55
Que para instanciarlo, hay que instanciarlo asociado 00:22:57
a un objeto de la clase A previo. 00:23:01
Algo así. 00:23:03
Ahora lo hacemos en... 00:23:05
¿Vale? 00:23:13
Entonces, esta es la idea. 00:23:17
Los objetos de la clase A se instancian y no... 00:23:18
Para ello, si es transparente, los objetos de la clase B, ¿vale? 00:23:21
Es completamente transparente. 00:23:26
No es como cuando tienes una clase cliente con un objeto pedido dentro. 00:23:27
Para instanciar el cliente tienes que instanciar el pedido. 00:23:31
Aquí no. 00:23:33
La clase es interna. 00:23:35
Tú puedes instanciar objetos de esta clase y para ella esta otra clase es que ni existe, ni le interesa, ni le importa. 00:23:37
Pero ahora sí, cuando instancias objetos de esta, por ser interna esta otra, primero el nombre cambia. 00:23:43
El nombre de la clase realmente cambia, se convierte en este. 00:23:50
Y segundo, solo puedes instanciarlos asociados a un objeto que ya exista 00:23:53
de la clase en la cual está contenido. 00:23:58
Entonces, no es que sea una arquitectura que sea imprescindible, 00:24:02
tú puedes hacer clase A y clase B por libre, pero te facilita dos cosas. 00:24:07
La primera es un tema de diseño. 00:24:12
Con esto fuerzas a que solo puedan existir ya por código directamente 00:24:15
objetos de este tipo, si previamente 00:24:19
existen de este, que eso puede tener 00:24:21
un sentido, ahora diseñar la aplicación 00:24:23
porque estás de nuevo protegiendo 00:24:24
que se instancien objetos cuando no hacen falta 00:24:26
o no es necesario, pueden crear problemas 00:24:29
esa es la primera ventaja 00:24:30
que ya pones una restricción 00:24:32
entonces poner restricciones a nivel de código 00:24:34
viene bien 00:24:37
porque te aseguras que luego en tiempo 00:24:38
de ejecución seguramente salgan 00:24:41
menos errores, cuantas más restricciones 00:24:43
pongas a nivel de código 00:24:45
menos errores 00:24:46
incontrolados vas a tener tiempo de ejecución 00:24:48
a cambios más rollos 00:24:51
que el código, porque tienes que satisfacer esas restricciones 00:24:53
es como el diseño de bases de datos 00:24:55
las bases aprobacionales son muy restrictivas 00:24:57
tienes que poner las claves primarias 00:24:59
claves ajenas para ti y para la tarea 00:25:01
pero una vez que has hecho un diseño bueno 00:25:03
cuando ya haces las consultas 00:25:05
en SQL 00:25:07
si satisfaces 00:25:07
esas restricciones 00:25:11
los resultados van a ser consistentes 00:25:12
si hiciéramos diseños de bases de datos abiertos 00:25:15
tú harías las consultas 00:25:19
que te dieran la gana 00:25:22
y luego los resultados podrían ser consistentes o no 00:25:23
porque como has podido hacer cualquier cosa 00:25:25
pues esta es la misma idea 00:25:27
la primera ventaja es esa 00:25:28
que a nivel de escritura de código 00:25:30
de compilación estás poniendo ya una restricción 00:25:33
y eso seguramente 00:25:35
te haga pensar mejor la aplicación 00:25:36
y evitar que luego en tiempo de ejecución 00:25:39
digas, uy que cosa mala me está haciendo esto 00:25:41
esa es la primera, y la segunda 00:25:43
que es la que nos interesa a nosotros 00:25:45
ahora, la segunda 00:25:46
es que desde la clase 00:25:49
interna hay visibilidad 00:25:51
directa tal cual 00:25:53
a las variables de la clase que la 00:25:55
contiene, es decir 00:25:57
desde estos métodos 00:25:59
si a mi me da 00:26:00
la gana desde estos métodos 00:26:03
imagínate que tengo aquí un método cualquiera 00:26:05
desde estos métodos 00:26:07
yo puedo acceder a las variables 00:26:09
de la clase, por supuesto, puedo acceder a estas 00:26:11
variables como siempre pero también puedo acceder a estas propiedades a 00:26:13
éstas es decir desde esta clase interna tengo visibilidad de las propiedades de 00:26:19
la clase externa o lo que es lo mismo desde este objeto 2 puedo modificar las 00:26:26
propiedades de éste esa es la ventaja 00:26:32
este objeto 2 se convierte en dependiente su existencia depende de que 00:26:37
exista este, 00:26:42
su existencia depende de que exista este, 00:26:44
no puede ser independiente, no puedo crearle por libre, 00:26:46
no puedo hacer un new v sin que 00:26:48
exista este, no puedo, 00:26:50
su existencia depende de que 00:26:52
exista este, y a cambio 00:26:54
a través de él y de sus 00:26:56
métodos podemos modificar propiedades 00:26:58
de aquel del que depende. 00:27:00
¿Vale? No es una herramienta más 00:27:02
para diseñar aplicaciones, que nos puede 00:27:04
venir muy bien y puede encajar perfectamente 00:27:06
en lo que queremos hacer. 00:27:08
y si encaja perfectamente lo que queremos hacer 00:27:09
aparte de que el programa 00:27:12
se va a entender mejor, seguramente nos 00:27:14
vayan a salir luego en ejecución menos cosas 00:27:16
raras que no sabemos por qué salen 00:27:18
porque el diseño se ha adaptado de partida 00:27:19
a lo que queremos 00:27:22
bueno, pues esto es un poquito por encima 00:27:23
el concepto de clase interna, que es útil 00:27:26
efectivamente para diseños 00:27:28
en los cuales esto nos interesa 00:27:30
pues justo a nosotros nos 00:27:31
interesa esto, porque teníamos dos 00:27:34
clases 00:27:36
esta tenéis que verla como la frame 00:27:36
y esta como la capturadora 00:27:40
en la acción listener 00:27:44
¿qué problema teníamos? que desde esta 00:27:45
queríamos poder acceder a las propiedades de esta 00:27:47
y no podíamos, teníamos que pasárselo por parámetro 00:27:50
al constructor, lo cual es un rollo 00:27:54
sobre todo si tengo que pasar mucho 00:27:55
anda, pues meto esta dentro de la otra 00:27:57
y ya he solucionado mi problema 00:28:00
que es acceder 00:28:01
desde la capturadora, que es esta 00:28:03
desde el Action Listener a todas las del frame que son estas. 00:28:07
He solucionado de golpe ese problema. 00:28:11
La siguiente pregunta sería, hombre, ¿pero tiene sentido 00:28:13
que esta realmente depende de su existencia de la otra 00:28:16
o es independiente? 00:28:20
Hombre, claro que depende. 00:28:21
¿Qué sentido tiene que haya una capturadora de componentes 00:28:23
de un frame si el frame no existe? 00:28:25
No tiene ningún sentido. 00:28:28
Luego se adapta perfectamente. 00:28:29
La existencia de esta está condicionada, 00:28:31
solo me interesa a mí si hay un frame. 00:28:34
Si no hay un frame, ¿a quién quiero yo escuchar? 00:28:36
No quiero yo escuchar a nadie 00:28:38
Luego se adapta a la perfección 00:28:39
Lo de las clases internas 00:28:42
Porque la capturadora 00:28:43
Su existencia 00:28:46
Solo tiene sentido si existe un frame 00:28:47
Y al meterla adentro 00:28:50
Tengo acceso automático 00:28:52
A todas las propiedades 00:28:53
¿Vale? 00:28:56
Pues 00:29:00
¿Cómo sería entonces? 00:29:01
Vale, pues para no 00:29:03
Romper esta 00:29:51
Me voy a hacer otro paquete 00:29:53
Vista 2 00:29:57
Y en ese otro paquete 00:29:58
Vista 2 00:29:59
Pongo este frame 00:29:59
Pero con la captura dentro 00:30:00
Etcétera 00:30:01
Vale, pues voy a copiar 00:30:02
La ventana visiesto 00:30:15
Que tenía 00:30:16
La voy a copiar 00:30:17
Esa misma 00:30:19
En vista 2 00:30:19
Vale, pues esta es 00:30:20
Le voy a quitar 00:30:30
Todo esto verde 00:30:31
Que está en la otra 00:30:32
Ya escrito 00:30:33
¿Vale? Para que se vea mejor 00:30:35
Entonces en el constructor 00:30:40
Pongo el gestor de ubicación 00:30:41
Todos estos comentarios están en la otra 00:30:44
Así que da igual, asocio el gestor al panel 00:30:46
Añado los componentes al panel 00:30:48
¿Vale? 00:30:56
Y ahora esto 00:31:03
Lo vamos a quitar 00:31:05
¿Vale? 00:31:08
Entonces he añadido los componentes 00:31:13
Pero mi 00:31:14
Botón todavía no tiene añadida 00:31:16
Ninguna clase, ningún objeto de ninguna clase capturadora 00:31:18
Vale, ¿por dónde vamos a poner esa clase? 00:31:21
¿Vale? 00:31:24
Vamos a ponerla aquí dentro 00:31:25
¿Vale? Vamos a ponerla aquí dentro 00:31:27
Esa clase, entonces voy a copiar y pegar 00:31:31
Toda esta clase enterita 00:31:32
Aquí 00:31:38
La clase 00:31:41
La voy a copiar 00:31:44
Aquí dentro, ¿vale? 00:31:54
Entonces como veis no me da ningún problema 00:31:55
Es una clase interna, me ha dejado ponerla dentro 00:31:57
Sin errores y sin nada 00:32:00
¿Vale? Entonces voy a quitarle 00:32:01
Esto 00:32:04
Que es lo que quería ahorrarme 00:32:04
Haciéndolo como clase interna, el tener que pasárselo 00:32:07
Por constructor, o sea el constructor 00:32:09
Enterito, fuera 00:32:11
Solo quiero ActionPerformance, este 00:32:12
Solo quiero este 00:32:15
¿Vale? 00:32:17
Entonces, ahora 00:32:20
Esta clase interna 00:32:21
De aquí, puede acceder 00:32:23
A todas las propiedades 00:32:26
A todas de VentanaVisiesto 00:32:27
¿Vale? A todas 00:32:29
entonces, ¿cuál es la solución 00:32:31
aquí, la estructura aquí? 00:32:34
todos mis componentes, en lugar de 00:32:35
declararlos aquí, voy a declararlos 00:32:38
fuera, ya está 00:32:40
en lugar de locales, y aquí ya los 00:32:41
coloco, hago con ellos lo que quiera 00:32:44
entonces, simplemente la etiqueta 00:32:45
y con su 00:32:47
inicialización si quiero, aquí 00:32:49
fuera, ¿cuál más tenía? 00:32:51
bueno, la puedo quitar 00:33:00
ya de aquí, claro 00:33:01
bueno, la etiqueta, ¿cuál más? 00:33:01
Este, el dato 00:33:04
Control X, aquí 00:33:05
Ahí está 00:33:08
¿Cuál más? 00:33:09
Así ya me queda más cortito 00:33:12
El resultado, la etiqueta esta 00:33:14
Aquí fuera 00:33:16
Y el botón 00:33:21
Aquí fuera 00:33:26
Vale, entonces ahora me queda una estructura 00:33:33
Un poco más, un constructor más cortito 00:33:35
Ya se empieza 00:33:38
Esto ya es más fácil un poquito de entender 00:33:41
Vale, entonces yo tengo 00:33:43
Este es mi frame 00:33:45
En mi frame 00:33:47
¿Qué componentes quiero? 00:33:49
Yo los he decidido, pues estos son mis componentes 00:33:50
Pa, pa, pa 00:33:53
Además, los puedo inicializar 00:33:54
Ahí si quiero, si no da igual 00:33:57
Los inicializo ahí dentro 00:33:59
Si los puedo inicializar aquí, pues mira, eso que me quito 00:34:00
¿Vale? Mi listado de componentes 00:34:02
Ahí, pa, pa, pa, esos son tu listado de componentes 00:34:05
Ahora, el constructor 00:34:07
El constructor, pues hace ya lo que tenga que hacer 00:34:08
Hace el gestor de ubicación 00:34:11
Lo asocia al panel 00:34:13
Pega los componentes al panel 00:34:14
¿Y qué es lo único que le falta? 00:34:16
Lo único que le falta es 00:34:19
Al botón 00:34:21
Añadirle 00:34:23
Añadirle 00:34:24
Añadirle un objeto 00:34:27
De esta clase de aquí 00:34:34
Un objeto de esa clase 00:34:35
¿Vale? 00:34:37
Vale, pues vengamos a añadírselo 00:34:39
Y ya está 00:34:41
Le añado un objeto de esa clase 00:34:53
Aunque el nombre real de la clase 00:34:56
y ahora vamos a comprobar, de capturar 00:34:58
pulsar botón, será en realidad 00:35:00
ventana visiesto, captura, pulsar botón 00:35:02
como aquí lo estoy instanciando 00:35:04
desde dentro de esta, no hace falta ponerlo 00:35:06
si yo lo instanciara en otra parte 00:35:08
sí tendría que ponerlo, pero eso no lo vamos a hacer 00:35:10
nosotros, no, quiero que 00:35:12
nos liemos ahora con clases internas 00:35:14
vale, entonces ahora ya 00:35:16
le añado un objeto de esta clase que 00:35:20
está dentro 00:35:22
entonces la ventaja al estar dentro 00:35:23
es que solo necesito la acción performance 00:35:26
solo 00:35:28
y en la acción performance accedo a lo que me dé la gana 00:35:29
a todo lo del frame 00:35:33
accedo a todo, siempre y cuando lo del frame 00:35:34
esté declarado fuera 00:35:36
y esta ya es la estructura habitual 00:35:37
de swing 00:35:42
el siguiente salto, pero eso ya lo veremos con el builder 00:35:42
es que esta clase además de interna sea anónima 00:35:46
pero eso ya sería el siguiente salto 00:35:48
es otra cosa 00:35:50
lo importante es que entendáis esta 00:35:51
esta estructura 00:35:54
si nos vamos de hecho 00:35:56
para que veáis que son dos clases diferentes 00:35:58
si nos fuéramos aquí 00:36:00
a ver lo que ha generado 00:36:04
en Vista 2 00:36:14
fijaos que hay dos clases 00:36:16
en el paquete Vista 2 00:36:25
está VentanaVis y esto con la otra dentro 00:36:28
con la otra dentro 00:36:30
y yo he dicho, oye, que este dentro 00:36:31
no significa que no sean dos clases independientes 00:36:32
claro que lo son, son dos clases independientes 00:36:35
esta es una y esta es la interna 00:36:37
que en punto clas se llama 00:36:39
con un dólar dentro 00:36:41
Son dos clases separadas 00:36:42
Y yo puedo instanciar las dos por separado 00:36:45
Esta la instanciaré con new ventana bisiesto 00:36:47
Y esta la instanciaré con new ventana bisiesto 00:36:50
Punto 00:36:52
Captura pulsar botón 00:36:53
Para la instancia desde código 00:36:55
Si quiero instanciarla afuera 00:36:56
Ahora es que la estaba instanciando dentro 00:36:57
Entonces al instanciarla dentro de esta 00:37:00
Puedo instanciarla directamente con su nombre interno 00:37:02
Pero son dos clases independientes 00:37:06
bueno independientes en el sentido de que se pueden instanciar 00:37:12
por separado pero 00:37:18
esta para existir tiene que 00:37:20
existir un objeto de esta otra 00:37:22
vale entonces si ejecutamos 00:37:24
esta ahora 00:37:26
nuestro main 00:37:28
un momento ya nos vamos 00:37:29
vamos a nuestro main 00:37:33
aquí 00:37:35
nuestro main en lugar de ventana 00:37:35
si esto vamos a hacerla de vista 00:37:43
dos 00:37:45
Vista 2, la otra que he hecho 00:37:45
Vale 00:37:49
Le pongo su nombre real 00:37:53
Con el prefijo delante 00:37:56
Para que no use la que tiene el import, que es esta 00:37:57
Esta es la nueva que he hecho 00:37:59
Con la clase interna 00:38:01
Si no se nos ha escapado nada, debería funcionar igual 00:38:02
Este main, con la nueva que hemos hecho 00:38:06
Y sí, funciona igual 00:38:08
Vale 00:38:17
Pues venga, vamos a parar aquí entonces 00:38:17
Subido por:
Raquel G.
Licencia:
Todos los derechos reservados
Visualizaciones:
10
Fecha:
22 de abril de 2024 - 18:08
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
38′ 21″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
549.86 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid