Transcripciones
1. Introducción: Hola ahí. Bienvenido
a mi curso de Java. Ahora bien, si haces clic en este curso, probablemente
tengas al menos
una vaga idea de lo que
es Java y eso de alguna manera es importante para tu carrera y
tu educación Bueno, no te equivocas.
Déjame mostrarte cómo Java es uno de los lenguajes de
programación más populares que existen, utilizado por casi todas las
empresas tecnológicas, prácticamente la página de carreras de cualquier
compañía de tecnología
va a enumerar Java como
una de las habilidades. Saber programar en
absoluto es la habilidad que
te pone en la vía rápida por
un salario muy generoso. La razón es que Java es
eficiente, rico en funciones y relativamente fácil de
captar en comparación con algunos otros lenguajes
como C. Eso también significa que puedes recoger programación sin
pasar por el curso de una semana de duración Lo esencial de Java se puede destilar en tan solo unas horas, que es lo que he
hecho en este curso. Usarás las lecciones
de este curso para construir tu propio
juego interactivo que
luego podrás compartir con tus amigos
o poner en tu currículum. Una cosa que
buscan los reclutadores son proyectos personales
verificables, y este se ajusta bastante bien a la
factura Puedes elegir hacer todo
el proyecto por tu cuenta si
quieres desafiar. Alternativamente, también
he incluido cuatro videos de recorrido. Te ayudan por si
acaso te pierdes. También he configurado
todas las muestras de código en un entorno de sandbox en línea.
Ahora bien, ¿qué significa eso? Significa que no hay
necesidad de computadoras complejas. No hay instrucciones de configuración arcanas. Todo lo que necesitas hacer
es visitar los enlaces que proporciono y hacer clic en
el botón verde Ejecutar. Puede gastar toda su
energía enfocándose en la codificación real en lugar de perder el tiempo configurando
un entorno de codificación. Espero que estés emocionado de
aprender sobre Java. Paso mucho tiempo armando este curso y
espero que se demuestre. Te veré en el siguiente video.
2. Acerca de ti y de mí: Hola ahí. En este video, vamos a
hablar brevemente sobre el público previsto
para este curso, así
como por qué deberías
elegir este curso de todos los cursos disponibles que probablemente veas por ahí. Entonces, en primer lugar, ¿por qué
deberías confiar en mí? Ni siquiera me conoces bien. Trabajo para una de las empresas tecnológicas
más grandes del mundo que
actualmente tiene su sede en Cupertino, California Realmente no se me
permite decir para quién trabajo. Pero basta con decir ese código publicitario
que ha impactado las experiencias de usuario de millones
de personas por ahí,
tal vez incluso Tengo mucha experiencia
escribiendo código que importa. Antes de trabajar en
la industria tecnológica, realidad
enseñé ciencias de la computación de
pregrado en la Universidad de California, Berkeley durante cuatro años El curso que impartí C 61 fue nombrado uno de los cinco
mejores cursos en Estados Unidos
por Bloomberg y regularmente veía a más de 2000
estudiantes cada semestre También grabé
videos de Youtube walk throughs para ese curso bajo el canal
CS 61, un departamental A agosto de 2023, ese canal ha recibido
más de 963.000 reproducciones Por último, en 2020,
fui nombrado entre
los 13 mejores instructores del departamento de
ingeniería de la universidad. De varios
cientos, tengo
mucha experiencia enseñando y
manejando clases grandes, especialmente aquellas
con un componente significativo en línea
como esta. Ahora, ¿por qué debería
elegir esta clase? Bueno, aludí a esto
en un video anterior, pero una
ventaja significativa de este curso es que todo el código es
público y ejecutable Ahora bien, puede que no entiendas lo que eso significa o
por qué es significativo, y eso es totalmente razonable. Básicamente, un problema
que suele ocurrir en cursos de
programación
es que incluso
si tomas el código del instructor exactamente como es y
lo pones en tu computadora, posible
que no obtengas
la misma salida o tal vez el código ni
siquiera se ejecute. La razón es que las computadoras
son máquinas muy complejas. A menudo, es
posible que su computadora no esté configurada exactamente de
la misma manera que se configura la
computadora del instructor. En este curso, todo el código se
ha trasladado a un entorno
en línea, incluido el código del proyecto. Toda la configuración de codificación
ha sido
abstraída para usted y
cuidada para que pueda enfocar toda su energía en
la
programación en lugar de
configurar su computadora Si quieres seguir de
forma interactiva en este curso, te
recomiendo que configures
una cuenta en Repl Voy a soltar un enlace en
la descripción del curso así
como en los recursos. A continuación, quiero
platicar brevemente sobre el público previsto
para el discurso. Ahora no se alarme
con esa afirmación. Incluso si no tienes
experiencia en codificación, aún
deberías poder
sacar mucho de esta clase. Dicho esto, si realmente
quieres cubrir todas tus bases y asegurarte de entender toda la sintaxis de
Java de abajo hacia arriba, te
recomiendo que eches un
vistazo a mi otro curso, Java for Beginners
Code en 1 hora. Esa clase te
enseñará algunos detalles de meollo
arenoso sobre Sin embargo, no necesitas saber todo de esa clase para entender las cosas
en esta clase. Lo que te recomiendo que hagas es
ver un par de videos de esta clase y ver si
entiendes el significado
de lo que estoy diciendo. Si resulta que no
entiendes nada, te
recomiendo que tomes un descanso. Echa un vistazo a un par
de videos del curso que filmé antes y vuelve a esta
clase cuando estés listo. Y eso es todo para este video. La próxima vez que me veas,
vamos a estar saltando a
algún contenido real.
3. Introducción al proyecto: Bienvenidos amigos. En este
video vamos a hablar del proyecto
que vas a
estar implementando a lo largo de este curso. El proyecto que vamos
a implementar
se llama Buscaminas Siéntete libre de buscarlo
en Google ya que es un juego bastante popular y
no exclusivo de esta clase. Aunque ya estés
familiarizado con el juego, aún así te
recomendaría que veas este
video para
que entiendas nuestra implementación
específica. El código en el
proyecto que te
darán se ha completado
parcialmente, pero faltan algunas piezas
importantes. Tu objetivo será arreglar estos
componentes críticos para que el juego funcione como lo
hace en este video. Caminaremos
juntos por
esos componentes en puntos
posteriores del curso para que no te pierdas. Al final del proyecto,
deberías poder jugar el juego forma interactiva e
invitar a tus amigos y familiares a jugarlo también Ahora veamos cómo funciona
este juego. Sigamos adelante y haga clic en
Ejecutar nuestro juego de Mente. Barredora comienza con una tabla de diez por
diez de celdas sin explotar. Todas estas células, marcadas X son células que aún
no han sido reveladas. Estas celdas, con letras de la
A a la J en
los bordes del tablero, te
ayudan a identificar
las coordenadas de una celda Nuestras coordenadas van a
tener la columna de fila de formulario. Por ejemplo, esta
celda de aquí
va a tener coordenadas
porque está en A.
En la columna B, todas las celdas
son celdas numéricas, celdas vacías, o celdas mineras, pero su estado
actualmente está oculto por la X. Si tocas en una celda que es una celda mía, pierdes el juego. El objetivo del juego es
encontrar todas las células no mineras. Veamos qué pasa
cuando tocamos un celular. Podemos hacer tap B, ¿de acuerdo? B se reveló
como una celda vacía, que podemos ver porque,
bueno, está vacía. Una celda vacía es aquella que tiene cero minas inmediatamente
adyacentes a ella. Eso significa que la celda A, la celda B, celda
A AC, la celda BC y la celda BB no eran todas minas. Eso quiere decir que todos
eran seguros para tocar. Observe que después de que
grabamos la célula B, también se revelaron
un montón de otras células Todas estas de aquí,
todas estas celdas vacías así
como estas
celdas numéricas de aquí mismo. Hacemos esto porque
como acabo de decir, una celda vacía significa que todas las celdas adyacentes a esa celda
vacía son seguras de tocar. Nosotros solo los tocamos para
que ahorres tiempo. Si encontramos una celda vacía
adicional junto a la celda
vacía original que grabamos, también
tocamos todas las celdas seguras alrededor de esa celda Y continuamos con
este proceso hasta que nos quedamos sin celdas seguras para aprovechar. Echemos un vistazo a
esta celda por ejemplo. Se reveló
que esta célula era una celda número. El número dos significa
que hay exactamente dos celdas mineras
inmediatamente adyacentes a ella. Eso significa que estas células son todas potencialmente células mineras. Esta también es
potencialmente una célula de mina. ¿Cómo averiguamos
cuál es seguro o no? Este es el quid del juego de
la barredora de minas. Necesitamos combinar
información de otras celdas para deducir
información para esta celda Aquí hay una forma en que podemos deducir
qué célula es una célula de mina. Echemos un vistazo a
esta celda de aquí mismo. También se ha
revelado que esta celda es una,
pero como estas celdas a su alrededor ya han sido reveladas
como celdas vacías, se ha revelado
que
esta es una celda numérica, y esta se ha revelado
que es una celda numérica. Sólo queda una celda
que es adyacente a esta. Por lo tanto, esta
célula no revelada debe ser la célula de la mina. Como no queremos
tocar una mina, vamos a marcar la celda como una celda peligrosa para que
sepamos no tocarla. Podemos ver que esta
X de aquí mismo está en fila y columna H.
Podemos hacer bandera F, H. Este símbolo de triángulo nos
indicará que la celda está señalizada y sabemos
no tocarla Ahora bien, como sabemos que
esta célula es una célula de mina, sabemos que esta celda
va a estar segura. ¿Por qué? Pausa el video y te
revelaré la respuesta en 321. El motivo es que este número de
celda de aquí mismo es uno. Ya deducimos que se trataba una célula peligrosa por
esta número uno de aquí Por lo tanto, debido a que ya
hemos encontrado la celda que está adyacente a esta
celda número que es una mina, sabemos que todas las
demás celdas alrededor este número uno van
a ser seguras de tocar. Sigamos adelante y
probemos nuestra hipótesis. adelante y toquemos I. Efectivamente, vemos que me
revelaron que era un número celular, que es tres que
era seguro para tocar. Aunque todavía hay muchas
minas en esta zona, en la gran mayoría de los casos, podrás continuar con
este proceso de inferencia para todo
el tablero y eventualmente identificar dónde están todas
las minas Si crees que cometiste un error, también
puedes desmarcar
la celda así Ahora, H se ha restablecido a una celda no revelada
para fines de demostración Veamos qué pasa si
tocas en esta celda de mina. Estos asteriscos
representan mentes en nuestro tablero y podemos ver que ahora
tenemos un juego terminado Reiniciemos el juego haciendo
clic en el botón Ejecutar. Ahora voy a acelerar esta siguiente tabla muy rápido para que puedan ver el resultado final. Siéntete libre de ver este video a velocidades
muy lentas si
quieres seguir adelante y ver si puedes
determinar por qué tomé
decisiones para marcar o
tocar ciertas celdas. Por último, podemos ver que hemos aprovechado todas las células no mineras Hemos ganado el juego en total. Cada juego debe
tener diez celdas mineras. Bien, Y eso
es todo para este video. Espero que esto te
entusiasme por hacer el proyecto. Paso mucho tiempo armando
esto para ti y espero que hayas aprendido
mucho de Java haciéndolo. Te veré en el siguiente video.
4. Ilustración de herencia: Bienvenidos amigos. En este video, vamos a
hablar de herencia. Para que esta lección sea
un poco menos seca, vamos a
hablar de helado. Esto es helado. Ahora imagina que
tienes un amigo que
nunca ha oído hablar del helado y te
pide que se lo describas. Cada unidad de helado viene con una serie
de rasgos comunes. Por ahora, vamos a simplificar
y debería ser bastante seguro decir que cada unidad de
helado tiene crema. Una temperatura de aproximadamente 0 Celsius y un cono para sostener la crema. Ahora imagina que terminaste describir el helado a
tu amigo imaginario. Pero ahora siente curiosidad por los
diferentes tipos de helados
como el helado de fresa
y el helado de arándanos Probablemente lo
describirías mucho de
la misma manera que describes el
helado original de aquí. Estos nuevos sabores también tienen un cono y una temperatura
de aproximadamente 0 Celsius. La única diferencia es que el helado de fresa tiene crema con sabor
a fresa,
y el helado de arándanos
tiene crema con sabor a arándanos Todo esto está bien y dandy
para este ejemplo en particular. Si solo tenemos tres atributos
para describir el helado, no
está de más
repetirnos para cada uno, pero se puede imaginar
que podríamos querer agregar aún más rasgos para
describir este helado. Tal vez también queremos agregar
un atributo de sabor de cono, o una textura de cono. O tal vez el peso
del helado, o el volumen del helado. Se puede obtener infinitamente más
descriptivo del helado. Y cada vez que tu amigo
te pidiera que describieras un nuevo helado
con sabor, tendrías que
redefinir cada uno de esos rasgos una y
otra vez Sería muy agradable si
tuviéramos una manera de reducir
la cantidad de trabajo que
tenemos que hacer para describir
nuevos sabores de helado. Aquí es donde
entra la herencia de forma natural. En algún momento,
te cansarías de describir las mismas
características para el helado. En lugar de reiterar que el
helado tiene un cono y una temperatura de 0 centígrados,
le dices a tu amigo, bueno, el helado de arándanos es
igual que el helado normal, excepto que la crema
es de un sabor diferente, todo lo demás es La herencia es un paradigma en Java que nos permite hacer esto. La herencia significa que
los comportamientos y atributos de un modelo base se copian a
un modelo más nuevo y actualizado. Todavía tenemos la
capacidad de sobrescribir atributos
selectos como el sabor a
crema en este caso Entonces esto es bastante impresionante ahora, en lugar de
repetirnos y redefinir cada atributo de helado cuando definimos un nuevo sabor a
helado, todo lo que tenemos que hacer es
anular un atributo, el atributo de sabor a crema, y heredar el resto de los atributos compartidos
del modelo de helado base, como la temperatura
y el cono Esto suena muy sencillo, pero es un
principio muy importante de la programación Java Reducir el código repetitivo
es muy valioso de recapitular. La herencia es como
maximizamos el código, reutilizamos y simplificamos tu código. Te voy a mostrar algunos
ejemplos concretos de cómo
se ve esto en código
en el siguiente video.
5. Ejemplos de herencia: Hola amigos. En este video, vamos a discutir algunos ejemplos concretos de
herencia. Primero, imagina que tenemos una clase llamada dog y decimos que tiene un campo
estático llamado sound y un método get llamado
get Sound que recupera
el sonido en caso de que te hayas olvidado o no estés familiarizado
con la sintaxis Te recomiendo pausar
el video ahora y ver el video titulado Objetos
parte Dos en mi otra clase, Java, para principiantes en 1 hora. Ahora tenemos además otra
clase llamada Brown Dog, que extiende la clase de perros. Esto extiende la sintaxis es nueva. Así es como especificamos los patrones de
herencia en Java. En este caso, diríamos que el perro marrón hereda del perro No te preocupes por las
implicaciones de esto por ahora. Solo reconoce a Dysntex. Ahora digamos que el perro marrón tiene un método llamado get color, que simplemente devuelve
la palabra marrón. Ahora vamos a juntar todo esto. Tenemos la clase
de perro de antes y tenemos la clase de perro marrón que
extiende perro en nuestra clase principal. Vamos a crear una instancia de la clase de perro y una instancia
de la clase de perro marrón. Así, si imprimimos dog get sound y brown
dog getcolor, la salida es bastante
predecible. Perro sí consigue sonido. Simplemente imprimiremos corteza
y perro marrón getcolor, imprimiremos palabra marrón La magia pasa es cuando
hacemos doggetund marrón. En base a lo que sabemos
hasta ahora de la programación Java, esto parece que
fallaría, ¿verdad? Dado que la clase brown dog no tiene un método
get sound, eso parece una suposición
razonable. Resulta que
si ejecutas esto,
esta última declaración
en realidad imprimirá corteza. La razón es que tenemos herencia cuando una
clase extiende a otra, Java primero buscará en
la clase extendida y verá si tiene un método o campo
definido si no lo hace. Java luego verifica
su clase padre. En este caso, primero revisamos perro
marrón para conocer el método
get sound. No tiene ese método, así que comprobamos que el perro de clase
padre tiene el método get sound. Usa ese método
que devuelve ladrido. Quiero enfatizar
aquí que Java utilizará primero el
método más específico que encuentre. Recuerda que Java
se ve en perro marrón primero para obtener sonido
antes de que se vea en perro. Esto significa que si el perro marrón tenía un método get sound que
devuelve algo
diferente a los perros obtener método de sonido y nosotros llamamos
perro marrón perro obtener sonido. Java habría utilizado en su lugar
el método get sound definido en brown dog. Eso fue un bocado.
Si estás viendo a 1.5 x o dos x velocidad
y no captaste eso, te
recomiendo que rebobines 30 segundos y vuelvas
a escuchar esa frase A una velocidad X, ese es el final de nuestra discusión
sobre la herencia. Para recapitular, usamos la palabra clave
extends para
decirle a Java que nos gustaría
crear una
relación de herencia Una vez que se
ha establecido la relación de herencia, Java utiliza la resolución de
método dinámico para averiguar qué
método usar. Primero se ve en
la clase real desde la que
estamos llamando al método. Y sólo si el método está ausente, Java
se ve en
la clase padre. Aquí está el enlace
al código de repeler, usando esta lección para
que jueguen con Te veré en el siguiente video.
6. Súper ejemplos: Bienvenidos amigos. En
este video vamos a hablar de súper recuerdo de la
lección anterior que tuvimos una clase de perros que tenía
un método get sound. También teníamos una
clase de perro marrón que heredado del perro marrón tenía
un método get color. Cuando llamamos brown
dog get sound, Brown dog re utilizó el método get sound from
dog vía herencia. También, recuerde el orden en que Java resuelve los nombres de los métodos. Si llamamos marrón no conseguimos sonido. Java buscaría primero en la clase de perros marrones
para obtener sonido. Java solo se vería
en la clase de perros si perro
marrón no
tuviera que obtener Sound. Si brown dog tuviera
definido
un método get sound y llamáramos a
brown dog get sound, brown dogs get sound
anularía el
método get sound de la clase dog. Lo que significa que
ejecutaríamos la lógica contenida dentro de
perro marrón en lugar de perro. Podemos re, usar o anular métodos
de la clase padre. Pero, ¿y si queremos anular y reutilizar la lógica
de la clase padre? Veamos cómo funciona. Primero, digamos que tenemos
nuestra clase de perro otra vez, obtenemos método de sonido
que devuelve ladrido. Ahora digamos que tenemos nuestra clase de perro
marrón que hereda del perro y además
tiene un método get sound Este método tiene una nueva palabra clave que no habíamos visto antes. Súper. Super es como hacemos referencia a la
clase padre de la clase actual. En este caso, super es realmente
un alias para la clase de perros. Esto significa que super
do get sound es análogo a decir
perro consigue sonido. Lo que significa que súper obtener
sonido devolverá ladrar. El resultado de todo este método de dogtetsund
marrón será corteza marrón corteza Eso es más
o menos. Hemos aprendido sobre nuestra nueva palabra clave super, que se usa para referirse
a una clase padre cuando estamos escribiendo código
dentro de la clase hijo. Esta palabra clave también nos permite
crear métodos híbridos de anulación. Es decir, somos capaces de re, usar código de la clase padre y también agregar nuestra
propia lógica personalizada. Aquí está el enlace
al código de repeler en esta lección para
que jueguen con Te veré en el siguiente video.
7. Polimorfismo de subtipos: En este video, vamos a hablar de polimorfismo de subtipo Antes de saltar,
por favor, no se deje intimidar por estas palabras que
suenan tan elegantes El concepto
en realidad no es mucho más complicado que
cualquier cosa que hayamos visto hasta ahora, pero a los diseñadores de
Java no se les
ocurrió un nombre más simple. Una vez más, comencemos
nuestra ilustración con una clase de perro que tiene un método get sound
que devuelve ladrido. También tendremos una
clase de perro marrón que hereda del perro, y este método de perro marrón
devuelve corteza marrón Armando todo,
tenemos nuestras dos clases. Tenemos un tercer método get sound ubicado
en nuestra clase principal. Este tercer método toma en una instancia de perro y simplemente llama a que los perros
obtengan método de sonido. Si instanciamos una instancia de
la clase de perro base y luego
pasamos esa clase de perro base a este método como cabría
esperar, obtendríamos ladrido como salida Pero ahora digamos que instanciamos
una instancia de perro marrón y pasamos ese objeto a
este método get sound Esto es extraño. El método get sound
aquí en la parte inferior derecha solo acepta
argumentos de tipo dog, sin embargo el tipo de objeto que estamos
pasando es brown dog. En base a lo que sabemos de Java, esto parece que
debería ser un error, ¿verdad? Resulta que esto no
se equivocará. Esta línea en realidad
imprimirá corteza marrón. Esto se debe a algo en
Java llamado método dinámico La
resolución es un ejemplo
de polimorfismo de subtipo polimorfismo de subtipo básicamente
significa que un subtipo de un tipo padre puede
tratarse como Intuitivamente, esto
debería tener sentido. Un perro marrón debe tener todas
las propiedades de un perro. Un Chihuahua marrón debe tener todas las propiedades
de un perro marrón. Una cosa más específica
debería tener al menos todos los comportamientos y rasgos de una cosa menos
específica relacionada. Ahora volvamos a este ejemplo, la razón por la que podemos pasar en un perro marrón a
este método que acepta tipos de perros es que Java asume
tipos específicos de perros, podrá
llamar a todos los métodos de la clase perro base cuando el
programa realmente se ejecute. Java resolverá entonces métodos de
instancia usando el tipo
dinámico de un objeto. Aka el tipo que un
objeto en realidad es un perro marrón y no
el tipo estático que
declaramos que es
en este método perro. Eso lo diré una vez más
porque es un concepto bastante importante. El tipo estático de
un objeto es lo que declaramos explícitamente
el objeto como. En este método, es perro marrón. En este método, el
tipo estático cambia a perro. El tipo dinámico de
un objeto es lo que realmente es
el objeto
y nunca cambia. En este caso, el
tipo dinámico es perro marrón. Para resolver un método de instancia, utilizamos el
tipo dinámico del objeto. Quizás te estés preguntando
por qué hacemos esto en absoluto. ¿Por qué en la tierra nos
confundiríamos? ¿Por qué no simplemente llamarlo
un perro marrón cuando lo
instanciamos y simplemente
lo guardamos como un perro marrón para La razón por la que
podríamos querer volver, utilizar este método para
muchos tipos de perros. Imagínese que además de
la clase de perros marrones, también
teníamos clases de perros blancos, perros azules y perros amarillos, todos los cuales heredan del perro y todos los cuales tienen métodos de
obtener sonido Sería muy
molesto si tuviéramos que
definir un método que tome en un objeto de tipo perro marrón y otro método que tome en
un objeto de tipo perro blanco, y perro amarillo, y perro azul. Cuando todos estos métodos
hacen exactamente lo mismo, en lugar de
repetirnos, simplemente creamos un método que acepta el tipo
del perro modelo base. Al tener un tipo de entrada más
general, podemos maximizar nuestra
reutilización de código y solo tener un método que se encargue de todos los casos más específicos. Eso es todo para este video. Para recapitular, hablamos de polimorfismo de
subtipo. Es un paradigma Java
que nos permite tratar instancias
específicas de un objeto como un objeto base menos específico. También hablamos de tipos estáticos
versus dinámicos, que dictan la forma en que
resolvemos los métodos de instancia Cuando nos referimos a
un método de instancia, usamos el método definido en el tipo dinámico de un objeto
en lugar del tipo estático. Aquí está el enlace
al código de repeler en esta lección para
que jueguen con Te veré en el siguiente video.
8. Ilustración abstracta: Bienvenidos amigos. En este video, vamos a recorrer un panorama visual de las clases
abstractas. En esta ilustración, en
realidad vamos a volver a nuestros ejemplos de helados de
la lección de ilustración de herencia. Recordemos que tenemos una clase de
helado y también tenemos helado de
fresa y clases de helado de
fresa y helado de
arándanos
que heredan del helado Ahora bien, si piensas para ti mismo, ¿cómo son estas tres clases
en la vida real? Probablemente se te
ocurra alguna idea de cómo es el
helado de fresa y arándano Más o menos, se ven
algo así. Estas clases
reflejan la realidad y están ancladas a ejemplos
concretos Pero, ¿qué pasa con la clase de
helado? ¿Qué aspecto tiene el
helado sin sabor? Quizás estés pensando en el helado
de vainilla, pero incluso la vainilla es un sabor. El helado de vainilla también sería una subclase que hereda
de la clase de helados Pero el helado en sí, sin sabor, no
existe tal cosa, al
menos no en tu tienda de abarrotes
local. En Java, en realidad
modelaríamos esta
clase de helado como un resumen. Una clase abstracta es algo que no
se puede instanciar directamente porque una instancia de ese objeto no tiene ningún
sentido Al igual que el helado
sin sabor no tiene sentido. En cambio, sólo podemos instanciar subclases
de una clase abstracta, como el helado de fresa o
arándano Una vez más, estamos agregando complejidad a tu
trabajo y conocimiento. Parece que todo lo que estamos haciendo es limitar tu funcionalidad. Y tal vez te estés
preguntando, por qué. ¿Por qué crearíamos
una clase abstracta que ni siquiera puede ser instanciada ¿No nos estamos
limitando y ralentizando deliberadamente
si nos obligamos a crear una subclase antes de
usarla para La respuesta es que
aunque un objeto como helado
sin sabor no
tiene ningún significado en sí mismo, todavía
tiene
valor de dos maneras La primera es que los patrones de
herencia siguen siendo ciertos aquí. Al igual que con la herencia
regular, podemos definir un valor de campo en el objeto base y tener subclases heredar
para ese A pesar de que el
helado sin sabor no existe, todavía
podemos declarar que
su temperatura es de 0 Celsius y tener subclases
todas heredan Esto debería tener sentido
ya que no necesitamos tener una clase de helado de concreto para
determinar su temperatura. Solo podemos decir, en general, el helado debe ser de 0 centígrados y definirlo en la clase abstracta
base. La segunda forma en que las clases abstractas siguen siendo valiosas es que pueden especificar un contrato
que las subclases deben cumplir Por ejemplo, podemos declarar que todos los helados deben tener
un método definido que devuelva el color del helado en el modelo de helado
base. Este método no se
definirá porque
no existe tal cosa como un color para
todas las instancias de helado. No obstante, el helado de
fresa puede tener un
método get color que devuelva el rosa. Y el
helado de arándanos puede tener un método get color
que devuelva el azul Si tuviéramos una clase de
helado adicional que
no proporcionara una implementación get
color, Java no lograría compilar. Eso es algo bueno
porque no
queremos que nuestro código se
compile a menos que estemos absolutamente seguros de que todas las instancias de helado de
concreto tienen un color definido para ellas. Eso puede sonar un poco
confuso, pero no te preocupes. Te voy a mostrar ejemplos de cómo funciona eso en
el siguiente video. Eso es todo para esta lección. Hablamos de
clases abstractas y de cómo son casi objetos en el sentido de que no se
pueden instanciar
directamente, sino que pueden proporcionar un contrato
o plantilla para Veremos
ejemplos concretos de esto pronto. Te veré en el siguiente video.
9. Ejemplos abstractos: Hola amigos. En este
video vamos a recorrer algunos ejemplos
de uso de clases abstractas. Y en realidad hoy vamos
a sacudir las cosas. En lugar de caminar por
diapositivas y diagramas de código, vamos a ser
manos en la codificación. Por supuesto, te
recomiendo que
sigas en tu cuenta Repel
It si puedes Si no, no dejes de
visitar el enlace Repel. Después de que termine esta lección, bifurcarla y juguetear
con el código Lo primero que
vamos a hacer es visitar a Repl. Pulsa el botón Crear repeler, elige la plantilla Java y nombra tus clases
abstractas de Repele Ahora que se ha creado, lo
primero que vamos a hacer es crear una clase
abstracta de perros. Vamos a hacerlo haciendo clic en el botón de nuevo archivo de aquí y llamarlo Java. Lo primero que
vamos a hacer es crear una clase de perro abstracto. La declaración de clase parece casi una definición de
clase regular, excepto que vamos a agregar
el modificador abstracto. El modificador abstracto solo
significa que vamos a tener al menos un
método abstracto dentro de esta clase. Primero definamos un atributo llamado piernas entumecidas
y establecerlo en cuatro Tenga en cuenta que este no es
un campo abstracto. No existe tal
cosa. Solo los métodos pueden ser abstractos en Java. Intuitivamente,
debería tener sentido por qué definimos como atributo
en una clase abstracta Recuerda, no
necesitamos un tipo específico de perro para decirnos
cuántas patas tiene un perro. Los perros en general tienen cuatro patas. Es seguro definirlo aquí. Ahora definamos un
método regular no abstracto llamado Get Sound, que va a devolver ladrido. Esto va a
comportarse exactamente como cualquier otro método no abstracto en una clase regular.
Aquí no hay sorpresas. Ahora, finalmente, definamos
un método abstracto. Vamos a llamarlo obtener
color y no definirlo. Nuevamente, esto debería tener sentido. Tiene sentido definir, obtener sonido para los perros en general, porque los perros generalmente
hacen el mismo sonido. Pero, ¿cuál es el color de un perro? No puedes responder a
eso sin tener una instancia concreta de
un perro frente a ti. Por lo tanto, es un método
abstracto. Ahora vamos a crear una nueva clase, clase regular, no
una clase abstracta. Y que extienda nuestra clase de perro
abstracto. Vamos a llamar a
este tipo un perro moreno. Y va a
extender nuestra clase de perros. Clase pública Brown. Tenga en cuenta que la sintaxis para extender una
clase abstracta es la misma que para extender una clase
no abstracta. Aquí vamos a proporcionar una implementación concreta
del método abstract get color. El color de un
perro marrón debe ser marrón. Sólo vamos a hacer que se le
devuelva marrón. Agreguemos adicionalmente una anotación de anulación
a este método La anotación at override
es 100% opcional, pero es una buena práctica
incluirla. La razón es que Java comprobará
entonces en tiempo de compilación si el método
que has anotado está realmente
sobrescribiendo un Ejemplos en los que esto sería útil serían cuando
puede estar mal escrito, el método o el método no existe realmente
en la clase padre Es especialmente importante al sobrescribir
métodos abstractos porque los métodos
abstractos no tienen ninguna lógica definida en
la clase abstracta Queremos estar absolutamente
seguros de que hemos proporcionado una
implementación concreta para el método. Ahora vamos a
juntarlo todo en nuestra clase principal. Entonces lo primero que vamos
a probar es instanciar un perro así.
Veamos qué pasa. Mira, tenemos un error. Dice que el perro es abstracto
y no puede ser instanciado. Esto tiene sentido, porque
como ya hemos dicho antes, las clases
abstractas no pueden
ser instanciadas directamente. Sólo podemos instanciar
sus subclases. Ahora intentemos instanciar
un perro marrón en su lugar, que hereda de este tiempo el código compilado
sin ningún problema Nuevamente, esto no debería tener
sentido. Perro marrón es una subclase
de una clase abstracta. Ahora veamos qué pasa
cuando llamamos a estos métodos. Primero, cambiemos el nombre de
este tipo Brown Dog porque es un perro marrón. Primero echemos un vistazo a las patas entumecidas de punto de perro
marrón. Si recuerdan, las patas entumecidas de punto de
perro marrón deberían ser este tipo de
aquí dentro de la clase de perros Dado que los campos no pueden ser abstractos, las piernas
entumecidas van a actuar
exactamente de la misma manera que van a funcionar
los atributos definidos en
las clases regulares Cuando llamamos patas entumecidas de punto de
perro marrón, Java buscará primero en
la clase de perro marrón para ver si existe un atributo
de patas entumecidas. No lo hace. Luego se ve en
la clase de padres, luego se ve en perro y
ve que las piernas entumecidas sí existen Esta primera línea debería
imprimir cuatro. Vamos a probarlo. Efectivamente, recuperamos cuatro. A continuación, probemos
algunas llamadas a métodos. Veamos qué
pasa cuando llamamos perro
marrón punto obtener color
y marrón perro punto obtener. Sonido Como era de esperar,
perro marrón obtiene color vuelve marrón. Ese es el método que estaba vacío en la clase de perro original pero fue anulado en
perro marrón, perro marrón, perro get Sonido Fue el método que definimos
en la clase de perro padre y ese perro marrón no definió explícitamente. Resumen rápido Perro marrón tiene conseguir
color, perro tiene get. Sonido. Podemos ver que los métodos
regulares actúan exactamente de
la misma manera que solían hacerlo. Si no existe
en perro marrón. Entonces llamaremos al método
definido en la clase padre. Sin embargo, obtener color también actúa de manera similar
a las clases regulares. Llamamos al método que se
define en la subclase. En este caso, si hubiéramos
olvidado anular el método get color de la clase abstracta que hereda el
perro marrón de Java, habría arrojado un error Veamos en realidad qué
pasa si lo hicimos. Digamos que mal deletreamos conseguimos
color así y pegamos a correr. Ya ves que tenemos un error. Perro marrón no es abstracto y no anulo método
abstracto, obtener color en perro. Este es uno de los beneficios de usar las clases abstractas. Vemos nuestros errores por adelantado incluso
antes de ejecutar el código. Eso es todo para este video. Hoy echamos un vistazo a las clases
abstractas y
cómo implementarlas, así
como algunos de los
errores que podrían surgir al hacer un mal uso de las clases
abstractas. Aquí está el enlace
al código de repeler. Me gustaría que
lo bifurcaras y juguetearas
con el código
10. Guía completa de dragaminas 1: Bienvenidos amigos. En este video
vamos a recorrer la primera parte de
este proyecto utilizando lo que hemos aprendido en
las últimas lecciones. Si quieres seguir
adelante de forma interactiva, vas a necesitar hacer una cuenta y
verificar tu correo electrónico El enlace para eso debería estar en la descripción de la clase y estaba en el video de introducción
para este curso Si no quieres
hacer otra cuenta, eso también está totalmente
bien
Por supuesto ,
te recomiendo encarecidamente que hagas una cuenta. Lo primero que
querrás hacer después de hacer una cuenta es visitar bit punto lee, esqueleto
buscaminas El enlace también está en la descripción
del proyecto. Una vez que estés en esta página, haz clic en el botón de bifurcación y
debería llevarlo a una copia
del código en tu cuenta. Echemos un vistazo a la
estructura de este proyecto. Tener los archivos, la celda de la placa principal, celda
vacía, la celda mental
y la celda numérica. Gran parte del código en
Maine y Board se ha implementado para usted
y abordaremos algunas piezas faltantes más adelante
en los recorridos posteriores Para este video, nos vamos
a centrar en las clases celulares. Como ya
habrás adivinado, una clase celular representa una de las casillas del juego
Buscaminas Echemos un vistazo más de cerca. La clase de celda es
una clase abstracta. Declara un contrato para que sigan
otras clases, y también proporciona
algunos métodos predeterminados. Cada clase de celda concreta debe implementar un método de dos cadenas, que es su
representación de cadena en la placa, y un método tap que define lo que sucede
cuando se toca la celda También tenemos algunas
banderas que tienen valores
predeterminados de false
y tenemos algunos métodos que se deben compartir entre
todas las implementaciones que se
ha tocado Bandera, ONU bandera mentes de
vecinos entumecidos e incrementar vecinos entumecidos Quiero que
piensen en lo siguiente. ¿Por qué estos métodos son abstractos y por qué son
estos métodos concretos? Pausa el video y te
responderé en 321. Bueno, si te
pregunto cómo debería ser una celda en general y
buscaminas ,
¿podrías No puedes. Una celda está en blanco. Si es una celda vacía,
tiene un número en ella. Si es una celda numérica y tiene un asterisco, si
es una celda mental, necesita una
implementación concreta de una celda para determinar cómo debería ser su
representación de cadena cómo debería ser su
representación De igual manera, el comportamiento para el tap también depende de qué tipo de
celda estés hablando. Por ejemplo, si tocas una celda
mental, el juego ha terminado. Pero si tocas una celda vacía, solo te ayudamos a tocar todas
las celdas seguras vecinas. Por otro lado,
si le pregunto si una celda independientemente de su tipo, ha sido intervenida, ¿puede responder a esa pregunta?
Sí, puedes. Independientemente del
tipo de celda que sea, puede responder si
una celda ha sido intervenida De manera similar, los
comportamientos de flag y unflag en una celda son los mismos
en todas las clases de celdas, independientemente de su tipo Bien, comencemos a abordar estos dos comentarios
en clase celular. En primer lugar, vemos que hay un método de lingotes que
ha sido intervenido Cuando tienes un método que devuelve el estado de un objeto, eso es una pista de que
deberías estar mirando los campos del objeto. En este caso, hemos
intervenido y está marcado. ¿Qué opinas que debería
devolver
este método , dada esa información? Bueno, deberíamos volver tapped ya que su nombre sugiere
que va a almacenar información sobre
el estado del tap de las celdas A continuación, echemos un vistazo a flag. Devuelve nulo. No tenemos que preocuparnos por
un valor de retorno. En cambio, este
método vacío sugiere que su único propósito es
modificar el estado de un objeto. Dado que queremos modificar
el estado del objeto, ¿qué variable crees que
deberíamos estar modificando? Bueno, deberíamos estar modificando
el campo marcado, estableciendo su valor en true Del mismo modo, el método unflagged va a establecer el campo is
flagged Eso es todo lo que tenemos
que hacer para la clase celular. Pasemos a la celda vacía. Primero vemos que tenemos que anular todos los métodos abstractos. Copiemos sobre los métodos
abstractos y comencemos a implementarlos. Vemos aquí que hay
un comentario para usar este carácter especial
para celdas señalizadas Empecemos por
implementar esa lógica. ¿Cómo se sabe si se ha intervenido
una celda? Bueno, echemos un vistazo. Tenemos esta
variable marcada que almacena información sobre el estado de
bandera de la celda. Vamos a usar eso. Si esta celda ha sido señalada, devolvemos este
carácter especial aquí mismo De lo contrario, si esta
celda ha sido intervenida, entonces devolvemos un espacio vacío Debido a que es una celda vacía, si tocas una celda vacía, debería revelar un espacio vacío. Por último, si esta celda
no ha sido marcada ni tocada, ¿cómo debería
ser? Bueno, recordemos de
nuestro primer video hablando de este proyecto, dijimos que todas
las celdas comienzan como una X, que
simplemente representa eso, ese estado celular aún
no se ha revelado. A continuación, echemos un vistazo, como su nombre indica, ¿qué cree que va a hacer este
método? Video positivo, y
voy a responder en 321. El método top va a
establecer el campo tapped en
true para que podamos recordar
el estado de esta celda Después de establecer la bandera en true, notamos que este método
necesita devolver un lingote Bueno, en realidad es bastante
difícil saber aquí si
necesitamos devolver verdadero o
falso. Te voy a dar una pista. Si quieres desafiar, prueba visitar el tablero Java y
mira su método tap. Vea si puede deducir cuál
debe ser
el valor de retorno previsto
del método tap de clases de celda en un toque exitoso Y pausa el video si
quieres pensarlo. Si no, sólo te
diré la respuesta. La respuesta está en 321, vamos a devolver true, ya que un valor de retorno verdadero indica que la celda
era segura para tocarla. Lo cual podemos deducir al
mirar Board dot Java. Vemos en el tablero Java que
si el resultado del tap es verdadero, entonces seguimos buscando celdas vacías
vecinas para tocar. En otras palabras, un resultado de tap de true significa que la celda
era segura para tocar. De lo contrario, no
buscaríamos celdas
vacías vecinas para tocar. Ahora pasemos a
la celda numérica y
repita el ejercicio. Esta vez, vamos a
querer anular
los métodos abstractos y
también adormecer las mentes vecinas El método tap va a ser prácticamente el mismo que el
de la celda vacía. También es seguro tocar una celda numérica. Nos volvemos verdaderos y volteamos
el lingote de tap a true. El método de dos cadenas
también se verá muy similar
al método de
dos cadenas de clases anteriores excepto que si ha sido intervenido, debemos devolver el número de minas que son
vecinas a esta celda Convenientemente,
vemos que aquí hay un campo llamado mentes
vecinas entumecidas No te
preocupes demasiado por cómo usamos este método de incremento Vecinos
entumecidos solo saben que ya lo hemos
implementado para ti Básicamente, solo
llamamos a este método en
el momento apropiado a la hora de
plantar minas en el tablero. Vecino entumecido Mentes
nos da el valor correcto. Como queremos que este método
devuelva una cadena, Numb Neighbor Minds
como un entero, necesitamos convertir este
entero en una cadena Pero, ¿cómo
lo hacemos? Bueno, usemos un
recurso fantástico llamado Google. Busquemos en Java cómo
convertir un entero en una cadena. Sigamos adelante y hagamos clic
en el primer resultado. Vamos a desplazarnos un poco hacia abajo, e inmediatamente vemos
que
aquí hay un ejemplo , yo equivale a diez. Y convertimos ese diez en una
cadena usando el valor de cadena. Sigamos adelante y
usemos ese valor
de corriente de este número mentes vecinas. De esta manera, este valor retorno
coincide con el valor
de retorno del método de dos cadenas. Por último, también anulemos las mentes de los vecinos
entumecidos, lo que no tuvimos que hacer
para la clase anterior Mentes vecinas
entumecidas, como su nombre indica, devuelve el número de minas
que son celdas vecinas Tenemos un campo que
devuelve exactamente eso. Sigamos adelante y regresemos
num mentes vecinas. Ahora hemos completado
el número celular. Echemos un
vistazo a la clase final que estamos implementando
en este video. Mind cell en realidad
va a tener muchas similitudes con las
celdas anteriores que acabamos de implementar. Sigamos adelante y copiemos
estos métodos abstractos. El
método de tap de celdas mentales va a ser diferente de
las clases anteriores. Todavía vamos a estar configurando
el campo tapped en true, pero en lugar de devolver true, vamos a devolver false Dado que cierto significa
que era un grifo seguro, una mina no es una
celda segura para tocar. El
método de dos cadenas va a parecerse a otras clases, excepto que si se ha tocado, deberíamos devolver un asterisco porque esa es su
representación en el tablero En realidad, eso es todo
lo que tenemos que hacer ahora. Terminamos con todas
nuestras clases celulares. De hecho, no podremos
verificar si
lo hemos hecho correctamente hasta el
final de todos estos recorridos Como reto, si
quieres ver si
realmente entendiste lo que estaba
pasando en este video, te
recomiendo que vuelvas a bifurcar el código
original y ver si puedes rellenar todos los
comentarios para hacer en el esqueleto
sin mi ayuda. De lo contrario,
te veré en el siguiente video.
11. Interfaces: Bienvenidos amigos. En este video vamos a
hablar de interfaces. Pero espera,
ni siquiera hemos hablado de interfaces antes.
¿Qué son? Las interfaces son
clases que especifican un contrato y no pueden ser
instanciadas directamente. Ahora sé lo que estás pensando. ¿Eso no suena exactamente como la definición que dimos
para las clases abstractas? En realidad estarías en lo cierto. Las interfaces son muy similares a las clases
abstractas y que su
funcionalidad fundamental es la misma. Ahora probablemente te estés
preguntando por qué. ¿Por qué tenemos tales entidades en Java que prácticamente
hacen lo mismo? Es casi como si los diseñadores del
lenguaje Java estuvieran
tratando de engañarnos. Bueno, resulta que
existen algunas diferencias entre clases abstractas e interfaces. Vamos a repasarlos. La mayor diferencia es que las clases
abstractas solo
admiten herencia única, mientras que las interfaces admiten
múltiples implementaciones. En Java, una clase sólo puede
heredar de como máximo, una clase que incluye clases
abstractas Perro marrón puede heredar de perro, pero no podríamos tener perro
marrón heredar
de otra cosa, como decir
animal marrón por Las interfaces
solucionan este problema. Las interfaces no se heredan
como lo son las clases. En su lugar, se implementan y una clase puede implementar
múltiples interfaces. En nuestro ejemplo de perro marrón, podríamos tener
perro marrón implementando una interfaz de perro e
implementando una interfaz animal marrón. Y entonces el perro marrón
tendría dos contratos para cumplir con la interfaz del perro y
la interfaz del animal marrón. Con base en esta información, las clases
abstractas son útiles cuando tenemos jerarquías de
objetos sencillas Las interfaces son útiles
cuando tenemos un objeto cuyos contratos deben mezclar y combinar métodos de
múltiples jerarquías Digamos que tenemos un perro moreno que
hereda de una clase de perros,
y la clase de perros hereda
de una clase de mamíferos Esta es una jerarquía lineal, y tiene sentido implementar nuestros contratos de método
como clases abstractas. Por otro lado, digamos que
tenemos un perro marrón, y nos gustaría que cumpliera con
la plantilla
de objeto de un animal de color. Y también nos gustaría que cumpliera con la plantilla de un
animal con patas. Los animales de color y los animales con patas son dos jerarquías de
objetos separadas Por supuesto, hay
muchos animales que deben cumplir ambos contratos, pero también hay animales que sólo cumplen uno u otro. Como puedes ver,
elegir interfaces o clases
abstractas se
reduce a cómo decides diseñar
tu jerarquía de clases Ahora veamos cómo
usamos realmente las interfaces en la práctica. Primero, definimos una interfaz
llamada animal con patas y declaramos un
método que debe
implementarse llamado get non legs. También definiremos una interfaz
llamada animal coloreado que declara un
método que debe
implementarse llamado get color. Ahora vamos a crear una clase de perro
marrón. Lo primero que quiero que
noten es que estamos usando la palabra clave implements
aquí en lugar de extends. Lo siguiente que quiero
que veas es que aquí hemos especificado múltiples
interfaces que deben ser implementadas
por brown dog. Si intentas hacer esto
con la palabra clave extends, Java arrojará un error. Esta es una característica
única de las interfaces, pudiendo implementar
múltiples cosas. Sin embargo, aparte de la
definición de clase, el resto de la clase se ve bastante similar a
lo que hemos visto. Ya que debemos
implementar todos los métodos declarados en las interfaces
que estamos implementando, definimos tanto get color
como get numb legs También agregamos la
anotación de anulación para ser explícito de que estas implementaciones
están destinadas a anular las declaraciones
en las interfaces Eso es más
o menos. En este video, hablamos de interfaces, que son un nuevo tipo
de clase que declara un contrato que deben cumplir las clases
que las implementen. Las interfaces permiten crear múltiples
patrones de herencia que no
se pueden hacer con clases
abstractas regulares. Aquí está el enlace al
código de repositorio utilizado en este video. Por favor visita el link fork the repo y
juguetea con el código Te veré en el siguiente video.
12. Enums: Hola amigos. En este video vamos a hablar de enumeraciones. Comencemos la
ilustración de hoy
definiendo una clase llamada dog one, que tiene un método get type
que solo devuelve brown dog. Digamos que también tenemos
una clase llamada dog two, que también tiene un método
get type, pero esta devuelve perro blanco. Por último, tenemos perro tres. Perro tres consigue tipo
devuelve perro amarillo. Sí, eso es un amarillo
con una H en lugar de una W. Ahora vamos a
juntarlo todo. Tenemos nuestras tres
definiciones de perros a la izquierda y luego a la derecha
instanciamos tres perros, una instancia para cada clase Digamos que queremos
ejecutar algunas comprobaciones simples. Solo queremos llamar, obtener
tipo en cada uno de estos perros. Después revisa la salida. Si la salida coincide con
algún valor esperado. Imprimiremos algo
para nuestro primer perro. Queremos comprobar si el tipo de perro de
uno es perro marrón. Para el segundo perro vamos a
querer comprobar si
es un perro blanco. Por último, para el tercer perro, queremos comprobar si
se trata de un perro amarillo. Bueno, ya que
accidentalmente mal deletreamos perro
amarillo en nuestro perro
tres obtenemos definición de tipo, esta condición
será falsa y
no imprimimos que el
perro tres es Eso no es un gran problema en
un programa sencillo como este, pero te puedo dar una situación de
mayor participación. Imagina que tu
sitio web busca tráfico de varios países y quieres cambiar
el idioma
del sitio web en función del
país del que es el usuario. Digamos que para
alguien en Japón, le gustaría establecer
el idioma
del sitio web en japonés. Similar a esta lógica, tendrías un montón
de declaraciones if. Elegir el idioma
del sitio web en
función del usuario punto get country. Ahora digamos que escribimos mal Japón en algún lugar de nuestro código Ahora bien, este usuario japonés no
va a obtener el idioma adecuado y simplemente te perdiste las ventas potenciales. Sería genial si pudiéramos proteger balas nuestro código
contra tales errores tipográficos, y tenemos una herramienta que
hace exactamente eso Vamos a crear una
clase enum llamada dog type. Por lo general, cuando creamos una clase, escribimos el nombre público de la clase. Pero aquí, tenga en cuenta que estamos
diciendo enum público, tipo
perro dentro de esta enumeración Luego definimos tres valores, amarillo, marrón y blanco. Tenga en cuenta que estos tres valores
no están entre comillas, no
son cadenas. Puede que aún no quede
claro cómo ayuda esto. Echemos un vistazo a
cómo usamos estos. Vamos a definir un nuevo
método para cada una de nuestras clases de perros
llamado get enum type Entonces podemos ver para perro uno, este método devuelve
tipo marrón y devolvemos tipo blanco
y doc tipo amarillo. Para los otros dos
perros, esto podría parecerse básicamente a
lo que teníamos antes, pero aquí hay una distinción muy
importante. Enum actúa de manera similar a una
variable o un campo
en Java, en que Java
realizará una búsqueda cuando lo
hagas referencia, cuando digo doc type brown, Java buscará realmente la
clase de enum tipo perro y verá si hay un valor dentro
de ella llamado Si no hay tal valor, Java fallará en compilar. Ese es uno de los principales
beneficios de las enumeraciones. Las enumeraciones permiten a Java
realizar una
comprobación de tiempo de compilación de que todos los
valores de referencia realmente existen Esto reduce la posibilidad de que escribas mal tus valores de
referencia Las enumeraciones también significan que hay
una fuente de verdad para los valores
constantes
en lugar de antes cuando escribimos manualmente cada
cadena para comparar valores Ahora podemos hacer
algo como esto, donde tenemos una garantía
más fuerte de que el valor constante al que nos estamos
refiriendo realmente existe. Si accidentalmente escribimos mal
doctype amarillo aquí, donde ponemos Y E L L
O H. Java
fallaría entonces al compilar porque comprobaría dentro de
la enumeración de tipo doc Date cuenta que no
existe tal cosa como doc tipo Y L L O H.
Eso es todo para este video. Hablamos de enumeraciones, que nos permiten definir valores
constantes para
nuestras aplicaciones Estos valores constantes
son útiles porque si alguna vez
tenemos una
referencia mal escrita a una enumeración, Java lanzará un error de
compilación y sabremos exactamente
dónde solucionar Las enumeraciones también proporcionan una fuente
de verdad para nuestras constantes. Define sus
constantes en un solo lugar, y siempre se refiere a
esas constantes en otra parte de
su programa en lugar de reescribir el valor una y
otra Aquí está el enlace al código
Repl en este video. Te veré en la siguiente.
13. Switch: Hola amigos. En este video vamos a
hablar de switch. Comencemos nuestra
ilustración con definiciones
similares
del último video. Tendremos un tipo perro con tres tipos de color y
tendremos un perro marrón cuyo método get type
devuelve el tipo perro marrón. Ahora en nuestro método principal, vamos a instanciar a un perro marrón Diremos si el tipo de perro marrón es estampado blanco ese
perro es blanco. Si el
tipo de perro marrón es amarillo, imprima que los perros son amarillos. Si el tipo de perro es marrón, imprime que el perro es marrón. De lo contrario, imprima que se desconoce el color del
perro. Ahora bien, en realidad no hay nada
malo con este código. Funciona perfectamente bien. Pero tenga en cuenta que aquí tenemos el mismo valor en
cada cláusula if. Y no sólo eso, tenemos la misma estructura lógica
en cada cláusula if, comparando el mismo valor
con diferentes tipos de enumeración Nuevamente, no hay nada malo esto desde un
punto de vista funcional, pero simplemente se ve torpe Resulta que Java tiene
una solución para eso. Aquí hay una forma alternativa de
escribir lo mismo. Antes de empezar a
hablar de este código, quiero que te eches
un vistazo tú mismo. ¿Puedes adivinar qué está haciendo cada
nueva palabra clave? Pausa el video y
cuando estés listo. Veamos qué tan cerca estuviste. En primer lugar, esta
cláusula de cambio en la parte superior
básicamente está diciendo
que queremos comparar este valor una y
otra vez. Vamos a comparar
el valor dentro de los paréntesis de cambio con
los valores que siguen a estas palabras clave de mayúsculas y minúsculas Esta cláusula del primer caso es
más o menos equivalente a si punto de perro
marrón get type es
igual al tipo perro blanco. El segundo es equivalente a si doggettype
marrón es igual
al tipo perro amarillo Probablemente puedas adivinar qué significa
la cláusula del último caso. Observe que en este caso
las cláusulas no decimos perro tipo blanco y
perro tipo amarillo. Nosotros solo decimos blanco y amarillo. La razón es que
en los bloques de switch, Java deducirá el tipo de enumeración, el valor en los paréntesis de
conmutación, y espera que solo escribas los valores de enumeración sin
el nombre de clase
enum al frente Ese es un punto bastante menor, pero solo tenlo en cuenta si
te encuentras con algún error. Por último, este caso por defecto es aproximadamente equivalente a
else, pero no exactamente. En realidad significa ejecutar siempre este caso si el programa
llega a esta línea. No obstante, sólo
llegamos a este caso en el caso Ls debido a
estas declaraciones de ruptura. Pero, ¿qué son? Resulta que estas
sentencias break detienen evaluación
adicional
dentro del bloque de switch si la ruta del código
alguna vez las alcanza. Por ejemplo,
digamos que no
tuvimos la ruptura en la
cláusula marrón en el caso Brown. Si ese fuera el caso, entonces se ejecutaría
todo este código. Imprimiríamos
que el perro es marrón. Y entonces como ya
no hay línea de freno, Java seguiría ejecutando
el código en el siguiente caso. El siguiente caso aquí
es el caso por defecto. También imprimiremos el color de perro
desconocido. Como puede ver, si nuestro bloque de interruptores tuviera
muchos más casos en
él, sería una gran pérdida de
tiempo si seguimos ejecutando el código incluso después de que ya encontramos el tipo
de perro marrón. En general, cuando solo
esperas que se
iguale un caso, es una práctica recomendada establecer
una línea de freno en cada caso. Eso es todo para este video. En esta lección,
hablamos de switch, que básicamente es solo
una forma más concisa de escribir repetitiva
si otra lógica Aquí está el enlace al código
Repl en este video. Te veré en la siguiente.
14. Guía completa de dragaminas 2: Bienvenidos amigos. En este video, vamos a
recorrer la segunda parte de este proyecto utilizando lo que hemos aprendido en las últimas lecciones, específicamente enumeraciones y switch Esta vez
en realidad vamos a echar un vistazo a la clase principal. Están pasando muchas cosas
en este archivo. Antes de comenzar, tómate
un momento para leerlo. Está bien si hay
partes que no entiendes. Muchos de los nombres de las variables
son bastante descriptivos y al menos
deberían
darte una pista
decente lo que está haciendo. Ahora pasemos por
esto juntos. Primero creamos un tablero, imprimimos el tablero, y luego comenzamos un bucle
infinito aquí. Esta línea de entrada del escáner
básicamente es solo decirle a
la consola que vea lo que ingresó
el usuario en
el turno actual. Recordemos en nuestra demostración
que hicimos cosas como fila de
bandera y columna de fila de
toque. Lo que sea que ingreses en la
consola se guardará en esta cadena de entrada del
usuario aquí, la división de entrada del usuario solo
significa que vamos a separar la cadena única en
función del espacio en blanco. Por ejemplo, cuando tenemos
tap space a space B, entonces deberíamos terminar con una matriz que tenga
tres elementos en él. El primer elemento será tap, el segundo elemento será A, y el tercer
elemento debe ser B. Es por
eso que si la longitud
de la matriz no es tres, rechazamos el comando
e iniciamos el bucle de nuevo. Puede que no estés familiarizado
con esta línea de continuar. Todo lo que hace es decirle a Java que salte el resto del bucle
y comience por la parte superior. Nuevamente, vamos a volver
a la parte superior de este bucle y, Comprobar la siguiente entrada del usuario. Aquí tenemos fila
igual a uno negativo, seguido de un bucle vacío. Columna es igual a uno negativo, seguido
también de un bucle vacío. Volveremos a
esto en un video posterior. No es súper
importante por ahora. Sólo debes saber que fila y columna van a
ser enteros que representan los índices
del tablero sobre
el que al usuario le gustaría
realizar una acción Por último, llegamos a una parte del código que nos
interesa. Aquí creamos un lingote
llamado célula segura. Tenemos un
bloque de interruptores vacío que lo sigue. A continuación decimos que si es seguro celular es
falso, luego juego terminado. Esto implica que
este bloque de conmutación debería estar cambiando el
valor de la celda segura. De lo contrario, es seguro celular
simplemente siempre será verdad. Y sería redundante
tener este caso F aquí mismo. Piensa en el último paseo
por el que hicimos. ¿Se te ocurre el método que implementamos que devuelve un valor de lingotes indicando si un grifo era
un grifo seguro o no La respuesta es que
implementaste el método tap. Recordemos que teníamos
este método
Tap que registra que
la celda ha sido que registra que
la celda ha sido tocada para las celdas numéricas
y las celdas vacías
volverán true para
las celdas mentales, devolvemos false Y si exploraste
un código un poco más, habrías visto que en Board Java también tenemos un
método tap. ¿Y qué hacemos? Primero, tocamos la
celda ubicada en columna de la fila de
índice y guardamos el resultado de ese toque en
este resultado de toque de lingotes Si era un grifo seguro y no hay
minas rodeándolo, entonces tocamos todas las celdas
vecinas a su alrededor y volvemos verdad. De lo contrario, si grabamos
una mina, devolvemos falso. Eso implica que dentro de
este bloque de switch, deberíamos estar llamando a
tap row column, guardar el resultado de esa
llamada en es celda segura. Pero recuerde,
se usa un bloque de interruptores cuando tenemos
múltiples casos para verificar qué casos
deberíamos estar verificando dentro de
esta caja de interruptores. Una vez más, pausar el
video y pensar lo que discutimos estaba sucediendo
antes en la balda. Voy a revelar la respuesta en 321. Bueno, la única vez
que obtenemos un valor para celular es segura es cuando
tocamos una celda. Pero esas no son las únicas
acciones que un usuario puede tomar. Recuerda del
video de introducción del proyecto que un usuario también puede marcar y desmarcar una celda si
olvidaste lo que hacen esos Básicamente, flag
marcará una célula como una mente potencial
pero no tocará la celda. quitará una bandera de También quitará una bandera de
la celda sin
tocar la celda. Debido a que el comando user
va a tomar la columna form action row, vamos a poner el comando cero dentro de estos
paréntesis aquí mismo Nuestro primer caso
va a ser un grifo. Si el usuario ingresa un tap como comando,
entonces vamos a decir,
entonces vamos a reasignar el valor de una celda segura para que sea el resultado de tocar en
el tablero en
la columna de fila de
posición No olvides, después realizar cualquier acción que
queramos realizar
dentro de este caso, necesitamos dejar una
declaración break antes del siguiente caso. Si el comando user era una bandera, ¿qué método debería recordar? Bueno, aquí hay una buena oportunidad para usar nuestras habilidades de lectura de código. Veamos qué otros métodos
hay en la clase board. Tenemos un
método está resuelto aquí mismo, pero eso
realmente no parece probable. Oye, aquí tenemos una bandera
y un método sin alimentar. Esos parecen encajar en nuestro caso de uso, vamos a usarlos de nuevo
en nuestra clase principal. En el caso de bandera,
vamos a llamar a flag column. Dado que este método devuelve, realmente no pretendemos usar el valor de retorno de este método para hacer otra cosa, simplemente
rompemos. Por último, tendremos
nuestro último caso, que es el caso de la bandera aquí. Haremos columna de bandera, luego también vamos a romper. Sin embargo, tenemos un pequeño
problema aquí. Es totalmente posible
que un usuario pueda ingresar alguna cadena aleatoria
como el comando de entrada, o que el usuario
haya
escrito accidentalmente la marca tap flag o unflag Pero queremos que
este código sea más robusto y aquí es donde entran en juego
las enumeraciones Predefinamos algunos valores
posibles que queremos
aceptar del usuario Aquí arriba en la acción, um,
sigamos adelante y
definamos unflagg, tap Realmente no importa en qué
orden los escribas. Ahora aquí, vamos a convertir estos valores de caso de
cadenas, valores de enumeración Esto protegerá contra
posibles error tipográfico. Sigamos adelante y
cambiémoslo en un grifo. Hagamos esto en una bandera, hagamos esto en una bandera de la ONU. Pero ahora tenemos un pequeño problema. Recuerda que Java inferirá
el tipo del valor en estos paréntesis y verificará que
ese tipo coincida con el tipo
de estos valores de caso Pero ese no es el caso aquí. El tipo de comando
cero es una cadena. El tipo de estos
valores de caso es una enumeración de acciones. ¿Cómo convertimos una cadena
en una enumeración de acciones? Bueno, esta es una oportunidad
fantástica para flexionar nuestras habilidades de Google. Sigamos adelante y Google
Java cómo convertir una cadena, una cadena, en una enumeración Sigamos adelante y haga clic
en el primer resultado aquí mismo. Nos desplazamos hacia abajo. Realmente no necesitamos
leer la mayor parte de esto, pero podemos ver
aquí mismo en el bloque de código, te
están diciendo que tienen una enumeración llamada estado Pisa Um, y tiene un
valor dentro de ella. Enum de estado de pieza. ¿Listo? Vamos a
desplazarlo un poco más hacia abajo. Vemos que tenemos este
ejemplo, el estado de Pisa enum. Excepto que esta vez derivamos
el valor de la enumeración, no diciendo patatenum, listo,
sino pieza de estado, valor de enum de cadena, Esa es una
pista bastante buena ya
que nos dice que el método value de una clase enum convertirá
una cadena en una adelante y usemos eso
en lugar del comando cero, hagamos el valor
de acción del comando cero. Ahora eso es prácticamente todo lo que tuvimos que hacer para este paseo. Desafortunadamente, una vez más, no
podremos
ver el resultado de lo que hicimos hasta que
terminemos todo el proyecto. Pero espero que te quedes
por ahí para ver el resultado final. Eso es todo por este video. Gracias por mirar y te
veré en la siguiente.
15. Excepciones: Hola amigos. En este video vamos a
hablar de excepciones. Revisemos el ejemplo que
teníamos en el video anterior. Recordemos que nuestra
enum tipo perro tenía tres tipos, blanco, marrón y amarillo Si el tipo perro coincidiera con
alguno de estos tres casos, imprimiríamos una declaración y luego saldríamos
del bloque de interruptores. La única vez que golpearemos
este caso predeterminado es si tipo de perros
marrones no es ninguno
de estos tres colores, pero luego solo tenemos
estos tres tipos definidos. ¿Cuándo nos
encontraríamos con este caso? Bueno, podría ser si el tipo es nulo o tal vez en el futuro terminemos
sumando un tipo de perro extra. Pero olvídate de actualizar
este bloque de interruptores. Pero en términos generales, en realidad no
esperamos llegar a este
caso predeterminado en la mayoría de los casos de uso. Si golpeamos este
caso predeterminado con este código, en realidad
vamos
a obtener un error silencioso. Tendremos una línea extra que se está
imprimiendo , color perro desconocido. Pero el programa funciona bien. No falla en compilar y no hay error
cuando lo ejecutamos. No sabemos si se
esperaba o no imprimir el color
desconocido del perro . En cambio, lo que debemos
hacer es lanzar una excepción. Aquí hay un ejemplo de uno de los
tipos de excepciones más comunes, excepción estatal
ilegal. Anote esto en el texto aquí. Decimos tirar, que le dice a
Java que lance un error. Y luego proporcionamos una nueva
instancia de la excepción con nueva y pasando un
mensaje de error a la excepción. Ahora bien, si Java llega alguna vez a
esta línea de código, se
lanzará
un error cuando ejecutes el programa y el
programa se detendrá. Esto en realidad es algo bueno. Digamos que agregaste un tipo de perro
extra llamado Azul, Pero olvidaste
agregar un estuche para ello. Quieres que el código se detenga
y te diga que hay un tipo desconocido en lugar de seguir corriendo como
si nada hubiera pasado. Es difícil de ver con
este pequeño programa. Pero imagina que tienes una aplicación mucho
más importante. Por ejemplo, digamos que
hay una aplicación que te dice cuánto
dinero tienes en el banco. Es mucho mejor para
el banco decir que
hubo un error al cargar
tu cuenta en lugar fallar
silenciosamente y decirte
que tienes 50.000 dólares
negativos en tu cuenta
tanto para el desarrollador
como para el usuario de la aplicación El error explícito es mucho más informativo que la salida
arbitraria y rara. El beneficio agregado para
el desarrollador es que el error
personalizado realmente
te dirá dónde sucedió algo
inesperado. También facilita
mucho la depuración. Eso es todo para este video. Hablamos de excepciones que detienen
deliberadamente programas
con el mensaje de error personalizado. Aunque a primera vista, estos pueden parecer
algo terrible para agregar a tu programa. Pero, de hecho, ayudan a garantizar la estabilidad
del programa al proporcionar controles de
cordura y
proporcionar pistas
al desarrollador en caso
de que se produzca un error Aquí está el enlace al
código de repeler utilizado en este video. Te veré en la siguiente.
16. HashMap: Bienvenidos amigos. En este video vamos a
hablar del mapa hash. El ejemplo de hoy es bastante corto y puede caber en un solo archivo. Lo primero que
quiero que noten es esta importación en la
parte superior del archivo. El mapa hash es una estructura de
datos que se incluye en el paquete
Java Util, que es un paquete incorporado A continuación, echemos un vistazo a
cómo declaramos un Hashmap. Como de costumbre, primero declaramos el tipo de la variable
que es un Hashmap Entonces usamos estos
corchetes angulados para especificar los tipos de las claves y
valores dentro de este mapa. El entero entre corchetes
angulares especifica el tipo de las claves. La cadena entre corchetes especifica el tipo
de los valores. Una clave es básicamente
algo que
vamos a usar para buscar valores. Por ejemplo, piensa en la lista de
contexto en tu teléfono. Cuando quieres buscar el número de teléfono de
tu amigo, primero
buscas
su nombre. Al hacer clic en el nombre, su teléfono mostrará el número de teléfono de
su amigo. El nombre de tu amigo es una clave que asigna a un número de teléfono
que es un valor. En este caso, vamos a estar mapeando enteros a cadenas También observe que usamos entero I
mayúscula
aquí en lugar de t
minúscula cuando
declaramos tipos enteros que están contenidos dentro de otros
objetos como una clave dentro de un mapa, usamos entero I mayúscula, pero por lo demás entero
mayúscula y T
minúscula son
prácticamente intercambiables. A continuación veamos cómo
instanciamos un mapa hash. Observe que aún
incluimos los corchetes angulares, pero no ponemos
nada en ellos. Eso es porque esta
sintaxis le dice a Java que simplemente inferya los tipos
de claves y valores Desde el lado izquierdo
de esta asignación, Java sabrá
crear un mapa hash con claves enteras
y valores de cadena. En la siguiente línea, mapa poner uno amarillo dice que ahora
estamos mapeando uno a amarillo dentro del mapa mapa punto puesto a marrón significa que
mapeamos dos a marrón. Cuando imprimimos mapa punto obtener uno, imprimimos amarillo. Cuando imprimimos mapa punto obtener dos, imprimimos marrón. Parece bastante simple
y suele ser. Una cosa que quiero
llamar aquí es que estos consigue y pone suceden
en tiempo constante. Realmente no hemos
hablado de lo que significa esta O de una notación
porque no es realmente un
foco en esta clase. Realmente no necesitas saber a
detalle lo que está pasando, pero te voy a dar
un breve resumen. El
mapa hash y hash es en realidad un mecanismo en
la
programación que permite a la computadora almacenar
objetos de una manera tal que sea muy fácil y rápido
recuperarlos posteriormente. Todavía lleva tiempo recuperar
y almacenar esos objetos, pero el tiempo es prácticamente
insignificante en la mayoría de los casos de uso Los mapas son muy buenos
para almacenar datos. Muy bien, así que eso
es todo para este video. Hablamos del mapa hash, que es una estructura de datos que almacena y mapea claves de valores. Hace todo esto
en tiempo constante, lo que significa que la latencia requerida
para escribir y leer desde el mapa no aumenta mucho ya que aumentamos el
número de elementos en el mapa. Aquí está el enlace al
código de repeler utilizado en este video. Te veré en la siguiente.
17. Anexo de mapas: Bienvenidos amigos. En este
video vamos a repasar una característica adicional de
Java relacionada con los mapas hash. Aquí está el ejemplo que tuvimos en el video anterior con un
poco más de código en él. Primero, vamos a importar
Java util dot map. A continuación, echemos un
vistazo a esta línea. Abajo, declaramos
una variable llamada x y le damos un tipo de
mapa, entero, entero. Lo instanciamos
usando el mapa 1234. Un par de cosas a tener en cuenta aquí. Primero, un mapa no es
lo mismo que un mapa hash. Un mapa es en realidad una interfaz, y un mapa hash es una
implementación concreta de
esa interfaz. Segundo, un mapa creado con
mapa de será inmutable, lo que significa que no se pueden modificar sus claves o valores
una vez Este mapa de sintaxis parece gracioso, pero básicamente equivale
a mapear la clave uno al valor dos y la clave
tres al valor cuatro. Si conseguimos
uno, vamos a conseguir dos. Ya que uno se mapea a dos, si hacemos x punto obtenemos dos, obtendremos un valor nulo porque
dos es un valor, no una clave. Como la clave dos no
existe, obtenemos un resultado nulo. Por último, el docket tres nos
dará cuatro, ya que las claves y los valores se
alternan en el mapa de llamada de creación y
lo especificamos tres después del valor dos Eso es todo para este video. Solo quería
darte una introducción a una forma rápida de crear
una instancia de
un mapa si no quieres primero
crear el mapa y
luego llenarlo con claves y valores uno por uno
para recapitular rápidamente Los mapas creados de esta
manera son inmutables. Cuando lo hacemos, alternamos claves y valores dentro
del mapa de llamada. Aquí está el enlace al código de
repeler en este video. Te veré en la siguiente.
18. HashSet: Bienvenidos amigos. En este video, vamos a
hablar del conjunto hash. El ejemplo de hoy es bastante similar al
del último video. Encaja en un archivo, e incluso la sintaxis es bastante
similar. Vamos a meternos en ello. Lo primero que
debes notar es que al igual que el mapa hash, conjuntos
hash deben importarse
explícitamente. Los conjuntos de hash también viven en
el paquete Java Util. A continuación, veamos la declaración de la
variable. Declaramos un conjunto hash, y luego dentro de estos corchetes
angulados
declaramos el tipo de los elementos que estarán
contenidos dentro de él. Usamos capital I integer ya que estamos envolviendo
los enteros en un contenedor, igual que listas o mapas hash, al instanciar
los conjuntos hash, no
necesitamos
especificar el tipo de los elementos en
el
lado derecho de la Podemos simplemente poner corchetes
en ángulo vacíos, y Java inferirá el
tipo de los elementos a partir de
la declaración de la variable en el lado izquierdo de la asignación El método ad nos permite
almacenar artículos en el set. Tenga en cuenta que Java
no le permitirá poner un objeto de otra cosa
que no sea un entero en el conjunto. No podrás poner
cadenas o valores de lingotes. Obtendría un
error de tiempo de compilación si lo intentara. Aquí, si intentamos sumar 35 después de que ya lo
hicimos antes, nada va a cambiar realmente. Esta es una de las
características clave de los conjuntos hash. Los juegos de hash solo
almacenarán artículos únicos. Si intentas agregar
el mismo elemento dos veces, Java no se
equivocará, pero tampoco hará
nada diferente. También tenemos un método de tamaño, y probablemente puedas
adivinar qué hace eso. Simplemente devuelve el número
de artículos en el conjunto. En este caso, son dos. Como solo tenemos
35.91 en el conjunto, el método contenido
devuelve true o false dependiendo de si
el
ítem solicitado ya está en el conjunto Es cierto para 35 y
es falso para 36. También puedes eliminar
elementos del set. Si llamas a elementos
que eliminan 35, entonces 35
ya no estará en el set. Podemos confirmar llamando a
los artículos que contienen 35, los cuales devolverán false. Ahora una última
comida para llevar clave para ti. Al igual que los mapas hash, los conjuntos de hash también utilizan el mecanismo de hash. No necesitas conocer los
detalles sino solo saber que estas llamadas contienen
agregar y eliminar, todas ocurren en tiempo constante. Lo que significa que el tiempo requerido
para ejecutar estos métodos
no aumenta significativamente a medida
que crece el tamaño del conjunto. Esto puede ser muy útil
cuando desea utilizar una estructura de datos para búsquedas y almacenamiento realmente
rápidos. Digamos, por ejemplo, que
quieres verificar si un determinado anuncio
ya se ha reproducido para un usuario. De esa manera, siempre podemos
reproducir anuncios únicos. Bueno, una forma en la que podrías
representar es que cada objeto de usuario tiene un
conjunto hash asociado a él o ella. Ese conjunto contiene
los
objetos publicitarios que ese usuario ya
ha visto. Ese es sólo un ejemplo básico. Y tendremos otro caso de uso para los conjuntos hash en el proyecto, que verás muy pronto. Bien, y eso
es todo para este video. En esta lección,
hablamos de conjuntos de hash que nos permiten almacenar
valor para búsquedas posteriores. También tienen derechos de lectura de
tiempo constante, lo que los hace muy útiles
en diversos casos de uso, como el
ejemplo publicitario único del que hablamos. Aquí está el enlace de repo para
el código en este video. Te veré en la siguiente.
19. Guía completa 3: Bienvenidos amigos. En
este video vamos a recorrer una de las partes más impactantes del proyecto Usando lo que hemos aprendido
en los últimos videos en tablero Java. Desplázate hacia abajo hasta este método llamado reunir celdas vacías
vecinas. Echemos un
vistazo a lo que hace. Este bloqueo Q vinculado a clase Q puede que no
le resulte familiar, no se preocupe por eso. No es tan relevante
para el curso. Todo lo que realmente necesitas saber
sobre esto aquí mismo, es que nos está ayudando a realizar algo llamado BFS,
o Breadth First search Eso es aliento, como en B, R, E, A, D, T, H. No
hablamos de eso en el discurso. Y no es realmente
necesario que sepas cómo
funciona específicamente. Pero siéntete libre de
buscarlo en Google si tienes curiosidad porque es
un concepto muy chulo. En este método, nuestra
búsqueda BFS está recopilando todas las celdas vacías que están adyacentes a la
fila y columna proporcionadas Una vez que recoge todas las celdas vacías
adyacentes, luego busca celdas
vacías que son adyacentes a las celdas vacías que ya
hemos recopilado. Y luego seguimos
buscando celdas vacías adyacentes a esas
celdas vacías, y así sucesivamente. Como habrás adivinado,
esto es parte
del código que maneja un
toque en una celda vacía Recordemos que cuando
tocas una celda vacía, normalmente
nos tocan una gran parte
del tablero Eso se hace a través de este método, que le dice al programa
dónde se encuentran todas las celdas vacías adyacentes a la celda en la que
tocó Antes de continuar, quiero
reconocer que algunos de ustedes pueden sentirse un poco frustrados con
estos paseos A lo mejor te apetece, oye, ¿por qué no hablamos de BFS
en el paseo a través de videos ¿Por qué nos están introduciendo nuevas estructuras de datos y
algoritmos en este proyecto? Bueno, hay un par de
razones para ello. El principal es que
una gran parte de ser programador es
poder leer código desconocido, entenderlo al menos
parcialmente, y luego modificarlo No es cierto que haya una cantidad finita de
Java que puedas aprender Y solo después de que lo
hayas aprendido, estarás listo para abordar
todo el código del mundo. La verdad es que hay un montón de gente inteligente por ahí. Y la gente usa todo tipo de
algoritmos y códigos difíciles de entender. No hay una cantidad mágica de Java que necesites saber antes de estar listo
para enfrentar el mundo. Aprender a trabajar
con código con el que no estás 100% familiarizado es
una realidad cotidiana. Si has llegado
hasta aquí en el curso, me alegro de que sigas aquí y aprendas a
aprender conmigo. Bien, ahora por fin
echemos
un vistazo más de cerca a algunos
componentes clave de este método. Mira esta variable llamada, sobre todo la línea de
aquí mismo que dice pole split. Lo que está haciendo
es eliminar una cadena de la estructura de
datos, separar la cadena en componentes usando el delimetro, y luego guardar el resultado de esa división en coordenadas
invariables Por ejemplo, si
hubiera un elemento en la Q que fuera una cadena a B, entonces el resultado de
dividir por el sería una matriz de dos elementos cuyo primer elemento sería y cuyo segundo
elemento sería B. Aquí puedes ver
que en nuestro caso, A es en realidad
un índice de fila y B es en realidad
un índice de columna. Utilizamos estos índices para
seleccionar una celda en nuestro tablero, y luego tenemos esto que hacer. De hecho, es muy difícil entender lo que
tenemos que hacer aquí. Si nunca has visto BFS, no te desanimes
si te sientes Pero te diré lo que está
pasando aquí. En este bucle que sigue
al hacer tenemos esta línea A más j. Como probablemente puedas adivinar,
Ad agregará la cadena, se la
damos a Q.
Una cosa que quizás no
notes de inmediato aunque, es que podríamos agregar
infinitamente elementos a Q. Y entonces nunca saldremos este bucle que comprueba
si Q está vacía Básicamente, la idea es que solo
queremos realizar
este bucle anidado aquí, máximo una vez, por
cada celda de la placa Pero ahora mismo, si
ya has visto la fila A en la columna B, aún
podrías agregar
accidentalmente una B a Q y volver a pasar por este bucle
anidado Así que tenemos que hacer un seguimiento de todas las celdas que
ya hemos visitado. Queremos almacenar
celdas que
ya hemos visto en la estructura de
datos y luego solo ejecutar este bucle
doble anidado en la celda actual
no ha sido visitada ya ¿Se te ocurre
una estructura de datos que hayamos aprendido que permita una inserción rápida
y búsquedas rápidas? Piénsalo y haré una pausa el video y te
responderé en 321, la respuesta es un conjunto hash. Podemos almacenar celdas que
ya hemos visitado en un conjunto hash. Eso significa que si te encuentras con una celda que no está
en el conjunto hash, eso significa que nunca antes te has
encontrado con una celda. De esta manera, podemos
asegurarnos de que solo ejecutamos este bucle doble anidado en
cada celda como máximo una vez Esto es lo que tenemos que
hacer Primero
aquí arriba vamos a
instanciar nuestro
conjunto de hash llamado scene Entonces aquí abajo vamos a comprobar
primero ¿
ya hemos visto esta celda? Podemos usar los conjuntos
contiene método para T. Luego envolvemos todo
este bucle
cuatro doble anidado dentro de aquí y volteamos esto
a un negativo Si aún no hemos
visto la celda dada, entonces agregamos esta celda
al conjunto de hash de escena porque ahora
hemos visitado esta celda. Ahora que hemos
visitado esta celda, realizamos nuestro loop. Ahora nos aseguramos de que
este bucle
nunca se vuelva a ejecutar. ¿Por qué es eso? Bueno, veamos, 1 segundo. Creo que me
equivoqué esta sangría. Ahí vamos. Bien. ¿Por qué funciona esto? Digamos que nos encontramos con una célula que nunca
antes se había visto. No va a
estar dentro de escena. Lo agregamos a escena, y luego realizamos
este doble loop. Digamos que
accidentalmente agregamos la celda que acabamos de ver por
dentro, de vuelta dentro de Q. Entonces cuando
pasemos por
el bucle, de nuevo, vamos a eso
vamos a hacer pop la celda que
ya vimos fuera de la que. Y entonces vamos a comprobar si escena no contiene reventado Bueno, porque
ya agregamos la celda que vimos a la
escena se ha puesto aquí, entonces para cuando volvamos a esta declaración si
en la siguiente ronda, esta volverá falsa. No podremos
ejecutar este bucle for doble anidado en esa
celda otra vez Eso es todo para este video. Ahora hemos cumplido nuestra tarea. Estamos a solo una pieza de poder
jugar nuestro juego. Te veré en el siguiente video.
20. Guía completa de dragaminas 4: Bienvenidos amigos. En este video finalmente
vamos a
completar nuestro juego. Cuando termines
con este video, deberías poder jugar
el juego de forma interactiva y compartir el enlace con tus amigos para que ellos también puedan jugar. Bien, para la primera
parte de este recorrido, vamos a
volver a visitar Board Java En la parte superior de este archivo, deberías ver que tenemos este mapa letra a num definido. Recuerda que cuando
juegas el juego, nuestros comandos toman la forma. Acción, fila, columna como a, B. Nuestra fila y columnas
se ingresan como letras, pero necesitamos convertir
estas letras en índices. Y nuestro tablero buscaminas, nuestros índices de tablero,
van a comenzar de arriba a abajo,
de
izquierda a En otras palabras, A
mapea para indexar cero, mapas para indexar uno y mapas para indexar
dos, y así sucesivamente. Aquí, solo necesitamos
definir esas asignaciones.
Hagámoslo. Tenemos un mapeo a cero, mapeando a uno
Lo rápido a tener en cuenta, el hecho de que dejé una nueva línea entre cada par de valores, los valores
Clave en realidad
no es necesario. También puedes simplemente poner
estos todos en una línea. Yo solo la pongo en diferentes
líneas para que se vea mejor. Además, asegúrate de
tener comillas dobles
alrededor de tus llaves. Si pones comillas simples, eso es en realidad un tipo de
Java diferente llamado carácter. A continuación vamos a
ir a Java Principal, desplazarnos hacia abajo hasta donde
tenemos fila entera igual. Aquí es donde hacemos la
conversión de letra a número. Recordemos del video
anterior donde
hablamos de esta
matriz de comandos aquí mismo, cuando nos dividimos por espacio en blanco, dividimos el comando de usuario
en tres elementos. El comando es el
primer elemento, la letra de fila es
el segundo elemento y la letra de columna
es el tercer elemento. Recuerda, nuestros índices
empiezan en cero. Eso quiere decir que la letra de la fila va a estar en el índice uno. En comandos, vamos a recuperar el mapeo
de números de la fila haciendo carta de
tablero a nu mapa obtener comandos uno aquí. Esta carta al mapa entumecido es lo que acabamos de
definir aquí Se va a tomar la
letra de fila que el usuario introduce y luego buscar el índice
numérico que
esa letra corresponde al que acabamos de definir en
la otra clase Del mismo modo, hagamos lo mismo para
la carta del tablero de
columnas para adormecer los comandos mapget Ahora en realidad necesitamos agregar algunas mejoras y
corregir
un error tipográfico que hice en videos
anteriores en Board Java donde implementamos reunir celdas vacías
vecinas, cambiar de escena a celdas de escena La última línea de
este método aquí
en realidad esperamos que exista una variable
llamada celdas de escena. Ese fue mi mal, me disculpo. Cambiemos la
escena a celdas de escena. Por último, en las
clases de celda que
implementamos en uno de los
primeros recorridos para esto, asegúrate de
tener el caso tapped, el caso tapped antes de que el caso sea
marcado Esto se debe a
que una vez que toca una celda, ese estado de celda es final. No se puede abanderarlo ni enderezarlo. Sin embargo, si es flag viene primero
en el método de dos cadenas, entonces eso significa que si primero marca una celda y
luego la toca, el tablero seguirá
renderizando el símbolo del triángulo para
el tablero en lugar
del estado tapped ya que comprueba el toro bandera antes que
el toro tocado No te preocupes si eso es un poco
confuso, es un error complicado. El punto principal de este proyecto
era practicar la codificación, no encontrar errores oscuros.
No te preocupes por ello. Ahora intentemos hacer clic en Ejecutar y jugar nuestro juego. Bonito. Parece que el
juego está funcionando. Nos están revelando
celdas numéricas, celdas
vacías reveladas en
todos los lugares adecuados. También podemos intentar marcar, y obtenemos una bandera en
el lugar correcto Bien, así que eso
es todo para este video. Gracias por llegar hasta aquí. Ahora puedes jugar el juego
y compartirlo con tus amigos. Te veré en el siguiente video.
21. Conclusión del módulo 2: Hola otra vez. Bienvenidos
al final de este curso. Enhorabuena. Ahora has
construido una tarifa de minas de trabajo por juego que puede generar
más de 1 billón de configuraciones Y puedes usar
estos para desafiar a tus amigos y
presumir en tu currículum. Y por cierto,
no estoy exagerando, realmente
me refiero a
más de 1 billón Puedes revisar mis
matemáticas. También has aprendido varias formas
de diseñar código. Usando herencia,
clases abstractas e interfaces. También has aprendido sobre estructuras de datos
útiles como mapas hash y conjuntos. Puede que sea difícil
creerme en este momento,
pero a medida que
avanza en su carrera, en realidad va
a encontrar que muchas tecnologías
avanzadas en
realidad solo se construyen sobre cosas básicas
como la herencia y las estructuras de datos
básicas, como las que
aprendió en este curso. Por ahora solo tendrás que tomar
mi palabra para ello. Pero al final, espero que algún día veas a lo que me refiero. Lo más importante es que la programación es una habilidad en la que todos están
aprendiendo continuamente. No prometo
haberte enseñado
todo lo que hay que saber
sobre la programación Java, pero sí espero
haberte dado una imagen más clara de los fundamentos para
que estés bien equipado para aprender
aún más por tu cuenta,
ya sea a través de
mis cursos futuros
o a través de los de otra persona Una vez más, enhorabuena
por terminar el curso, y les deseo todo lo
mejor hasta la próxima vez.