Construye tu propio juego de buscaminas en Java | Alvin Wan | Skillshare

Velocidad de reproducción


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Construye tu propio juego de buscaminas en Java

teacher avatar Alvin Wan, Research Scientist

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Lecciones en esta clase

    • 1.

      Introducción

      1:34

    • 2.

      Acerca de ti y de mí

      3:27

    • 3.

      Introducción al proyecto

      7:05

    • 4.

      Ilustración de herencia

      3:09

    • 5.

      Ejemplos de herencia

      3:31

    • 6.

      Súper ejemplos

      2:24

    • 7.

      Polimorfismo de subtipos

      4:40

    • 8.

      Ilustración abstracta

      3:53

    • 9.

      Ejemplos abstractos

      7:09

    • 10.

      Guía completa de dragaminas 1

      10:57

    • 11.

      Interfaces

      4:20

    • 12.

      Enums

      4:39

    • 13.

      Switch

      3:47

    • 14.

      Guía completa de dragaminas 2

      9:14

    • 15.

      Excepciones

      2:57

    • 16.

      HashMap

      3:14

    • 17.

      Anexo de mapas

      1:48

    • 18.

      HashSet

      3:22

    • 19.

      Guía completa 3

      7:11

    • 20.

      Guía completa de dragaminas 4

      5:19

    • 21.

      Conclusión del módulo 2

      1:15

  • --
  • Nivel principiante
  • Nivel intermedio
  • Nivel avanzado
  • Todos los niveles

Generado por la comunidad

El nivel se determina según la opinión de la mayoría de los estudiantes que han dejado reseñas en esta clase. La recomendación del profesor o de la profesora se muestra hasta que se recopilen al menos 5 reseñas de estudiantes.

149

Estudiantes

1

Proyectos

Acerca de esta clase

Este curso es impartido por el profesor invitado Derek Wan (enlace a la página de perfil de Skillshare)

[Los temas discutidos se basan en los presentados en mi otro curso https://skl.sh/445M6ks. Aunque no es un requisito estricto, te recomiendo que visites mi curso anterior si te pierdes en estos videos]

Esta clase cubre conceptos básicos de Java y te enseña todo lo que necesitas saber para construir un juego de buscaminas capaz de generar más de 17 billones de configuraciones de juego. Este curso te equipará con las habilidades necesarias para abordar grandes proyectos de codificación y escalar tus programas con una complejidad creciente.

Qué aprenderás

  • Herencia
  • Super
  • Polimorfismo
  • Clases abstractas
  • Interfaces
  • Enums
  • Switch
  • Excepciones
  • HashMaps
  • HashSets
  • Replit

¡No se requiere hardware o configuración especializada para aprender Java conmigo! Todo el código se ejecutará en un entorno de aislamiento en tu navegador que tiene todas las dependencias ya instaladas y configuradas para ti.  Puedes concentrar toda tu energía en Java, en lugar de regatear con las peculiaridades de tu computadora. Todo lo que necesitas para este curso es Internet, tu dispositivo y algo de tiempo libre.

Las diapositivas se pueden encontrar aquí: https://drive.google.com/drive/folders/1ZmmSP7P82_LJZ9OXhg5kWbYei2e5UIPu?usp=sharing

Conoce a tu profesor(a)

Teacher Profile Image

Alvin Wan

Research Scientist

Top Teacher

Hi, I'm Alvin. I was formerly a computer science lecturer at UC Berkeley, where I served on various course staffs for 5 years. I'm now a research scientist at a large tech company, working on cutting edge AI. I've got courses to get you started -- not just to teach the basics, but also to get you excited to learn more. For more, see my Guide to Coding or YouTube.

Welcoming Guest Teacher Derek! I was formerly an instructor for the largest computer science course at UC Berkeley, where I taught for several years and won the Distinguished GSI (graduate student instructor) award. I am now a software engineer working on experimentation platforms at a large tech company. 4.45 / 5.00 average rating (943 reviews) at UC Berkeley. For more, see my Skillshare or Webs... Ver perfil completo

Habilidades relacionadas

Desarrollo Lenguajes de programación Java
Level: Intermediate

Valoración de la clase

¿Se cumplieron las expectativas?
    ¡Superadas!
  • 0%
  • 0%
  • Un poco
  • 0%
  • No realmente
  • 0%

¿Por qué unirse a Skillshare?

Mira las galardonadas Skillshare Originals

Cada clase tiene lecciones cortas y proyectos prácticos

Tu membresía apoya a los profesores de Skillshare

Aprende desde cualquier lugar

Ve clases sobre la marcha con la aplicación de Skillshare. Progresa en línea o descarga las clases para verlas en el avión, el metro o donde sea que aprendas mejor.

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.