Saltar navegación

2024-12-02-Programacion - 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 2 de diciembre de 2024 por Jose Manuel M.

92 visualizaciones

Tema 4 - Conceptos POO

Descargar la transcripción

Ya estamos grabando. 00:00:01
No sé si tenéis alguna duda o alguna cosita que me queréis comentar 00:00:04
antes de arrancar a contaros yo cosas por ahí del tema 4. 00:00:07
¿Alguien decía algo por ahí? 00:00:18
Ah, sí, que no hay ninguna cosa que plantear de momento. 00:00:23
Vale, pues nada, pues arranco a contaros cosas entonces. 00:00:27
Bueno, el tema 4 ya lo tenemos abierto desde la semana pasada. 00:00:35
No sé si habéis tenido oportunidad de ir echándole un ojillo. Vamos a hacer un repaso así general. Este tema 4 habla, aquí estamos, es una introducción a la programación orientada a objetos y en verdad es muy complicado arrancar la asignatura si no se empieza a hablar desde el día 1, si vas a hacer cosas con Java ya relacionada con los objetos. 00:00:38
hablar de las estructuras de control 00:01:03
que es verdad que son 00:01:06
los bucles o las condiciones 00:01:07
los if, los switch 00:01:10
porque si 00:01:11
si lo estás utilizando 00:01:13
dentro de una programación orientada a objetos 00:01:16
e intentar evitar 00:01:18
lo que son objetos y lo que son clases 00:01:19
pues en verdad es muy complicado 00:01:21
así que además 00:01:23
considero que es mejor ir introduciendo 00:01:25
todos estos conceptos desde el principio 00:01:28
así que mucho de lo que se habla aquí 00:01:29
pues ya hemos ido trabajando, en cualquier caso le damos otro repaso 00:01:32
más formal y vamos con ello 00:01:36
vamos a crear un proyecto, por ejemplo llamemos tema 4 00:01:39
y así nos vamos apoyando en el IDE para ir haciendo 00:01:48
ir comentando los diferentes contenidos 00:01:52
bueno lo primero de lo que empieza a hablar el tema 4 es la diferencia 00:01:57
entre clase y objeto, como os digo ya lo hemos 00:02:07
tratado estos conceptos, una clase vendría a ser un esquema en el cual definimos cómo 00:02:11
se van a comportar diferentes objetos dentro de nuestro programa. Cuando nosotros arrancamos 00:02:20
un programa, en realidad las clases no se activan, sino que se activan objetos que responden 00:02:25
a las características que hemos definido por una clase en particular. Eso sí, esos 00:02:31
objetos tienen un comportamiento de acuerdo a lo que esté definido en la clase. Y cuando definimos 00:02:36
la clase, recordad, decimos que se compone, digamos, por dos tipos de información. Por un lado, 00:02:42
vamos a llamar clase tarea 4 o clase persona. Por un lado tenemos características o atributos 00:02:52
de la clase y por otro lado tenemos lo que son los métodos o las acciones. Los atributos 00:03:00
son variables pertenecientes a la clase que están disponibles en el ámbito 00:03:08
de toda la clase, es decir, todo atributo que definamos para una clase estará disponible 00:03:13
para trabajar con ellos en métodos que aparezcan 00:03:17
dentro de su ámbito, es decir, de las llaves que encierran a la llave. 00:03:21
Por ejemplo, por una persona diríamos que tenemos public 00:03:25
public string para el nombre. 00:03:28
Es un clásico utilizar la clase persona cuando te pones a explicar cosas de estas. 00:03:33
Ya en este tema, pues vamos a hablar un poquito de lo que son las etiquetas public, tanto para una clase como para un método o para un atributo, como es el caso, pero ahora en un ratín, lo decimos. 00:03:38
las variables típicamente 00:03:53
si son de clase, están definidas en el ámbito de la clase 00:03:57
y si son variables que necesitamos utilizar dentro de un determinado método 00:04:01
vuelve a aparecer aquí la etiqueta public, ya os digo que ahora 00:04:05
comentamos en qué consisten las diferentes posibilidades que tenemos para utilizar public 00:04:09
o alternativas a public, voy a saludar 00:04:14
vamos a poner aquí, esto sería un método, es decir, estos son los dos 00:04:18
bloques que tenemos dentro de una clase. Fijaros que una clase no es, en este caso una clase y en 00:04:22
particular la clase persona que estamos definiendo, no es ninguna persona en particular que vaya a 00:04:29
formar, que vaya a interactuar con otros objetos de mi programa, sino que es el esquema de lo que 00:04:33
van a tener cualquiera de las personas que demos de alta dentro de mi programa, que podrán tener 00:04:40
un nombre, una edad y la posibilidad de saludar. Fijaros que, bueno, pues podríamos definir 00:04:45
variables en diferentes ámbitos. En el ámbito de la clase 00:04:53
en sí, con lo cual está disponible entre las llaves de la clase 00:04:56
y aquí podríamos definir otras variables 00:04:59
int y valor. Si fuera en un momento dado 00:05:01
dentro del saludo necesitáramos un determinado valor. 00:05:05
Esta variable está disponible para el ámbito 00:05:11
del método saludar, mientras estas otras 00:05:13
en el ámbito de la clase. Podríamos decir, bueno, pues 00:05:16
si quiero utilizarla aquí en el método saludar, me resulta 00:05:19
muy cómodo coger y definirla aquí 00:05:22
y ya está, defino aquí todas y también 00:05:24
puedo utilizar y valor aquí 00:05:26
esto tendría dos implicaciones 00:05:27
por un lado, la implicación 00:05:30
de que esta variable 00:05:33
estaría no solo disponible en el método saludar 00:05:34
si consideramos que es una variable 00:05:36
propia de este método y no de toda la clase 00:05:38
sino que otro método 00:05:40
que tuviéramos por aquí, despedirse 00:05:42
también tendría disponible 00:05:44
esa variable, que puede ser 00:05:46
que nos interese 00:05:48
ponerlo con minúscula 00:05:49
Podría ser que no nos interese y luego, por otro lado, a nivel organizativo, las variables que definamos de clase típicamente serán variables que identifiquen a las personas y no variables que momentáneamente podamos necesitar para hacer una determinada tarea, en este caso dentro del método de saludar, como podría ser la variable y valor. 00:05:55
Y valor, en el contexto de saludar, según el algoritmo que estemos desarrollando aquí para saludar, podría ser necesaria, pero y valor no sería algo que identifique a objetos de la clase persona que vayamos definiendo. 00:06:17
Entonces, bajo ese criterio tendríamos que definir los métodos de clase que sí que tengan que ver con características de las personas y si necesitamos otras variables en momentos puntuales dentro de unos métodos para desarrollar su algoritmo, pues los definimos como variables locales. 00:06:31
Dentro de lo que son la sintaxis típica que está un poco acordada a la hora de programar en Java, las clases las ponemos empezando con una letra mayúscula y los métodos con una letra minúscula, con una excepción que son los métodos constructores. 00:06:47
Los métodos constructores se tienen que llamar exactamente igual que la clase. 00:07:13
Entonces aquí podríamos definir un método, public void persona. 00:07:18
Entonces este método, lógicamente si se tiene que llamar, es un método constructor porque tiene el mismo nombre y método que la clase. 00:07:28
Si se tiene que llamar igual y nos obligamos a que las clases empiecen con mayúscula, lógicamente el método constructor tendrá que empezar con mayúscula. 00:07:36
mayúscula y se escapa de el acuerdo digamos que hay para nombrar los métodos en líneas generales 00:07:43
que deberían empezar todos con minúscula. Si ponemos una S mayúscula fijaros que no es un 00:07:51
problema en realidad para el compilador sino que más bien es un convenio a la hora de nombrar 00:07:56
las diferentes funciones en Java y que si lo vemos en minúscula pues rápidamente sepamos 00:08:02
que eso podría llegar a ser un método los métodos constructores recordad mira vamos a poner aquí 00:08:08
otra clase dentro del proyecto que sea la clase inicio vamos a llamarla por ejemplo y en esta 00:08:18
clase inicio vamos a suponer que es el punto de arranque de nuestro proyecto entonces en esta 00:08:31
clase está el método public public static o static public me parece que tiene que ir el static antes 00:08:37
después repasamos un poco toda esta cabecera 00:08:47
del método main, entonces 00:09:05
venimos diciendo que todo proyecto necesita un punto de entrada 00:09:08
que es el método main 00:09:12
aquí es donde vamos a arrancar nuestro programa 00:09:15
en este proyecto hemos definido una clase que es la clase persona 00:09:17
que tiene unas determinadas características 00:09:22
y realiza unas determinadas acciones en forma de métodos 00:09:24
que en realidad todavía no hemos programado nada 00:09:28
uno de los métodos es el método constructor 00:09:30
¿por qué? porque se llama igual que la clase 00:09:33
y luego, bueno, pues tiene otros dos métodos aquí 00:09:36
después vamos poniendo algo de código en ellos 00:09:38
que son el de saludar y despedirse 00:09:41
en nuestro programa ahora mismo, si no venimos al main 00:09:44
tenemos alguna persona que haya cobrado vida 00:09:47
digamos, y empieza a hacer cosas dentro del programa 00:09:51
para dar solución al algoritmo que estamos buscando 00:09:54
pues no, todavía no, pero si en cambio tenemos 00:09:57
un esqueleto aquí de cómo se comportan las personas, es decir, 00:09:59
el comportamiento de toda persona que definamos en nuestro programa 00:10:04
está agrupado en esta clase que es la que hemos llamado de esta forma. 00:10:07
Entonces, ¿en qué momento damos vida a una persona? 00:10:15
Pues definimos un tipo de variable que en este caso va a ser del tipo persona 00:10:19
que justo hemos definido aquí sus parámetros y sus comportamientos 00:10:25
un poquito de forma similar a como definiríamos una variable 00:10:29
de un tipo primitivo, igual que definimos aquí 00:10:34
y es una variable del tipo int, resulta que persona 00:10:38
es una variable del tipo miper, es una variable del tipo 00:10:42
persona, entonces las características que tiene miper serán las que hayamos 00:10:46
definido nosotros aquí en esta clase. Para los tipos 00:10:50
primitivos hemos hablado otros días, no es necesario hacer el new 00:10:54
para los tipos referenciados si que lo es 00:10:57
entonces la clase persona es un tipo referenciado 00:11:00
para el objeto miper 00:11:03
lo primero que tenemos que hacer es hacer un new 00:11:05
que nos hará las reservas que toquen 00:11:09
en memoria RAM para que miper sea capaz 00:11:12
de funcionar dentro del programa 00:11:15
que principalmente se entiende sobre todo 00:11:17
si nos fijamos en sus parámetros pues hará reserva para guardar 00:11:21
estos datos y luego después del new 00:11:24
Java lo que nos demanda es que 00:11:28
le ponga, llamemos a un método que haga una inicialización 00:11:33
si es que corresponde hacer alguna inicialización del objeto que estamos dando 00:11:37
de alta y esa inicialización se hace a través de los constructores 00:11:41
recordad que hemos dicho que el constructor 00:11:44
es un método que se llama igual que la clase, entonces por eso 00:11:49
justo aquí después del new solemos poner persona 00:11:53
en este conjunto lo que estamos haciendo es definir 00:11:57
en el conjunto de esta instrucción, estamos definiendo 00:12:02
un objeto llamado miper en particular 00:12:05
de la clase persona, hacemos las reservas 00:12:08
que correspondan en memoria y llamamos a un método 00:12:12
para la inicialización de este objeto 00:12:14
de la clase persona, que es el método constructor 00:12:17
¿y qué inicialización se producirá? Pues la que 00:12:20
programemos aquí. En relación a los constructores 00:12:23
fijaros que si yo comento esto 00:12:29
este persona me sigue funcionando, me sigue compilando. 00:12:36
¿Qué sucede? 00:12:43
Si, como siempre después de hacer un new en un objeto que es de un tipo referenciado, 00:12:44
como siempre vamos a llamar al constructor, 00:12:51
por defecto, aunque no lo hayamos definido, 00:12:54
en la clase, en este caso la clase persona, 00:12:56
Java entiende que hay un constructor por defecto 00:13:00
que en esa inicialización no viene a hacer nada, digamos. 00:13:03
pero para dar sentido a la sintaxis que tiene java pues existe por defecto un constructor de 00:13:08
este tipo es decir el nombre de la clase y sin ningún parámetro metido aquí en dentro de las 00:13:14
llaves si yo cojo eso es para cuando no existe el de por defecto cuando no existe definido ningún 00:13:22
constructor dentro de la clase persona si yo para inicializar la clase persona me defino un 00:13:31
constructor, pues ese que había por defecto por ahí 00:13:36
queda ya sobrescrito y el que se utiliza 00:13:39
es el que yo define aquí con el código 00:13:42
que yo ponga. Entonces, en el momento que yo ya he definido 00:13:46
un constructor dentro de la clase persona, ese constructor por defecto 00:13:57
al que estaba llamando yo antes cuando no existía ninguno, que era 00:14:01
uno por defecto y no hacía nada, deja 00:14:03
de existir para pasar a existir el que yo ponga 00:14:07
dentro de mi clase. Pero es más, 00:14:10
si yo defino un constructor 00:14:13
que dentro de mi clase que admita y ahora repasamos también estos métodos que admita información entre 00:14:16
los paréntesis ahora hablamos de qué consiste esto esto también desactiva el constructor por 00:14:32
defecto es decir definir cualquier constructor con o sin información entre los paréntesis desactiva 00:14:38
el constructor que por defecto tiene java para cuando no existe ninguno entonces en este caso 00:14:44
me sigue compilando esto, yo esperaba que no me compilase 00:14:49
pues nada de lo dicho, pues sigue compilando 00:15:02
nada, retiro lo dicho, estaba comentando que en el momento que definías 00:15:31
cualquier constructor, que en el momento que definías cualquier constructor con o sin 00:15:35
parámetros, yo pensaba 00:15:42
cosa que por lo que veo según se está comportando el código, era erróneo 00:15:45
que el constructor por defecto quedaba desactivado, en este caso 00:15:50
si hubiera sido como yo decía, esto me debería haber dado error 00:15:54
porque estoy invocando a un constructor por defecto 00:15:57
que no recibe ningún parámetro y en cambio solo 00:16:00
por código tengo definido uno que sí que recibe un parámetro 00:16:03
pero por lo que veo el constructor por defecto solamente 00:16:06
deja de tener sentido el que 00:16:09
nos ofrece Java que no hace nada 00:16:11
si lo sobrescribo dentro de 00:16:14
la clase persona, no si 00:16:17
lo sobrecargo, ahora os comento el tema de la sobrecarga 00:16:20
que es otro constructor con parámetros aquí, pues nada 00:16:24
este seguiría funcionando por lo que se ve aquí, ahora tendríamos 00:16:27
en sí dos constructores a los que podríamos llamar después del 00:16:32
new, fijaros que ambos dos son constructores porque los dos 00:16:36
se llaman como la clase persona, como la clase y este 00:16:39
objeto en el momento de inicializarlo, pues podríamos utilizar 00:16:44
el constructor que no recibe ningún parámetro, que sería este 00:16:47
y para este segundo objeto podríamos utilizar el constructor que si lo recibe vale bien ya entiendo 00:16:51
lo que me está pasando está mi error mirad los los constructores se definen sin tipo aquí ahora 00:17:14
también os comento lo que es el tipo este es public persona no public void a ver si ahora 00:17:24
así que tiene el comportamiento que yo esperaba miras efectivamente en el momento que defino 00:17:36
cualquier constructor ahora repaso lo que me estaba lo que estaba sucediendo para que lo 00:17:44
tengáis claro en el momento que yo defino cualquier constructor con o sin parámetros 00:17:49
recibiéndose por aquí entre los paréntesis el constructor por defecto deja de estar activo 00:17:53
veis ya no me compila por aquí cuando está activo cuando está disponible el constructor por defecto 00:17:58
cuando no existe ningún constructor en la clase en este caso fijaros como ahora tengo comentados 00:18:04
tanto el que no recibe parámetros como el que sí que lo recibe uno y ya me vuelvo a compilar esto 00:18:10
que era la lógica que yo esperaba antes pero mi error es que había puesto aquí un public void 00:18:15
y al momento al poner este voice aquí ya no lo consideraba como el constructor en sí porque los 00:18:21
constructores no tienen ninguna etiqueta de este tipo ahora os comento lo que es el voice este 00:18:27
Aquí lo tenemos. Bueno, pues fijaros cómo hemos dado de alta aquí a dos personas y estos objetos ya sí que son los que van interactuando durante el programa con, bueno, pues para ir haciendo cosas, pues mi per podrá saludar, mi per 2 podrá despedirse y a través de los objetos que hemos dado de alta y hemos inicializado con el constructor, poniendo aquí un punto, pues podemos hacer a sus parámetros o a las funciones que él puede hacer. 00:18:32
¿Qué funciones puede, qué métodos podemos llamar o qué funciones puede hacer un objeto? Pues los que tengamos definido dentro de la clase, más otros que están disponibles en todas las clases de que podamos, que vayamos utilizando dentro de nuestro programa, porque los tienen disponibles como consecuencia de una especie de herencia desde la clase Object. 00:19:08
Como pues el notify, notify all, toString, wait, bueno, todos estos métodos están disponibles para cualquier objeto de cualquier clase, no porque los definamos en sí dentro de la clase, sino porque nos vienen definidos, digamos, desde unas instancias superiores en una jerarquía de clases por herencia. 00:19:29
La herencia, hablaremos de ella más en detalle en siguientes temas, pero viene a consistir en que una clase que definamos, aparte de tener sus características, tiene algunas características porque son clases hijas dentro de una jerarquía de clases que va de arriba a abajo, de clases superiores. 00:19:48
Entonces la clase object es una clase definida en las librerías de Java que implementa unas ciertas cosas que interesa que las tengan disponibles todos los objetos de todos los programas. 00:20:17
Y esa es la razón por la que si ponemos aquí mi per punto, no solamente sale despedir aquí o saludar, que son métodos que he definido ahí o los atributos que tenemos por aquí, sino que nos salen otros métodos como equals, getClass, hasCode y notify que vienen heredados desde esas clases superiores. 00:20:29
Mira, más cosas. Una de las características que tenemos en la programación orientada a objeto es la sobrecarga de métodos. Persona, en este caso que es el método constructor, es un método más de la clase, entonces es posible sobrecargarlo, igual que sería otros métodos que tengamos por aquí. 00:20:50
Vamos a sobrecargar el método saludar, después os cuento para qué sirve el void este que decíamos. 00:21:20
Mira, si yo pongo este código, system.out.println, hola, en este saludo, y aquí pongo un hola2, resulta que el programa no me compila. 00:21:27
¿Y por qué no me compila? Porque si yo ahora cojo aquí y digo miper.saludar, hago una llamada para que el objeto miper salude, para saludar se tiene que ir al esquema de la clase persona a ver cómo tiene que actuar a la hora de saludar. 00:21:47
Y cuando llega aquí dice, tengo un saludar aquí y todo otro saludar aquí, que en principio van a hacer cosas diferentes. 00:22:06
Entonces hay una dualidad de posibilidades que dice, entonces, ¿qué hago? ¿Digo hola por pantalla o digo hola dos? 00:22:13
Esto no lo va a permitir el programa, el compilador nunca, porque como no sabe por dónde tirar, pues lo que nos dice es no compilo. 00:22:21
entonces que tendría que hacer definir un método diferente saludar dos para que me dejara hacer 00:22:30
los lados y saludar para que me dejas hacer el hola sería una alternativa pero ya no sería el 00:22:36
método saludar que es realmente lo que yo quiero hacer tenerlo identificado como saludar en ambos 00:22:41
casos con dos posibilidades distintas como podríamos manejarlo pues sobrecargando el 00:22:46
método saludar sobrecargar el método a saludar implica que de alguna forma cuando vayamos a 00:22:52
hacer una llamada a saludar no haya dudas de si quiere utilizar un código u otro y que técnica 00:23:00
en la que nos permite sobrecargar métodos que tienen el mismo nombre pues que reciban una 00:23:07
serie de parámetros entre los paréntesis entonces por ejemplo yo pongo aquí string ese saludo ahora 00:23:13
ya me compila, como podéis ver. 00:23:24
El hecho de que compila aquí 00:23:27
me permite que ahora 00:23:28
yo si yo llamo a mi 00:23:29
per.saludar y aquí 00:23:31
no paso ningún 00:23:34
parámetro, ninguna información, 00:23:36
ningún dato, cuando se venga 00:23:38
a la clase persona a buscar 00:23:40
que saludar ejecutar, ya no va a haber 00:23:41
lugar a dudas. Este 00:23:44
no espera recibir ninguna información, 00:23:45
con lo cual ejecutaría en este caso este 00:23:47
System.out.println 00:23:49
y este solo se ejecutará en el caso de que entre los paréntesis 00:23:51
a la hora de llamar al método saludar, pasemos un string. 00:23:56
Entonces, si yo cojo y pongo aquí, miper.saludar, buenos días, 00:24:01
ahora estoy llamando al método saludar, pasándole entre paréntesis 00:24:18
una cadena de caracteres, es decir, un string. 00:24:22
Si nos venimos por aquí, este no tiene definido ningún string aquí, 00:24:24
con lo cual no va a ser el código que se va a ejecutar 00:24:29
y este en cambio tiene definido un string que corresponde justo 00:24:31
con la sintaxis de esta llamada 00:24:35
que le estábamos pasando una cadena de caracteres 00:24:38
entonces para este saludar buenos días 00:24:41
ahora vuelvo a no haber dudas que el método 00:24:43
saludar que quiero ejecutar de la clase persona 00:24:47
es este, en este segundo caso nos dirá 00:24:50
uno o la dos 00:24:53
fijaros como si ejecutamos 00:24:55
he ejecutado el programa del otro día 00:24:58
bueno, me ha sacado aquí toda esta información 00:25:05
y fijaros en qué consiste toda esta información 00:25:20
hemos llamado a 00:25:22
dos constructores, este constructor 00:25:23
persona, fijaros como 00:25:26
tiene un hola, con lo cual el primer constructor 00:25:29
me ha mostrado este hola, al crear el 00:25:31
segundo 00:25:33
de los objetos, también he llamado al constructor 00:25:34
que no recibe ningún parámetro, aunque tengo 00:25:37
dos por aquí, me ha vuelto a escribir un segundo 00:25:39
hola, este saludar 00:25:41
al invocar este método 00:25:45
sin parámetros me ha ejecutado este saludar, me ha dicho el tercero de los olas 00:25:47
y este otro que recibía un stream buenos días 00:25:52
me ha ejecutado este otro método y ya me ha puesto el ola2 00:25:57
vale pues, que diferencia 00:26:01
en realidad, que diferencia tenemos entre llamar a uno u otro 00:26:09
pues aquí estamos, bueno antes de contaros eso, fijaros que yo 00:26:13
si yo pongo aquí saludar y le pongo aquí un número 00:26:17
en una cadena de caracteres un 2, pues tampoco me compila. ¿Por qué? Porque 00:26:21
un método saludar que recibe un valor numérico 00:26:25
aquí entero, no está considerado, no está sobrecargado 00:26:29
entre los diferentes métodos saludar que tiene la clase persona, que tiene una sobrecarga 00:26:33
entre un saludar sin parámetros y un saludar que recibe 00:26:37
un string. Pero no hay ningún saludar que reciba un valor 00:26:41
entero. Como no hay ninguno que reciba un valor entero, pues coge y este 00:26:45
no me compila. Si fuese necesario saludar pasándole 00:26:49
aquí un dato, fijaros que, ¿qué tendríamos que hacer? Pues sobrecargar 00:26:53
nuevamente saludar, fijaros que ahora vuelve a no compilarme 00:26:59
porque vuelve a haber una ambigüedad entre dos saludar 00:27:05
que los dos reciben un string, pues podría poner aquí uno que reciba un 00:27:09
entero y volvería a compilarme, ¿por qué? Porque tengo una triple 00:27:13
sobrecarga, uno sin parámetros, uno con un string y otro con un valor entero 00:27:21
Y ahora ya, aquí también, este ya no le importa, también le gusta. Bien, pues ahí tenemos la sobrecarga. ¿Qué sucede con estos? ¿Qué interés tiene, según acabo de hacer ahora, crear valores sobrecargados que reciban aquí cierta información? 00:27:25
Pues el interés puede ser el siguiente, fijaros, si yo, estas variables que definimos aquí dentro de los paréntesis se utilizan dentro del método como variables locales, si yo pongo aquí int y 1, pues 1 sería una variable tipo primitiva de tipo int y estaría disponible para ir utilizando esta variable metiendo valores, datos, utilizándolo para operaciones numéricas, 00:27:49
o lo que correspondiese dentro del ámbito del método saludar, que es donde está definido. 00:28:19
Pues estas variables que aparecen aquí entre los paréntesis son variables de ámbito local al método también. 00:28:25
Es decir, el string eseSaludo pertenece al ámbito del método saludar, de este en particular, de esta sobrecarga del método saludar. 00:28:33
De igual forma, esta variable int y valor pertenecen a este ámbito. 00:28:43
¿Y qué valor tienen? Pues por aquí podríamos ir modificándolo, podríamos poner ese saludo igual que con cualquier otra variable, pues irle dando valores aquí, información, lo que fuese, pero de partida la información que tiene con la información que se cargan en el inicio de la ejecución del método corresponde al dato que pasemos nosotros aquí cuando estemos haciendo la llamada. 00:28:48
Entonces, estos buenos días, en este saludar que está recibiendo una cadena de caracteres, este buenos días se carga directamente en la variable ese saludo. 00:29:14
entonces si yo pongo aquí un system.out.println de ese saludo, para que no me muestre más mensajes, de momento voy a quitar los constructores estos, al quitar esos dos constructores se me queda el constructor por defecto que no hace nada en código, uno disponible siempre, que no recibe ningún parámetro, ¿veis como me sigue compilando? 00:29:26
entonces si yo ahora me llamo al método que recibe 00:30:14
una cadena de caracteres en dos ocasiones 00:30:25
y en uno le paso buenos días y en otro buenas noches, durante la ejecución 00:30:28
de este saludar que recibe un string, este buenos días se cargará 00:30:33
en la variable ese saludo y en la segunda de las ejecuciones 00:30:37
lo que cargará será este buenas noches en la variable ese saludo 00:30:41
de tal forma que nos permite mostrar diferentes saludos 00:30:45
un mismo código 00:30:49
haciendo la misma llamada 00:30:52
en función a 00:30:53
la información que tengamos desde el punto 00:30:55
de la llamada 00:30:58
fijaros como si ejecutamos aquí 00:30:58
pues ahora nos dice una vez buenos días 00:31:02
y otra vez buenas noches 00:31:03
si tenemos aquí el saludar 00:31:05
este que recibe un valor 00:31:10
numérico, pues de igual 00:31:12
forma aquí podríamos coger y decir 00:31:16
vamos a mostrar 00:31:17
el valor, la misma jugada que antes 00:31:18
entonces ahora esto no escribiría siempre un valor, si ponemos aquí que escriba un 2, pues escribiría un 2, pero si ponemos sí valor, lo que nos mostrará es la información de esta variable, esta variable se carga cada vez con el dato que hemos pasado en la llamada, entonces si ahora ponemos aquí un 2 y hacemos otra llamada con un 3, veamos como la ejecución de los métodos nos muestran el dato con la información de las variables 00:31:22
En cuanto a la sobrecarga, también deciros que hemos hecho sobrecarga aquí del método saludar sin parámetros, con un parámetro, con otro parámetro, pues podemos seguir sobrecargándolo en base a que se diferencie el método saludar unas implementaciones de OTT con otras en el número o en el tipo de datos que tengamos. 00:31:49
aquí teníamos un mismo número de datos pero de diferente tipo 00:32:17
con lo cual ya no había ambigüedad aquí a la hora de llamarlo, luego tenemos también la 00:32:21
posibilidad de decir, mira pues quiero uno que 00:32:25
reciba dos parámetros, ese info, entonces 00:32:29
para llamar a este, desde el sitio donde 00:32:35
invocamos el método, pues pondríamos miper. 00:32:39
saludar, fijaros que aquí Eclipse 00:32:44
me está ofreciendo todos los métodos sobrecargados informándome de los tipos de datos que puede 00:32:46
recibir. En particular queremos utilizar este ahora, pues uno que recibe un entero y otro que 00:32:53
recibe un string. Entonces podríamos decir el valor 4 y el string buenas. ¿Y qué sucede con 00:32:58
estos dos valores? Pues supongo que ya lo iréis adivinando por lo que hemos comentado antes. Estos 00:33:08
valores, lo que hacen es directamente cargarse en estas dos 00:33:13
variables. Y valor de inicio valdrá en esta llamada 00:33:17
4 y buenas, este string se cargará en ese 00:33:21
info. Y estas dos serán dos variables locales disponibles 00:33:25
dentro del ámbito del método saludar 00:33:29
de esta versión sobrecargada del método saludar, es decir 00:33:32
en todo el ámbito de sus llaves. Aquí lo podríamos utilizar 00:33:36
para lo que lo que tocase típicamente los constructores que hablábamos antes de ellos 00:33:40
decimos que tienen el nombre de la clase y típicamente existe bueno pues el constructor 00:33:51
por defecto que es un constructor que no recibe ningún dato luego existe el constructor copia y 00:34:08
bueno podríamos llamar el constructor completo que recibe tantos parámetros el completo este sería 00:34:36
constructor copia este el constructor por por defecto y luego el que podríamos llamar 00:34:45
constructor completo que éste recibe tantos parámetros como atributos tenga definida la 00:35:03
clase este tiene dos atributos un string y una edad podría tener más si hubiera más 00:35:17
características particulares de objetos de la clase persona podría tener más en este caso 00:35:23
tiene dos, pues entonces recibiría string snom, vamos a poner, y int y et. Fijaros, tiene dos 00:35:28
atributos, voy a llamar completo, y normalmente este constructor lo que hace es, estos datos los 00:35:42
copia en las variables del objeto que estamos creando. Entonces aquí pondríamos ese nombre, 00:35:51
igual a ese nom 00:35:58
y edad igual a i ed 00:36:01
vamos a pensar un momentito en este, ahora después pasamos al constructor 00:36:10
copia, fijaros, si yo cojo y defino 00:36:20
imaginaos que doy de alta, interrumpidme si tenéis 00:36:24
alguna duda, alguna pregunta que hacerme sobre lo que os voy 00:36:30
contando, damos de alta en nuestro programa una persona 00:36:34
que llamamos MiPer. Justo a esta persona le empezamos a dar características. 00:36:45
Si decimos que tiene un nombre que es Noah y MiPer tiene una edad que es 10 años, por ejemplo. 00:36:51
Hemos dado de alta un objeto para que participe en nuestro programa 00:37:08
llamando a este constructor, ese constructor 00:37:12
es este constructor por defecto, que fijaros, no está haciendo nada, bueno, no es el de por defecto 00:37:18
lo tengo aquí escrito, pero no está haciendo nada, no he puesto código en él 00:37:22
y luego cojo y digo, esta persona, fijaros que 00:37:26
a la hora de hacer este new, me habrá hecho el sistema operativo 00:37:30
una reserva en zona de memoria, con al menos espacio donde guardar 00:37:34
estos datos, entonces, el hecho 00:37:38
de hacer el new, vamos a ponerlo aquí en esta línea, pues igual ha cogido el sistema operativo 00:37:42
y ha dicho en la posición 30.000, la que sea, ¿vale? Pongo aquí 30.000, pero sería la que 00:37:46
en la que encuentre un espacio en memoria RAM el sistema 00:37:50
operativo donde guardar esos datos. Reservo espacio 00:37:54
bueno, sí, reservo espacio 00:37:57
para una persona. El tamaño 00:38:06
de espacio que necesita reservar, pues ya se lo estará archivando el compilador 00:38:11
dejaba que serán menos para estos dos datos. Cuando cojo y escribo el nombre 00:38:15
de NOA, pues de alguna forma se habrá organizado y a partir de la 30.000 00:38:22
seguro que pondrá en algún sitio, guardará el valor de NOA 00:38:26
y cuando le pongo la edad de 10, a partir del 30.000 00:38:29
dentro del rango de memoria que haya reservado 00:38:34
pues seguro que guarda NOA y en algún sitio guardará el 10. 00:38:38
Todo este trocito está a partir del 30.000 dentro del 00:38:42
espacio de memoria que nos habrá hecho de reserva para el new. 00:38:46
Si yo cojo ahora aquí y digo miper2 00:38:49
igual a new persona 00:38:53
y ahora le paso aquí estos datos, 00:38:57
lo que estoy haciendo es con el new una reserva de memoria igual que 00:39:14
pasaba aquí para una persona, en particular va a ser para miper2, 00:39:18
es decir, esta referencia de una persona apuntará a la posición 00:39:22
que toque, y a lo mejor el sistema operativo en este caso ha dicho que es el 40.000 00:39:26
y luego llamo a un constructor que recibe 00:39:30
una cadena de caracteres y un valor numérico, este constructor 00:39:35
resulta que es uno de los disponibles aquí, porque lo tenemos sobrecargado 00:39:39
es este, fijaros como este recibe un string y un valor numérico 00:39:44
¿veis? entonces Valeria donde se cargará? 00:39:47
se cargará en SNOM y el 13 se cargará 00:39:51
en ied, ¿veis? Ahora continuamos con esa ejecución. 00:39:57
Los valores que tiene miper cuando he definido esta primera 00:40:07
persona, como hicimos el new, hemos cargado 00:40:10
en su nombre y en su edad, fijaros que son las variables de clase 00:40:15
de miper, noa y 10, es decir, los hemos cargado en 00:40:19
estas dos variables, ¿veis? Con lo cual, todo el tiempo 00:40:23
que esté disponible el objeto miper, 00:40:26
como estas variables están en este ámbito de ejecución 00:40:30
de toda la clase, los tendremos disponibles. Es decir, ese nombre 00:40:35
si no sobreescribimos su información, valdrá durante 00:40:39
toda la ejecución del objeto, si llamamos 00:40:43
a métodos, valdrá no A y la edad valdrá 10. 00:40:47
¿Qué sucede en este otro? Valeria y 13 00:40:53
que podemos pensar, y de hecho es lo que vamos a hacer, que son el nombre y la edad 00:40:56
que va a tener mi per 2, Valeria y 13 lo estamos metiendo a través del constructor. 00:41:00
Y el constructor guardará en esta variable la información de Valeria y en esta variable el 13. 00:41:06
¿Qué ámbito de ejecución hemos dicho que tienen estas dos variables que están aquí entre los paréntesis? 00:41:14
Hemos dicho que son variables locales a este método. 00:41:20
Con lo cual, una vez que se ejecute este método, estas dos variables desaparecen. 00:41:23
desaparecen. Es decir, que si este ha cogido valeria y este ha cogido 13, cuando llegue el código 00:41:27
aquí, se terminó estas dos variables. 00:41:32
Con lo cual, el nombre no está disponible si lo queremos utilizar por aquí en saludar, 00:41:36
en este otro saludar o en despedir. Para conseguir 00:41:40
que este valeria y este 13 se queden guardados 00:41:44
para el objeto miper2 00:41:47
y tenerlos disponibles en cualquier otro método de la clase, 00:41:50
que lo que hacemos es que esta información 00:41:56
y esta la guardamos en estas otras dos variables 00:41:59
que son las variables de clase. En definitiva hemos hecho 00:42:02
algo parecido en ambos casos. Hemos creado 00:42:07
un objeto miper y miper2. En este hemos 00:42:10
utilizado el constructor por defecto 00:42:13
que no hacía nada y luego 00:42:15
mediante estas dos instrucciones 00:42:19
hemos dado valor a los parámetros 00:42:20
de clase que el objeto miper de la clase persona 00:42:25
tiene. Hemos puesto noa en esta variable, en esta 00:42:29
de clase, y la edad de 10 en esta variable. 00:42:33
Como están definidas en este ámbito, no solamente están 00:42:38
disponibles en el constructor, sino que están disponibles en cualquier otro método de la clase 00:42:41
persona cuando ejecutemos ese código para el objeto 00:42:45
miper. Y en este segundo caso, 00:42:49
a todos los efectos esta línea ha hecho lo mismo que estas tres 00:42:52
para la clase miper2, luego que lo hemos hecho a través de 00:42:56
un constructor, hemos pasado estos datos por aquí, que vendrían a ser el equivalente 00:43:00
de estos dos, y la clase en este constructor 00:43:05
que como decimos, una vez termina su ejecución 00:43:09
ya que se copian en estas variables, si estas variables son de ámbito 00:43:13
local al constructor, desaparecerían, pero al guardarlas 00:43:17
en las variables de clase, pues ya las tenemos disponibles para utilizar 00:43:21
esos datos, Valeria como nombre y 13 como edad 00:43:24
en cualquiera de todos los métodos cuando estemos trabajando 00:43:28
con el objeto miper2 de la clase persona. Cuando termina 00:43:32
esta ejecución, con este new habremos hecho 00:43:38
esta reserva y aquí terminará valiendo en la memoria RAM 00:43:42
Valeria y 13, pero este Valeria y 13 00:43:46
se estarán cargando justo durante la ejecución 00:43:50
del constructor aquí. Entonces este es el que podríamos llamar 00:43:53
no me acuerdo si exactamente es completo como lo llama 00:43:59
la teoría, creo que sí 00:44:01
lo podríamos llamar completo en tanto en cuanto se utiliza 00:44:04
para copiar en el momento que estamos haciendo 00:44:08
una inicialización del objeto 00:44:11
información de tantos parámetros como 00:44:12
de tantos datos como parámetros 00:44:17
tiene la clase persona. 00:44:19
Podría haber otros intermedios, otros constructores 00:44:27
intermedios, pero ya no tienen un nombre 00:44:29
en sí. Es decir, podríamos tener uno 00:44:31
que dijese, mira, vamos a hacer 00:44:32
un constructor persona que reciba un nombre 00:44:35
y no reciba una edad. 00:44:37
Si no recibe una edad, ya no lo consideramos 00:44:41
como el constructor completo. 00:44:43
Nos serviría para, desde el momento en el que estamos 00:44:45
haciendo la inicialización, darle un nombre, 00:44:47
pero esta variable no tendría un dato. 00:44:49
Imaginaros que nuestro programa dice 00:44:51
hay un momento en el que queremos 00:44:53
que todas las personas que se dan de alta con este constructor tengan la edad de 15, pues aquí 00:44:55
podríamos poner y edad igual a 15, con lo cual estaríamos inicializando los dos parámetros, este 00:45:01
como consecuencia del parámetro que se recibe a la hora de llamar al constructor y este siempre con 00:45:09
un valor de 15, en esa situación se podría por ejemplo encontrar una tercera persona que sería 00:45:15
persona miper3, este nombre de los objetos 00:45:22
me estoy inventando unos, hacemos el new como siempre 00:45:27
y ahora llamamos al objeto persona y esta persona 00:45:31
se llama Rubén y no le pasamos un segundo parámetro 00:45:35
pues miper3 00:45:40
el string de Rubén se guardaría en la variable 00:45:44
senom, esta variable senom es local 00:45:49
a este método sobrecargado de la constructor de la clase persona, 00:45:53
con lo cual ese nom desaparece aquí, pero para dejarlo permanente 00:46:00
mientras exista el objeto miper3, lo paso a una variable de clase 00:46:05
que es del ámbito de la clase en su conjunto. 00:46:10
Es decir, copio en ese nombre ese nom. 00:46:12
Y como justo este constructor es el que hemos decidido utilizar 00:46:16
cuando creamos nuevas personas a las que les queremos añadir 00:46:20
un nombre, pero sin darles una edad 00:46:23
por defecto le consideramos una edad 15, imaginaos que eso es lo que 00:46:26
dijese nuestro enunciado del ejercicio, pues aprovechamos 00:46:29
y en el constructor que es momento de inicialización 00:46:32
del objeto, decimos que su edad y edad sea 15 00:46:35
ahora este 00:46:38
ya no sería ninguno de los que 00:46:41
tenemos digamos más estándar, el de por defecto que no recibe nada 00:46:44
el de copia que ahora os cuento y el completo 00:46:47
que tendría tantos parámetros de entrada 00:46:50
como atributos tiene la clase 00:46:53
si tuviéramos 10 atributos aquí, pues fijaros si habría 00:46:55
combinaciones de posibles constructores, un constructor 00:46:59
que le pasas 9 y uno se queda por defecto, otro que le pasas 00:47:02
7, otro que le pasas 7 pero diferentes a los 7 00:47:05
anteriores, habría muchas posibles 00:47:08
combinaciones de posibles parámetros sobrecargados 00:47:11
estos 3, el de por defecto 00:47:16
el completo y el copia. Fijaros, el copia lo que recibe como parámetro es otra persona, ¿veis? Aquí. 00:47:20
Si tenemos aquí, vamos a repasar, este me ha dejado de compilar, sí, porque lo he borrado. 00:47:37
Mirad, vamos a ver el constructor copia. Creamos una primera persona según este modelo, según el constructor por defecto, 00:47:49
el que no recibe ningún parámetro. 00:47:58
Y ahora vamos a crear una segunda persona, 00:48:02
igual a new, persona, 00:48:07
y queremos utilizar el constructor copia. 00:48:09
¿Qué recibe el constructor copia? 00:48:11
Fijaros, recibe una referencia a una persona. 00:48:13
Entonces aquí podríamos poner una referencia a una persona. 00:48:19
¿Quién es una persona anterior que ya existe en mi programa? 00:48:21
Mi per, ¿veis? 00:48:24
Entonces aquí podemos poner mi per. 00:48:26
El programa me compila. 00:48:31
¿Y esto qué sentido tiene? 00:48:33
Pues fijaros, miper es una referencia, es un dedito, es un puntero que está señalando el lugar en la memoria RAM donde se nos ha producido la reserva. ¿Para qué? Para guardar para miper su nombre y su edad. 00:48:34
Es decir, mi per, según este desarrollo de ejemplo que estamos poniendo, sería 30.000. Sería posición de memoria 30.000. A partir de ahí es donde están los datos del objeto mi per. Es decir, a partir de ahí es donde, por ser una persona, mi per tendrá guardado su nombre y su edad. 00:48:51
aquí justo a este constructor de la clase personal le estoy pasando 00:49:10
un valor de una referencia a una persona, es decir, en este caso 00:49:17
porque es el que hemos elegido, hemos hecho el supuesto que nos ha dado 00:49:21
el sistema operativo, es mi per que apunta en la RAM al 30.000 00:49:25
entonces igual que en estos casos, esto era un string que se copiaba en la variable 00:49:28
local que tenemos en el método, pues 00:49:33
esta referencia se copia en la variable local que tenemos en el método constructor 00:49:36
Es decir, aquí P tendrá la posición, tendrá la referencia a donde apunta quien ha llamado y quien ha llamado justo en esta ocasión, porque fijaros que este constructor lo vamos a llamar ahora después más veces, pues en esta ocasión ha llamado mi per. 00:49:40
Entonces, para este caso en particular, p apuntará al mismo sitio donde mi per. Entonces, ¿dónde estará apuntando p? Pues en esta ejecución en particular, para esta, que estoy haciendo aquí, estará llamando p, apuntando p a 30.000. 00:50:01
entonces si yo ahora cojo y digo ese nombre 00:50:21
fijaros, este ese nombre 00:50:25
a quien corresponde, a este atributo 00:50:27
de la clase persona y este 00:50:30
constructor lo estamos llamando para quien, lo estamos llamando 00:50:33
para miper2, con lo cual 00:50:36
si miper2 en el new ha sido 40.000 00:50:39
me dio 40.000 la reserva 00:50:43
ya os digo que 30.000 y 40.000 son datos 00:50:45
inventados, el sistema operativo nos dará el que 00:50:49
el que le parezca según los espacios 00:50:51
que encuentren memoria RAM disponibles en cada momento 00:50:53
no tienen 00:50:55
por qué ser estos números redonditos 00:50:57
que os voy poniendo en el ejemplo 00:50:59
entonces, ese nombre 00:51:00
e iedad 00:51:05
estarán 00:51:08
a partir del 00:51:09
40.000 en una zona de memoria 00:51:11
con un espacio suficiente para guardarle 00:51:13
ese nombre y la iedad 00:51:15
¿de quién? de miperdos 00:51:17
entonces si yo pongo aquí 00:51:19
ese nombre, este ese nombre 00:51:21
corresponderá a ese 00:51:23
posible, ese nombre que tenemos aquí 00:51:25
colgando del 40.000 00:51:27
y aquí diremos que sea igual a 00:51:28
p.eseNombre 00:51:31
p donde nos apuntaba 00:51:33
a 30.000 00:51:36
y a partir de ese 30.000 00:51:38
tiene un nombre, pues el nombre que hay 00:51:43
colgando de 30.000 00:51:45
que es 00:51:46
noa, como veis aquí 00:51:48
esa información del string lo copia 00:51:50
en el nombre perteneciente al objeto que está haciendo la llamada 00:51:52
al constructor, que es miper2. 00:51:57
Con lo cual, lo que estamos haciendo es poner aquí noa. 00:51:59
Y luego cogemos y hacemos aquí uniedad igual a p.iedad. 00:52:06
Nuevamente, p donde apunta a 30.000. 00:52:15
Colgando de 30.000, según la estructura que nos haya dado 00:52:17
el sistema operativo para hacer la reserva para las variables 00:52:21
de clase, hay una edad. 00:52:24
aquí que hemos puesto este 10, que cuelga de 30.000, fijaros 00:52:26
entonces coge este 10 y lo copia ¿dónde? 00:52:30
en iedad, iedad ¿quién es? 00:52:33
esta iedad, ¿de qué objeto está llamando al constructor 00:52:35
en este momento? miper2, que está en el 40.000 00:52:39
entonces 40.000 00:52:42
con el desplazamiento necesario para guardar la edad 00:52:43
nos guardará el dato de 30.000 con el desplazamiento 00:52:47
de la edad, es decir, nos copiará aquí el 10 00:52:51
Entonces, para todos los atributos que tengamos en una clase, el constructor copia lo que hace es guardarnos la información de este objeto que le pasamos como parámetro en los atributos que tiene el nuevo objeto que estamos creando. 00:52:53
Por eso se llama constructor copia. Copiamos la información de este objeto en el nuevo objeto y en todos sus parámetros. Este es el copia. 00:53:14
Si aquí cogiésemos, si hiciésemos persona miper3 igual a new persona y le pasamos p, por ejemplo, de nuevo, miper, perdón, miper2, por ejemplo. 00:53:25
Ahora, para esta ejecución, miper2, que hemos dicho que vale 40.000. 00:53:54
para miper3, gracias a este new 00:53:59
nos hará una reserva, sistema operativo de espacio de memoria 00:54:02
vamos a suponer que sería el 50.000 00:54:06
vamos a dividir de 10.000 en 10.000 00:54:08
con un trozo de memoria por aquí reservado 00:54:09
para guardar información para sus atributos 00:54:13
es decir, para su nombre y para su edad 00:54:17
nombre y edad de quien? de miper3 00:54:19
al constructor le pasamos como referencia 00:54:22
un objeto de una clase persona, miper2 donde apunta 00:54:25
al 40.000. Entonces, en esta segunda ejecución P, en la primera ejecución apuntaba a quien la 00:54:28
había llamado, en ese caso era mi per, pues en este caso, en esta segunda llamada es a mi per 2, 00:54:40
que es en el 40.000. Entonces P sería 40.000 ese nombre, que bueno, como es copia desde el primero, 00:54:45
los datos van a ser los mismos de nuevo, pero en este caso no los va a estar copiando de aquí, 00:54:53
sino que lo va a estar copiando de aquí. 00:54:57
Lo pondría aquí en el 50.000 NOA 00:54:59
y luego la edad sería el 40.000 00:55:00
y la IEDAD a copiarlo en la edad del nuevo. 00:55:07
Con lo cual tendríamos aquí un 10. 00:55:10
Constructor copia. 00:55:14
¿Se entiende? 00:55:17
Más o menos. 00:55:18
Miren el chat, a ver si me decís alguien algo por ahí. 00:55:21
Bueno, pues, a ver, al final yo os voy contando, 00:55:33
bueno, me preguntan para la grabación 00:55:37
que qué sentido tiene poder hacer la copia al final os voy enseñando aquí un poco herramientas 00:55:39
que luego bueno pues pueden pueden ser útiles en algún momento no sé al final hay que hay que 00:55:46
buscar enunciados donde pueda esto tener sentido decir ah pues me viene bien utilizar un constructor 00:55:54
copia. Imaginaros que estamos aquí en clase y tenemos lo que es personas son los alumnos y 00:55:59
resulta que todos los alumnos tienen en lugar de dos parámetros como aquí pues tienen 15 parámetros 00:56:11
y de esos 15, 13 son comunes podrían ser. Pues bueno podríamos utilizar dar de alta 1 aquí y 00:56:18
luego utilizar el constructor copia y hacer las pequeñas modificaciones sobre el nuevo que 00:56:27
correspondiese o yo que sé imaginaros que no sé a ver qué deciros imaginaos que es una clínica 00:56:31
veterinaria y estamos dando de alta cachorros de que tiene pues no sé una mamá perrito no y tiene 00:56:45
10 cachorros y en el mundo de en el momento de partida pues todos los consideras con los mismos 00:56:55
datos. Pues bueno, pues podrías dar de alta uno de los cachorros y luego 00:56:59
dar de alta 10 objetos nuevos, utilizando el 00:57:04
constructor copia, para que los 10 cachorros en ese momento inicial al menos 00:57:07
tuvieran todos el mismo valor. Y luego ya, bueno, pues según vaya evolucionando 00:57:11
el programa, pues a lo mejor alguno irá cambiando sus datos, como podría ser 00:57:16
aquí miper2.el, la edad, pues si cambia de 1, pues cambiarlo 00:57:20
a 15. En este caso ya sobreescribiríamos 00:57:24
la edad que tenía en el constructor copia los constructores son una inicialización de 00:57:27
el objeto según lo estás creando y bueno pues puede ser que en un momento dado fijaros que 00:57:33
sobrecargados tenemos mil alternativas de poner constructores uno que no tenga ningún dato bueno 00:57:40
pues ya se irán rellenando sus parámetros según vaya evolucionando el programa podemos tener 00:57:46
algunos, según nuestro enunciado, que 00:57:51
tenga todos los datos, que 00:57:53
vendría a ser como un constructor copia, pero en lugar de pasar la referencia 00:57:57
pasar todos los datos. Podríamos tener algún constructor 00:58:00
que tuviera un conjunto 00:58:03
de parámetros que no fuesen todos ellos, pero 00:58:05
unos cuantos. Y el definir uno, 00:58:09
dos, diez o los que sean, pues irá 00:58:12
en función a lo que nos demande el enunciado. 00:58:15
Y en un momento dado, pues a lo mejor podría ser que 00:58:18
de unos como base queramos sacar copias para no tener que estar rellenando todos sus parámetros 00:58:20
de golpe pues bueno de partida en el momento inicial aquí es una copia exacta todos sus 00:58:27
parámetros pero a partir de aquí el programa pues podría ir evolucionando cambiando ciertos 00:58:33
parámetros según lo vayamos necesitando y entre todos ellos pues bueno hay tres que se definen 00:58:38
digamos que se les ponen nombres y apellidos porque sí que son siempre iguales el de por 00:58:45
defecto, que es el que no recibe parámetros, el constructor 00:58:49
copia, que es el que recibe una referencia para hacer una copia exacta 00:58:53
de todos sus atributos en el nuevo objeto con el que recibimos por aquí, y el 00:58:57
completo, que en principio se utiliza un poco para lo mismo, pero en lugar de pasar 00:59:01
una referencia a un objeto, pues se le 00:59:05
pasan todos los atributos. 00:59:09
Mirad, más cosillas que os 00:59:24
voy contando. Cuando nosotros estamos definiendo en una clase 00:59:27
su asignatura o su cabecera, típicamente aquí los constructores 00:59:33
no, ahora después llegamos a los constructores. Aquí, bueno, 00:59:40
pues ponemos, ponemos public y ponemos aquí algo. Hasta ahora 00:59:43
casi siempre suele ser el void. Fijaros que main también tiene 00:59:48
void aquí. Los métodos, a la hora de salirnos de un método, 00:59:51
¿Cuándo termina un método? 00:59:57
En el que ponemos aquí la etiqueta void 01:00:00
Pues cuando se realiza toda su ejecución 01:00:02
Y existe la posibilidad de 01:00:04
Utilizar la etiqueta return 01:00:06
La etiqueta return lo que hace es 01:00:09
Me salgo del método 01:00:10
Donde la encuentre 01:00:12
De hecho, si yo pongo aquí 01:00:13
System.out.println 01:00:14
Fijaros que Eclipse me dice 01:00:17
Oye, mira, esto no tiene ningún sentido 01:00:23
Esto que estás haciendo 01:00:24
Porque has puesto aquí una instrucción 01:00:25
Y este código es código muerto 01:00:27
Aquí el programa nunca va a llegar 01:00:28
porque se encuentra antes un retorno esto si quiero que me compile pues bueno pues podría 01:00:30
poner aquí y y igual a 2 poner aquí y y es igual a 2 fijaros cada día si me compila y en cualquier 01:00:35
caso este código según está puesto ahora mismo esto nunca se ejecutaría porque se cumple este 01:00:57
if y siempre se va a salir por el return pero ya el compilador de java o eclipse no se fija en este 01:01:01
caso no se preocupa de evaluar esto sino que ya ve que sí que hay alguna alternativa porque hay 01:01:09
un if y este return está dentro de una estructura de selección con lo cual podría no ejecutarse 01:01:14
siempre imaginaos que esto en lugar de cogerlo por aquí lo estuviéramos cogiendo con un escáner 01:01:20
el valor de i, pues una vez podríamos meter un 2 y otra vez podríamos meter un 5 01:01:25
entonces como ya no siempre sale por el return 01:01:30
esta instrucción podría haber, aunque en este código sí que pasa 01:01:33
tal cual está porque siempre iba a valer 2 si no lo modificamos 01:01:38
pero imaginaos, ya os digo que no, imaginaos que 01:01:41
este código lo tenemos aquí y en lugar de si ponemos iValor 01:01:44
pues aquí ya se da un caso en el que no siempre iValor puede valer 2 01:01:59
porque dependerá del dato que hayamos puesto nosotros cuando hayamos 01:02:05
hecho la llamada, una vez será 2 y otra vez será 10, entonces no siempre 01:02:09
saldría por aquí, ya habría opción de que esto se ejecutase, con lo cual ya me compila 01:02:13
pero resulta que si este valor es cierto, esto no va a suceder 01:02:17
esto se va a salir con el return y no va a pasar por aquí, vamos a hacer 01:02:21
esa ejecución, vamos a poner mi per 01:02:25
punto saludar, ponemos aquí un 2 01:02:30
y lo vamos a poner aquí, un 3. 01:02:36
Vamos a hacer dos llamadas, una que vale 2 y otra que vale 3. 01:02:39
Entonces, la que vale 2, vamos a mostrar aquí el valor. 01:02:43
Una vez valdrá iValor2 y otra vez valdrá iValor3. 01:02:53
Cuando valga 2, se va a salir, y cuando valga 3, no se va a salir, 01:02:58
nos va a mostrar también este mensaje. 01:03:01
Entonces, hacemos esa ejecución, ahí lo tenéis. 01:03:06
Cuando vale 2, nos ha mostrado este iValor2, 01:03:08
pero como era 2, se ha salido con el return y nos ha mostrado este mensaje. 01:03:14
Cuando valía 3, me ha mostrado el 3 y luego me ha mostrado el mensaje. 01:03:17
Es decir, return nos saca de la instrucción, nos saca del método. 01:03:23
No es muy aconsejable poner returns por ahí entre medias del código. 01:03:28
Una vez dicho su función de return, poner returns por aquí por la mitad del código, 01:03:33
porque si este código es muy largo y hace muchas cosas, una cosa así tan sencilla, 01:03:38
podemos perder la referencia de los puntos de salida de los métodos entonces se suele aconsejar 01:03:43
evitar el uso de return así tal cual y que y provocar que el método termine siempre al 01:03:48
finalizar aquí en este en este espacio eso es la recomendación general cuando éste cuando el 01:03:57
método indica que devuelve void quiere decir que este método no devuelve nada es decir cuando lo 01:04:06
llamamos, no se espera ningún retorno 01:04:13
de él. Claro, si ponemos aquí un tipo int, 01:04:17
podríamos poner cualquier tipo, tipos primitivos o tipos referenciados, lo que 01:04:21
pretende decirnos es que saludar va a devolver 01:04:25
aparte de hacer lo que tenga que hacer por aquí, recibiendo información 01:04:29
como variables locales aquí entre paréntesis, va a ser capaz de 01:04:33
devolver un dato, un dato que será de tipo entero 01:04:37
Y para que devuelva algo, utilizamos el método return, pero en este caso no nos vale un return sin ningún dato, porque se espera que retorne, que devuelva un valor entero y se lo tenemos que indicar aquí. 01:04:40
Entonces vamos a poner aquí un 1, ¿veis? Ahora ya me compila. Devuelve un 1. ¿Qué hará esta instrucción? Aparte de sacarnos del código, devuelve un 1. Ahora vemos dónde capturamos este 1. 01:04:57
típicamente igual que antes con el consejo que os daba el return es que los return aparezcan al 01:05:09
final del método no en cualquier sitio por el intermedio para que no se nos salga de un método 01:05:16
en sitios que sea más difícil de localizar el por qué se ha ido cuando estemos haciendo un 01:05:22
mantenimiento o un testeo del programa este return que es un entero aquí se captura justo en el sitio 01:05:27
de llamada y lo devuelve la llamada hacia la izquierda. 01:05:35
Es decir, nosotros aquí estamos llamando 01:05:40
al método. Fijaros, estamos llamando al método 01:05:41
que recibe como parámetro un entero 01:05:44
que corresponde a este, con lo cual el que nos está ejecutando es este. 01:05:45
Antes teníamos aquí void que no devolvía nada 01:05:51
pero ahora hemos dicho que devuelve un entero. 01:05:53
Y si ya le decimos que devuelve un entero, es obligatorio meter una instrucción 01:05:56
return para que nos compile. 01:05:59
Y es necesaria una instrucción return 01:06:02
junto con un valor del tipo que hayamos indicado aquí en la cabecera 01:06:05
que devuelve. Si ponemos ahí un return1, ya le va gustando. ¿Por qué? 01:06:10
Porque un 1 es un valor de tipo entero. 01:06:15
Esto que devolvemos, ¿dónde lo tenemos? Pues lo obtenemos 01:06:19
en la llamada y es como si lo ejecutase y lo devolviese hacia la izquierda. 01:06:23
Entonces, si yo pongo aquí un int y 01:06:28
valor devuelto, una vez que se ejecute este, 01:06:31
hace la llamada para el método saludar del objeto 01:06:37
miper, hará todo el código que sea 01:06:42
en el momento en el que hace un return, con lo cual termina el método y devuelve un 1 01:06:45
tipo entero, valor que lo devuelve 01:06:49
en la llamada hacia la izquierda, con lo cual lo estoy cargando en esta variable 01:06:56
yo podría poner aquí un system.out.println 01:07:00
valor devuelto, entonces si yo ejecuto 01:07:04
ahora, ¿veis? Valor devuelto, 1, 1. Este valor devuelto 01:07:24
es como consecuencia de este, ¿y por qué me ha puesto aquí 01:07:32
1, 1? Porque lo que ha cargado y valor, que es lo que me ha devuelto, saludar 2. 01:07:36
Imaginaos que este saludar, en lugar 01:07:43
de ser un método saludar, pues fuese algo que 01:07:47
bueno, algo que tiene alternativas, ¿no? Imaginaos que 01:07:50
estamos intentando pedir nombres, imaginaos que 01:07:54
estamos pidiendo nombres por teclado y pues con el escáner hacemos la solicitud y hay un 01:07:59
momento en el que decimos y si el nombre este en este nombre que no voy a ponerme no voy a 01:08:05
poner por teclado por no andar enredando porque ya lo conocemos imaginaos que lo estamos cogiendo por 01:08:13
ejemplo por teclado vale una varía y lo cargamos en una variable ponemos aquí que se puede recibir 01:08:17
a Ana en un caso y en otro caso se pueda recibir Mila, por ejemplo. 01:08:24
Entonces podríamos decir, sí, ya os digo que aquí lo he puesto 01:08:32
de esta forma, pero aquí podríamos poner un escáner para que esto 01:08:36
fuera variable entre los nombres que se fueran metiendo. 01:08:39
Entonces pusiéramos aquí, si ese nombre, punto, equals a Ana, 01:08:43
aquí podríamos hacer lo que tocase con Ana, guardarlo en una base 01:08:53
de datos, en un fichero, hacer el procesamiento que fuese, 01:08:56
pero podríamos querer que aparte de hacer lo que fuese 01:08:59
por aquí, que desde el sitio donde se llama 01:09:03
fuésemos capaces de saber si se ha devuelto Ana o se ha escrito 01:09:07
Ana o se ha escrito Mila, pues entonces podríamos coger e identificarlo 01:09:11
de esta forma, es decir, en ese caso return un 1 01:09:15
un 1 es un código que estamos asociando a Ana 01:09:20
else, si no 01:09:24
un return de un 2 01:09:28
y un 2 podría ser un código que 01:09:31
estuviésemos asociando a Mila 01:09:33
fijaros que ahora como hay 01:09:35
dos return aquí 01:09:39
en una instrucción 01:09:40
de selección 01:09:43
y no hay más alternativas que estar 2 01:09:45
esto vuelve a no compilarme, ¿por qué? 01:09:47
porque dice aquí este código es muerto, aquí nunca va a llegar 01:09:49
el código, vamos a quitarlo de momento 01:09:51
entonces aparte de hacer aquí lo que quisiésemos 01:09:53
porque es Ana y porque es Mila 01:09:58
pues a lo mejor guardar 01:10:00
en un fichero hola, porque Ana 01:10:01
siempre dice hola. Y en este caso podríamos guardar en un fichero adiós, porque 01:10:07
Mila siempre se despide. Aparte de eso, puede ser que 01:10:11
esas son las acciones que queremos que pasen aquí en el método saludar, pero puede ser que 01:10:15
aquí, según haya sido uno u otro, haya sido Ana o Mila, 01:10:19
podemos coger y decir, mira, queremos que pasen también cosas. Entonces aquí podríamos hacer 01:10:23
una valoración de if y valor de if 01:10:27
es igual a 1, entonces sé que ha sido Ana 01:10:30
y si no, si no es 1 es porque será 2 01:10:35
en este caso no hay más alternativas porque saludar solo devuelve eso 01:11:00
entonces vamos a hacer una ejecución con Ana, dato que podríamos por ejemplo 01:11:04
estar cogiendo el de teclado, aquí lo tenemos puesto a fuego digamos en la variable 01:11:14
entonces hacemos una ejecución con Ana, pues fijaros como 01:11:19
nos dice aquí ha sido Ana, y si en cambio 01:11:22
ponemos aquí que sea mila, pues nos dice así dos mila 01:11:26
es decir, gracias al valor devuelto por un método 01:11:36
que lo devuelve con el método, con la instrucción 01:11:41
return y en el sitio de la llamada lo devuelve 01:11:45
hacia la izquierda una vez que termina, aquí ponemos una variable del mismo tipo que devuelve 01:11:49
pues lo podemos capturar y aquí seguir haciendo un procesamiento 01:11:53
en función de lo que haya pasado aquí, algo muy típico pues imaginaros que 01:11:57
más que aquí el ejemplo este de Mila y Ana, pues imaginaros 01:12:01
que esto es insertar en base de datos 01:12:05
un dato, una información. Pues durante la 01:12:08
inserción en la base de datos, para ver si se queda registrado, 01:12:11
puede ser que de repente no haya acceso a la base de datos 01:12:14
y no se puede hacer. Pues a lo mejor nos devuelve en ese caso el método 01:12:17
en este int que he puesto un 1 para Mila 01:12:20
y un 2 para Ana, pues nos puede devolver el código 65 01:12:23
que es imposibilidad de acceder a la base 01:12:26
de datos y el código 66 que es 01:12:29
vamos, que podría ser según 01:12:32
tuviéramos definido en 01:12:35
una serie de posibles errores 01:12:36
al acceder a la base de datos, el 66 que pudiera ser 01:12:41
no tienes privilegios para insertar registros 01:12:44
en la base de datos y a lo mejor el código 0 cuando ha ido bien 01:12:47
pues entonces, si de la llamada 01:12:50
al método, en este caso saludar, que sería 01:12:53
insertar en base de datos, aquí nos devuelve 01:12:56
un cero, pues podemos decir el proceso ha ido correcto 01:12:59
y si nos devuelve un valor distinto, pues a lo mejor podemos 01:13:02
no seguir haciendo ciertas operaciones que vendrían 01:13:05
a continuación de haber hecho esa inserción en la base 01:13:08
de datos. Aquí, fijaros que antes os he dicho 01:13:11
no es muy aconsejable ir poniendo returns 01:13:16
por ahí por el código. ¿Cómo sería la forma correcta 01:13:19
para intentar evitar que esto pasase? 01:13:22
Poner un solo return al final que es 01:13:26
lo que está más aconsejado, pues mirad lo que podríamos hacer es lo siguiente 01:13:28
para poner un solo return y tener la garantía de que se nos va a ir 01:13:33
justo antes de finalizar el método, lo que podríamos hacer aquí 01:13:36
es definir una variable aquí int i result del mismo 01:13:40
tipo que el que tenemos aquí y aquí en lugar de ir haciéndolo return 01:13:46
pues hacer aquí un i result igual a 1 01:13:51
que es el que identifica en este ejemplo que ha sido 01:13:55
ana y poner aquí un irresult 01:13:58
igual a 2, ahora no nos compila, fijaros que no nos compila ahora mismo 01:14:01
el método, ¿por qué? porque esperamos que devuelva un entero 01:14:07
y como no estamos con un return devolviendo un entero, pues no se queja, pero 01:14:10
lo que vamos a poner aquí es un return de irresult y así 01:14:14
conseguimos que solamente hay un return en todo el método, vamos guardando el valor 01:14:20
que luego vamos a devolver en una variable que podemos definir aquí en la cabecera 01:14:24
del método, en la parte de arriba, y luego hacer un return de esa variable. 01:14:28
Igual que aquí estamos devolviendo un int, cuando no nos interesa que un método devuelva nada, 01:14:37
simplemente queremos su gestión, lo que tenga que hacer por aquí según su algoritmo, 01:14:42
pero que no devuelva nada, porque no hay nada pendiente que hacer según le haya ido al método, 01:14:47
pues en ese caso es cuando utilizamos la etiqueta void. 01:14:52
Y si en lugar de devolver un entero queremos que devuelva otro tipo de datos, 01:14:57
pues puede ser otro tipo de datos puede haber un método saludar que devuelve un string pues entonces pondremos aquí 01:15:01
public 01:15:07
string 01:15:09
saludar vamos a poner esta string 01:15:10
en este caso lo que devolvería sería un string y ahora ha dejado de compilarme porque lo que estoy devolviendo aquí es un tipo de 01:15:18
datos numérico cuando lo que le he dicho aquí en la 01:15:26
cabecera en la firma del método es que se espera que devuelva un string 01:15:29
bueno en este caso si es lo que nos interesa se podríamos poner aquí un string ese result un 01:15:33
poco llevando la misma funcionalidad de antes no entonces esto tendría que devolver tendría 01:15:46
que ser una variable de este tipo string y luego devolveríamos aquí ese resulto y un método puede 01:15:53
devolver tipos primitivos o puede ahora este no le gusta aquí porque ya esto como devuelve un 01:16:06
string y estoy cargando un entero pues ya dice que no vamos a poner esto para que compile si 01:16:13
no pongo nada aquí a la izquierda de la llamada que supone pues que el método en verdad devolverá 01:16:24
el string en este caso el entero antes pero como no lo capturó por aquí en ningún sitio pues como 01:16:29
que se pierde y luego también podríamos tener la posibilidad de devolver tipos referenciados 01:16:35
Esto en realidad podría devolver una referencia a una persona. Imaginaos que estamos en un contexto en el que es un club de patinaje y es un método donde damos de alta a nuevos socios. 01:16:45
entonces este método podría ser el método de dar de alta, por aquí podríamos ir 01:17:04
recuperando todos los datos que iríamos cargando en un objeto de la clase 01:17:08
persona y luego el return nos podría devolver 01:17:12
ese objeto, entonces estaríamos devolviendo en lugar de un entero o un string 01:17:17
como antes, estaríamos devolviendo una referencia a una persona 01:17:20
para asignársela a una persona que hayamos dado por aquí de alta, sería una 01:17:24
referencia parecida a la que estábamos pasando aquí como parámetro de entrada 01:17:30
la posición de memoria de una persona que se ha creado en ese caso 01:17:34
dentro del método, la estoy devolviendo para que esté disponible 01:17:39
desde el sitio donde se llamó, es decir, digamos la operación inversa 01:17:43
lo que hemos hecho cuando lo hemos pasado como parámetro. Aquí 01:17:47
una persona de alta en el ámbito este del main 01:17:50
se lo estábamos pasando para que estuviera disponible su posición de memoria 01:17:55
y poder trabajar con ella dentro del método. Y lo otro 01:17:59
si devolvemos con el return una referencia a una persona, lo que estamos haciendo es dar de alta a la persona en el método y con el return devuelvo la posición de memoria para que pueda estar disponible desde donde se llama. 01:18:03
en este caso sería desde el main, si se entiende, por ahí bien, mira si nos venimos aquí al método 01:18:18
main tenemos aquí un touch un poco grande de información y de etiquetas aunque de bastante 01:18:39
ya hemos ido hablando, fijaros main que lo hemos escrito muchas veces hasta ahora pero no habíamos 01:18:51
no nos habíamos parado a repasarlo es un método que devuelve void, como devuelve void fijaros que 01:18:56
cuando ponemos por aquí el main nunca tiene un retorno es necesario podríamos poner un 01:19:03
retorno cuando cuando no devuelve nada puedes poner el retorno y le vale o no ponerlo y ya 01:19:08
está y cuando llega aquí termina si devuelve algo no nos vale no poner retorno obligatoriamente 01:19:15
tenemos que poner un retorno con el tipo de datos entonces main es un boite fijaros como el método 01:19:20
main para su ejecución recibe aquí una información 01:19:26
que será, en este caso es 01:19:29
args es un array 01:19:34
de cadenas de caracteres. Entonces 01:19:37
args será una variable de este tipo, como 01:19:40
decimos, array de cadenas de caracteres que estará disponible como 01:19:43
variable local dentro del ámbito del main, 01:19:46
es decir, entre esta apertura de llave y este cierre. 01:19:49
Lo mismo que decíamos aquí. 01:19:53
Ese saludo, en este caso era un string disponible 01:19:57
como variable local en el ámbito de este método saludar, entre su apertura 01:20:00
y cierre de llaves. En estos métodos, saludar 01:20:03
cuando cargábamos este dato, lo cargábamos en el momento en el que hacíamos la llamada 01:20:10
a saludar, que era tal que por aquí, en estos ejemplos 01:20:14
que teníamos por aquí. Aquí llamamos al método saludar y en la llamada le pasábamos 01:20:18
el dato que se va a cargar como 01:20:23
la información que se va a cargar en esta variable, que es una variable local a la ejecución del 01:20:26
método. En main, exactamente lo mismo. Aquí tenemos una variable que se carga en el momento en el que 01:20:30
main es llamado. Lo que pasa es que el main, justo como es el punto de entrada del programa, no es código 01:20:38
que pongamos nosotros para llamar, sino que directamente se llama en el momento en el que se invoca el 01:20:44
programa. Con lo cual, ¿en qué momento ARS-S cogerá información para su ejecución? Pues la coge en el 01:20:49
momento en el que estamos lanzando su ejecución y en alguna práctica anterior creo que habíamos 01:20:56
hablado que si nosotros venimos aquí a invocar la llamada a nuestro programa vamos al word 01:21:03
escape base de eclipse como hemos dicho otras veces vamos al ejercicio con el que estamos entre 01:21:16
manos tema 4 ls dentro del proyecto tema 4 tenemos en src los códigos fuente los puntos java y en el 01:21:20
los ejecutables. Fijaros que tenemos la clase inicio 01:21:29
y la clase persona, con su extensión .class 01:21:35
que si intentamos visualizarlo, more es un comando 01:21:38
de Linux que nos muestra sin editar los ficheros 01:21:42
si ponemos more persona.class, pues fijaros como 01:21:46
es bytecode, una vez el código ya compilado no se ve exactamente 01:21:49
el mismo código que tenemos aquí escrito. Entonces si nos venimos aquí 01:21:54
voy a comentar todo el código del main, ahí está 01:22:01
todo el código comentado, para que solo tener esto que ponemos, entonces si ponemos 01:22:16
aquí un system.out.println de rs 01:22:20
0, se llama inicio 01:22:26
fijaros, entonces el bytecode de la clase inicio.java 01:22:35
pues será inicio.class, llamamos a java, inicio 01:22:40
y me da un error, ahora os cuento el error, si yo pongo 01:22:43
inicio hola, fijaros como me muestra por pantalla hola 01:22:49
que he mostrado, la posición 0 01:22:53
del array RS, que se ha cargado en la posición 0 del array RS 01:22:57
se ha cargado este parámetro 01:23:01
que le he pasado cuando he llamado al programa, si yo pongo 01:23:05
java inicio hola adiós 01:23:09
y también muestro la posición 1 del array RS 01:23:15
que es, recordad, ars es un array de strings 01:23:22
salvo por aquí el programa para que me actualice el 01:23:26
bytecode, entonces fijaros como ya me muestra hola y adiós, este hola corresponde 01:23:32
a la posición 0 del array, esta 01:23:36
y este adiós corresponde a la posición 1, si yo ahora aquí, si yo hago 01:23:39
una ejecución en la que pongo esto, quitando el adiós 01:23:45
me muestra el hola, la posición 0 y me da 01:23:49
un error, que es cuando intenta acceder a la posición 1 del array 01:23:53
¿por qué no existe la posición 1? pues porque no le he pasado un segundo parámetro, esto ha cargado 01:23:57
en el arc S0 y en el arc S1 no ha cargado a nadie 01:24:01
que es lo que me había pasado aquí cuando hice un Java 01:24:04
inicio, porque hice este Java inicio 01:24:09
y me di un error intentando acceder a la posición 0 del programa 01:24:12
es decir, ¿en qué momento se llama el método 01:24:18
main, se llama el método main cuando intentamos arrancar el programa, que es el momento 01:24:25
cuando se ejecuta cualquier método, es el momento en el que 01:24:31
estas variables que tiene por aquí entre paréntesis se cargan con información 01:24:34
por aquí hemos cargado constructores con 01:24:39
información cuando hemos hecho la llamada al constructor, por aquí hemos 01:24:43
cargado con un string una variable del método saludar 01:24:47
el que está sobrecargado con un string cuando hemos hecho la llamada, en el momento que llamábamos 01:24:51
a ejecutar a saludar le pasamos por aquí el dato esto cuando se cargará pues se cargará en el 01:24:55
momento que llamemos al main pero es que el main no lo llamamos nosotros desde código sino que se 01:25:02
llama en el momento en el que lanzamos el programa como estamos haciendo por aquí si no queréis venir 01:25:05
para probar esto al terminar y lanzar el programa también ya lo vimos un día a ver si me acuerdo 01:25:12
estaba en como verás configuration saber era aquí si miras aquí para hacer esto mismo que 01:25:21
he hecho de pasarle parámetros a la ejecución del main a la ejecución del programa es decir 01:25:31
en la llamada al main parámetros que se cargan en ars 0 y en ars 1 para hacer esta simulación 01:25:37
desde Eclipse, pues nos podemos venir 01:25:43
aquí a la opción 01:25:45
de menú run 01:25:47
cobreis configurations 01:25:48
y aquí 01:25:51
aparece la opción arguments 01:25:53
entonces aquí en arguments 01:25:55
podemos poner los argumentos 01:25:57
este hola y adiós 01:26:01
corresponden justo 01:26:03
a este 01:26:05
hola y adiós que os he puesto 01:26:06
aquí, más allá de la llamada 01:26:09
entonces si yo digo aplicar 01:26:11
close si yo ahora hago una ejecución aquí de 01:26:15
eclipse fijaros como demuestra ese o la que es el que puesto ahí porque solamente 01:26:19
puesto ahora aquí el ars s les comento también este otro y me 01:26:23
saldría el ola y adiós este ola y adiós son estos dos argumentos que he puesto 01:26:29
aquí cambió por dos y ya me hice ola y dos bien entonces tenemos en el main 01:26:39
tenemos, en este caso es void, podría, main 01:26:54
tiene esta cabecera, es decir, es inamovible, tiene que ser 01:26:58
así, pero para cualquier otro método equivalente al void 01:27:02
podríamos tener un int, un string, un tipo referenciado 01:27:06
otro día lo volvemos a dar a lo mejor otra vuelta 01:27:10
luego está la etiqueta estática de aquí en el main, de esta os he hablado 01:27:13
también en diferentes tutorías, cuando cosas 01:27:18
se definen de forma estática, primero 01:27:22
os cuento sin el static. Cuando una clase 01:27:26
no es estática, pues tenemos 01:27:30
podemos definir diferentes objetos de esa clase 01:27:33
y el acceso, bueno, las cosas estáticas en líneas generales 01:27:38
es que con lo que mejor se entiende el término estático es con los parámetros. 01:27:42
Las cosas estáticas en líneas generales es que están compartidas 01:27:46
por todos los objetos de una clase 01:27:51
entonces si yo 01:27:53
el main 01:27:55
no era una clase, era un método 01:27:57
pero se entiende mejor para los 01:27:59
parámetros, si yo pongo aquí 01:28:01
un public, fijaros 01:28:03
static 01:28:04
y valor, vamos a poner 01:28:06
int 01:28:11
de tipo entero, fijaros 01:28:13
este static para este 01:28:18
valor lo que supone, voy a borrar por aquí 01:28:20
vamos a crear 01:28:24
una primera persona. Fijaros que aquí en la clase 01:28:26
de persona he mantenido la edad como un parámetro 01:28:47
de tipo entero que no es estático y valor lo he mantenido 01:28:51
como un tipo entero pero estático. Entonces yo pongo aquí miper 01:28:55
punto y valor igual a 15. 01:29:00
De fin, una segunda persona y para esta segunda persona 01:29:10
digo que tengo una edad 20 y el valor le voy a decir que sea 25. 01:29:14
y ahora pongo aquí un system out 01:29:20
.println 01:29:23
y vamos a poner estos dos datos 01:29:25
de mi per 01:29:29
voy a poner aquí unos espacios 01:29:30
y el segundo 01:29:36
de los datos 01:29:39
mi per y valor 01:29:40
y vamos a hacer lo mismo para la segunda 01:29:42
de las personas 01:29:51
entonces si yo ejecuto aquí 01:29:52
mira lo que pasa 01:29:57
en principio si nosotros vemos 01:29:59
que estamos mostrando aquí mi per, la edad y mi per, valor 01:30:05
lo que nos hace pensar es que la edad, si la hemos asignado a 10 01:30:09
nos va a mostrar un 10 y el valor nos va a mostrar un 15 01:30:13
pero esta primera línea nos dice que es 10 y 25 01:30:16
y en este segundo caso, mi per y edad y mi per y valor 01:30:19
pensamos que nos va a devolver 20 y 25 01:30:25
que efectivamente es correcto lo que hace, pero lo que nos chirría 01:30:28
un poco es aquí, porque aquí no nos muestra un 15, pues bueno, volvemos 01:30:33
a hablar un poco de lo que es las zonas de memoria, cuando 01:30:38
nosotros hacemos un new aquí para mi pair, si este tiene la posición 01:30:41
30.000, el reserva con el new espacios de memoria 01:30:46
para sus atributos, pero no se preocupa de aquellos atributos 01:30:50
que son estáticos, en este caso reservaría un espacio 01:30:55
de memoria a partir de la 30.000 para el ese nombre y la iedad 01:30:58
ese nombre e iedad. En este caso, para miper2 01:31:01
en la 40.000, reservaría para esa segunda persona 01:31:12
espacio para ese nombre y para la iedad, igualmente 01:31:18
y en forma global para todas las personas, no para esta 01:31:22
ni para esta otra, se fijaría en aquellos que son estáticos 01:31:26
y para la clase persona, pero no para un objeto en particular, sino en línea 01:31:30
en general, y de forma compartida, reservaría 01:31:34
espacio de memoria, vete a saber en qué posición 01:31:38
el sistema operativo, vamos a poner aquí la 80.000 01:31:42
para aquellos atributos que sean estáticos, que en este 01:31:45
caso es iValor. Y estos atributos, al ser 01:31:50
static, que podríamos decir que es igual 01:31:55
a compartidos, estos atributos tienen una única posición de memoria 01:31:59
para todos los objetos. Entonces cuando 01:32:05
yo asigno aquí a iedad el valor de 10 01:32:08
como iedad no es estático, se irá a su posición de memoria 01:32:12
aquí y cogerá y me pondrá un 10 aquí. 01:32:16
Cuando yo voy a mi per, que es una persona 01:32:23
y valor y le asigno un 15, fijaros como por ser 01:32:25
estático no hemos hecho reserva de memoria aquí, sino que se ha hecho para la persona en su conjunto. 01:32:29
Entonces cogerá y se vendrá aquí al ser estático y pondrá 01:32:33
un 15. Si yo ahora cojo y asigno 01:32:37
un 20 aquí, como iedad no es estático 01:32:44
y cada uno de los objetos tiene su zona de memoria 01:32:46
lo que nos hará es aquí en esta iedad 01:32:49
cogerá y pondrá un 20. Pero si yo 01:32:52
me voy aquí y asigno a iValor 01:32:57
que es un parámetro estático de la clase persona 01:32:59
el valor 25, como no tenemos 01:33:03
para cada uno de los objetos ese iValor, donde se irá 01:33:06
a la zona global de la clase 01:33:09
persona, entonces, que es esta 01:33:12
y que está compartida. Entonces, este 01:33:14
15 lo estará sobrescribiendo a 25. 01:33:16
Y perdemos 01:33:20
el 15 que habíamos puesto aquí. 01:33:20
Bueno, decimos, lo perdemos. 01:33:23
Bueno, es que a lo mejor es lo que nos interesa 01:33:24
según el enunciado del ejercicio. 01:33:26
Si todos tienen, 01:33:28
imaginaos que tienes, 01:33:31
vamos a hacer una exageración de dato, 01:33:32
pero un millón de personas que 01:33:34
todos pertenecen a 01:33:36
a Dan, vamos a decir, 01:33:38
a nuestra clase 01:33:40
de DAM. Todos ellos. 01:33:42
Y además un poco exagerado 01:33:45
con lo del millón de personas, pero bueno, 01:33:46
para que sea más ilustrativo. 01:33:48
Si tuviéramos que cambiar 01:33:50
el nombre de ese millón de personas, como 01:33:51
cada uno tiene su nombre, no nos quedaría más remedio 01:33:54
que ir uno a uno y cambiar su nombre. 01:33:56
Porque sería una variable de este tipo, de cada uno 01:33:58
de los objetos, de cada una de las instancias. 01:34:00
Pero si lo que queremos es 01:34:03
cambiar el que pertenece 01:34:04
en a DAM, porque ahora 01:34:06
desde la consejería de educación nos dicen que en lugar de 01:34:07
DAM sea DAN, pues sin necesidad 01:34:11
al ser un dato común a todos ellos de ir 01:34:15
a ese millón de objetos y hacer el cambio de DAM a DAN 01:34:17
como es común, pues iríamos a la variable estática 01:34:20
y con un único cambio quedarían automáticamente 01:34:23
todos actualizados, que es lo que nos ha sucedido aquí con 01:34:26
IVALOR. Como consecuencia de que 01:34:29
IVALOR, aquí pusimos 15 para mi PER 01:34:32
pero luego hemos puesto aquí 25 01:34:35
es actualizado, cuando aquí estoy mostrando y valor para mi per 01:34:37
como la zona es común, el dato que tiene es 25 y como consecuencia 01:34:41
nos muestra aquí este 25, entonces esta es la información de los datos 01:34:46
como funcionan los atributos que definimos 01:34:51
como estáticos, de igual forma los métodos también 01:34:55
pueden ser estáticos, en realidad cuando definimos 01:34:59
un objeto y ponemos un método como el de saludar 01:35:03
que no sea estático, lo que hace es 01:35:06
que cada uno de los objetos tendrá su propio método saludar 01:35:09
y si aquí ponemos static, como le sucede al main 01:35:14
pues será un método común para todos los objetos y llamará justo 01:35:17
la misma zona de código compartida entre todos 01:35:22
la misma idea que para los parámetros, lo que pasa es que con los parámetros el ejemplo 01:35:25
se ve muy claro haciendo una cosa así de este estilo 01:35:30
Pero si nosotros cogemos y ponemos aquí y edad igual a 45, ¿qué nos pasa? Que esto no nos compila. Y no nos compila, volvemos un poco a lo mismo que con la sobrecarga hablábamos de las ambigüedades. 01:35:32
si yo pongo aquí y edad, pensando en una persona 01:35:53
me dirá, muy bien, pero ¿qué persona, la edad 01:35:57
de qué persona quieres cambiar? Tú date cuenta que si es la edad del miper1 01:36:01
me tengo que ir a la posición que cuelga del 30.000 para cambiarlo. Y si es 01:36:04
de miper2, cuelga del 40.000. Entonces 01:36:08
como no seas más preciso, yo no te dejo compilar porque no es un 01:36:12
parámetro estático y no sé a quién tengo que cambiar. Entonces, si 01:36:16
yo cojo y pongo aquí mi per 2 punto y edad ya me compila porque ya no hay ambigüedades mi per 2 01:36:20
empieza en la posición 40.000 y la edad está aquí pues lo que estoy haciendo es cambiar este dato 01:36:28
a 45 cambio los datos estáticos me permiten hacerlos de esta forma poner en lugar de un 01:36:32
objeto persona punto fijaros cómo me ofrece el y valor para cambiarlo un dato que es estático 01:36:41
lo puedo cambiar a través de cualquiera de sus 01:36:50
objetos, aunque siempre van a actuar sobre la misma posición de memoria, el cambio va a ser 01:36:54
común a todos, o a través de la clase total, si solo tengo una posición 01:36:58
de memoria, no hay ambigüedades, de nuevo, pues te lo permito. Entonces, en este caso, 01:37:02
lo que me haría sería el 55. Pero fijaros cómo 01:37:06
a través de la clase persona, punto, no me da la opción 01:37:09
de cambiar una edad, porque me diría, no, eso no es un dato estático, no es común 01:37:17
a todas las personas, no tengo ni idea de qué persona 01:37:20
quieres cambiar la edad. En este ejercicio es miper y miper2 01:37:23
pero podrían ser muchos otros. Para acceder a 01:37:26
datos con independencia de los estáticos 01:37:34
de cualquier clase, necesitamos 01:37:37
definir un objeto. Para cambiar 01:37:40
la edad de una persona, obligatoriamente necesito 01:37:43
definir el objeto de la clase persona miper 01:37:46
y así de esta forma puedo acceder a él. 01:37:49
Siempre, por 01:37:53
Regla general, que queremos acceder a un parámetro o a un método de un objeto de una clase, tendremos que instanciar su clase. 01:37:55
¿Con qué excepción? Con la excepción de parámetros y métodos que sean estáticos. 01:38:02
Si son estáticos, puedo decir, lo defino para la clase y cuando vaya habiendo instancias de objetos de esa clase, ya tienen esos datos. 01:38:09
¿Dónde utilizamos nosotros continuamente métodos estáticos? 01:38:19
Pues mirad, un sitio donde utilizamos métodos estáticos es cuando ponemos el system.out.println. 01:38:23
Esto, fijaros que tiene toda la pinta de la sintaxis de los métodos de los que estamos hablando. 01:38:31
Tiene un nombre y recibe por aquí, tiene entre paréntesis, en particular el println recibe aquí una cadena de caracteres o cadenas de caracteres puede recibir. 01:38:36
O está sobrecargado con diferentes opciones. 01:38:49
esto pertenece, es un método que pertenecerá en la librería de Java 01:38:51
a una clase que es la clase System.out que es un flujo de salida hacia pantalla 01:38:57
hemos instanciado un objeto de System.out antes de llamar 01:39:01
al método println como necesitábamos para 01:39:05
escribir por ejemplo sobre el parámetro y edad, no, entonces 01:39:09
println como estará definido en la librería de Java 01:39:13
pues como un método, más punto, mirad el valor 01:39:17
absoluto de un número? Pues hay una clase que es la clase math 01:39:24
y hemos llamado al método valor absoluto 01:39:30
de un número que recibe aquí como parámetro. Si metemos un 01:39:35
valor que sea menos 5, pues nos devolverá un 5. Si metemos el 5, pues el 5, 01:39:38
el valor absoluto de matemáticas. ¿Hemos instanciado un objeto 01:39:42
de la clase math? No. ¿Hemos sido capaces de llamar a un método? 01:39:47
Sí. ¿Esto qué implica? Pues que implica que apps 01:39:50
en las librerías de Java, estaría definido como 01:39:54
un método estático. ¿Alguna duda? Yo creo que vamos a ir 01:39:58
cerrando ya aquí, porque son las 7 y cuarto. 01:40:08
Sí, más o menos bien. Mirad, del main, bueno, todavía la próxima clase 01:40:15
os sigo contando más. Me entra un eco, no sé si alguien habéis dejado abierto 01:40:20
el micro. Bueno, pues nada, 01:40:27
la próxima clase os cuento, os sigo contando cositas de esto. 01:40:33
termino con el main, que nos ha faltado 01:40:36
bueno, el main que es algo común a todos los métodos 01:40:39
pero aparece también aquí en el main, el public 01:40:43
y bueno, pues vamos haciendo por ahí 01:40:45
algunas cositas más, mientras tanto os voy viendo 01:40:47
por ahí por los foros, si tenéis alguna 01:40:51
duda y bueno, y poco más 01:40:54
que contaros, si 01:40:57
alguien tiene una pregunta por ahí, dime 01:41:03
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Primer Curso
Autor/es:
JM
Subido por:
Jose Manuel M.
Licencia:
Dominio público
Visualizaciones:
92
Fecha:
2 de diciembre de 2024 - 19:23
Visibilidad:
Clave
Centro:
IES ALONSO DE AVELLANEDA
Duración:
1h′ 41′ 37″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
200.59 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid