Programación Orientada a Objetos Semana 1 Razón social 00.00.2015 Logro de la sesión Al finalizar la sesión, el estudiante elabora programas de software orientado a objetos, utilizando un lenguaje de programación . 2 Agenda • Una situación parecida a la vida real – Introducción a la POO • Tips para el diseño de clases • Construir y probar objetos • UML y Diagramas de clase • Herencia • Polimorfismo • Encapsulación • Ejercicios 3 Una situación parecida a la vida real – Introducción a la POO ¿Cómo los objetos pueden cambiar nuestras vidas? Érase una vez en un área de desarrollo de software, a dos programadores se les asignó una especificación y se les dijo que la "construyeran". El gerente de proyecto realmente molesto, obligó a dos programadores a competir prometiendo que quien lo entregue primero obtendrá un premio. La especificación Habrá formas en una GUI, un cuadrado, un círculo y un triángulo. Cuando el usuario hace clic en una forma, la forma girará 360 ° en sentido horario (es decir, completamente) y reproducirá un archivo de sonido AIF específico para esa forma en particular Los programadores eran Larry, especialista en programación estructurada y Brad el especialista en programación orientada a objetos, ambos al revisar las especificaciones sabían que esto era pan comido Programación estructurada • Larry pensó para sí mismo: “¿Cuáles son las cosas que tiene que hacer este programa? ¿Qué procedimientos necesitamos? ”. Y él se contestó a sí mismo: "gira y toca Sonido". Así que fue a construir los procedimientos. Después de todo, ¿qué es un programa sino un montón de procedimientos? Programación OO • Brad pensó para sí mismo: "¿Cuáles son las “cosas” en este programa ... quiénes son los jugadores clave?" Primero pensó en las formas. Por supuesto, había otros objetos en los que pensaba, como el Usuario, el Sonido y el evento Hacer clic. Pero él ya tenía una biblioteca de código para esas piezas, por lo que se centró en construir formas. 4 Una situación parecida a la vida real – Introducción a la POO Programación OO Programación estructurada Como había hecho miles de millones de veces antes, Larry comenzó a escribir sus Procedimientos importantes. Escribió rotar y reproducir sonido en muy poco tiempo. rotar(numForma){ //hacer rotar la forma 360° } reproducirSonido(numForma){ //usar numForma para encontrar //cual sonido AIF reproducir y //reproducirlo } “Larry” acabó primero y se sintió ganador del premio y se confirmaba su creencia que aunque la programación OO era linda, era lenta. No obstante el gerente de proyecto indicó que ha habido un cambio en las especificaciones y que aún no podía dar el premio y que este no sería problema para los programadores con ese nivel de experiencia. Se sabe en la vida real que un cambio de especificaciones sin problemas es una fantasía. Brad escribió una clase para cada una de las tres formas Cuadrado rotar(){ //código para rotar //un cuadrado } reproducirSonido(){ //código para tocar el //archivo AIF para el //cuadrado } Circulo Triangulo rotar(){ //código para rotar //un círculo } reproducirSonido(){ //código para tocar el //archivo AIF para el //círculo } rotar(){ //código para rotar //un triángulo } reproducirSonido(){ //código para tocar el //archivo AIF para el //triángulo } La nueva especificación Habrá una forma de ameba en la pantalla, con las demás formas. Cuando el usuario hace clic en la ameba, girará como los demás y reproducirá un archivo de sonido .aif. 5 Una situación parecida a la vida real – Introducción a la POO La nueva especificación Habrá una forma de ameba en la pantalla, con las demás formas. Cuando el usuario hace clic en la ameba, girará como los demás y reproducirá un archivo de sonido .aif. Programación Estructurada Programación OO En el programa de Larry, el procedimiento de rotación aún funcionaría; el código usaba una tabla de búsqueda para hacer coincidir un número de forma(numForma) con un gráfico de forma real. Pero reproducirSonido tendría que cambiar. Resultó no ser un gran problema, pero aún así le hizo sentir náuseas tocar el código probado previamente. Brad sonrió, sorbió su margarita y escribió una nueva clase. A veces, lo que más le gustaba de OO era que no tenía que tocar el código que ya había probado y entregado. "Flexibilidad, extensibilidad, ..." reflexionó, sobre los beneficios de OO. reproducirSonido(numForma){ //if la forma no es una ameba //usar numForma para encontrar //cual sonido AIF reproducir y //reproducirlo //else //reproducir el sonido .aif de //la ameba } Ameba rotar(){ //código para rotar //una ameba } reproducirSonido(){ //código para tocar el //archivo AIF para la //ameba } 6 Una situación parecida a la vida real – Introducción a la POO “Larry” acabó primero otra vez por muy poco. Pero la sonrisa en la cara de Larry se derritió cuando el gerente del proyecto dijo (con ese tono de decepción): "Oh, no, no es así como se supone que gira la ameba ..." Resulta que ambos programadores habían escrito su código de rotación así: Lo que la última especificación olvidó mencionar convenientemente la forma de la ameba debe girar alrededor de un punto en un extremo, como una manecilla de reloj 1) determina el rectángulo que rodea la forma 2) Calcule el centro de ese rectángulo y gire la forma alrededor de ese punto. Programación Estructurada "Estoy tostado", pensó Larry, "Aunque, hmmmm. simplemente podría agregar otro if/else al procedimiento de rotación, y luego simplemente elaborar el código del punto de rotación para la ameba. Eso probablemente no romperá nada". Finalmente pensó que era mejor agregar argumentos de punto de rotación al procedimiento de rotación. Mucho código fue afectado. Probó y volvió a compilar casi todo, y las cosas que solían funcionar, no funcionaban rotar(numForma,xPt,yPt){ //if la forma no es una ameba //calcular el punto //central //basado en un //rectángulo y luego //rotar //else //usar el xPt e yPt // como el punto de // referencia y // luego rotar } 7 Una situación parecida a la vida real – Introducción a la POO Lo que la última especificación olvidó mencionar convenientemente la forma de la ameba debe girar alrededor de un punto en un extremo, como una manecilla de reloj Programación OO Sin perder el ritmo, Brad modificó el método de rotación, pero solo en la clase Ameba. Nunca tocó el código compilado, probado y en funcionamiento para las otras partes del programa. Para darle a la ameba un punto de rotación, agregó un atributo que todas las amebas tendrían. Modificó, probó y entregó (de forma inalámbrica) el programa revisado en poco tiempo Ameba int xPunto Int yPunto rotar(){ //código para rotar //una ameba usando //los puntos x,y } reproducirSonido(){ //código para tocar el //archivo AIF para la //ameba } LARRY: ¡Tienes un código duplicado! El procedimiento de rotación está en las cuatro cosas de Forma. Entonces, Brad el especialista en programación OO consiguió el premio, ¿verdad? No tan rápido. Larry encontró una falla en el enfoque de Brad BRAD: es un método, no un procedimiento. Y son clases, no cosas. LARRY: Lo que sea. Es un diseño estúpido. Debe mantener cuatro "métodos" de rotación diferentes. ¿Cómo puede ser eso bueno? BRAD: Oh, supongo que no viste el diseño final. Déjame 8 mostrarte cómo funciona la herencia OO, Larry. Una situación parecida a la vida real – Introducción a la POO Cuadrado Circulo Triangulo Ameba rotar() reproducirSonido() rotar() reproducirSonido() rotar() reproducirSonido() rotar() reproducirSonido() 01 Miré lo que las tienen en común cuatro clases Forma 02 Son formas y todos giran y suenan. Así que abstraje las características comunes y las puse en una nueva clase llamada forma rotar() reproducirSonido() Forma rotar() reproducirSonido() 03 Luego vinculé las cuatro clases de formas con la nueva clase “Forma”, en una relación llamada herencia La Cuadrado Circulo Triangulo Ameba Puede leer esto como "El cuadrado hereda de forma", "El círculo hereda de forma", etc. Eliminé rotar() y reproducirSonido() de las otras formas, así que ahora solo hay una copia para mantener. clase Forma se llama la superclase de las otras cuatro clases. Las otras cuatro son las subclases de Forma. Las subclases heredan los métodos de la superclase. En otras palabras, si la clase Forma tiene la funcionalidad, entonces las subclases obtienen automáticamente esa misma funcionalidad. 9 Una situación parecida a la vida real – Introducción a la POO Superclase (más abstracta) ¿Qué pasa con la rotación de la Ameba [rotar()]? Forma rotar() reproducirSonido() Subclases (más específico) Cuadrado Circulo 04 Triangulo LARRY: ¿No era ese el problema? ¿que la ameba tenía un procedimiento de rotación y reproducción completamente diferente? BRAD: Método. LARRY: Lo que sea. ¿Cómo puede la ameba hacer algo diferente si "hereda" su funcionalidad de la clase Forma? BRAD: Ese es el último paso. La clase Ameba sobreescribe los métodos de la clase Forma. Luego, en tiempo de ejecución, la JVM sabe exactamente cuál método rotar() ejecutar, cuando alguien le dice a la Ameba que gire. LARRY: ¿Cómo “le dices” a una ameba que haga algo? ¿No tiene que llamar al procedimiento, lo siento, método, y luego decirle qué cosa rotar? BRAD: Eso es lo realmente genial de OO. Cuando es hora de, por ejemplo, que el triángulo gire, el código del programa invoca (llama) al método rotar() en el objeto triangulo. El resto del programa realmente no sabe ni le importa cómo lo hace el triángulo. Y cuando necesite agregar algo nuevo al programa, simplemente escriba una nueva clase para el nuevo tipo de objeto, para que los nuevos objetos tengan su propio comportamiento. Hice que la clase Ameba sobreescribiera los métodos rotar() y reproducirSonido() de la superclase Forma. Sobreescribir sólo significa que una subclase redefine uno de sus métodos heredados cuando necesita cambiar o extender el comportamiento de ese método Ameba rotar(){ //código específico // para rotar una //ameba} Métodos sobreescritos reproducirSonido(){ //código específico //para reproducir //el sonido} El suspenso me está matando. ¿Quién se llevó el premio? 10 Tips para diseño de clases Cuando diseñe una clase, piense en los objetos que se crearán a partir de ese tipo de clase. Pensar acerca de • Cosas que el objeto conoce acerca de sí mismo o se conoce del objeto (características sustantivo) • Cosas que hace/se hace con el objeto (comportamientos - verbo) contenidoCarrito adicionarACarrito() removerDeCarrito() girar() pagar() Alarma Boton CarritoCompras conoce hace etiqueta color establecerColor() establecerEtiqueta() presionarBoton() liberarBoton() conoce hace tiempoAlarma modoAlarma conoce establecerTiempoAlarma() obtenerTiempoAlarma() silenciarAlarma() estaAlarmaconfigurada() hace Las cosas que un objeto conoce sobre si mismo o se conoce sobre el objeto se llaman variables de instancia, Representan el estado de un objeto (los datos) y pueden tener valores únicos para cada objeto de ese tipo. Las cosas que un objeto puede hacer son llamadas métodos, representan los comportamientos Cuando diseña una clase, piensa en los datos que un objeto necesitará conocer sobre sí mismo, y también 11 diseñe los métodos que operan sobre esos datos. Tips para diseño de clases - Ejercicio Complete lo que un objeto de televisión podría necesitar conocer acerca de si mismo y lo que hace - se hace con el objeto. Television Variables de instancia métodos 12 ¿Cuál es la diferencia entre una clase y un objeto? Una clase no es un objeto. (pero se usa para construirlos) Perro Una clase raza tamaño nombre ladrar() Varios objetos • Una clase es un plano para un objeto. Le dice a la máquina virtual cómo hacer un objeto de ese tipo en particular. Cada objeto hecho de esa clase puede tener sus propios valores para las variables de instancia de esa clase. Por ejemplo, puede usar la clase Botón para hacer docenas de botones diferentes, y cada botón puede tener su propio color, tamaño, forma, etiqueta, etc. Clase Míralo de esta manera Un objeto es como una entrada en su libreta de direcciones. Una analogía para los objetos es un paquete de tarjetas como se muestra en la figura (clase Agenda). Cada tarjeta tiene los mismos campos en blanco (las variables de instancia). Cuando completa una tarjeta, está creando una instancia (objeto), y las entradas que llena en esa tarjeta representan su estado. Los métodos de la clase son las cosas que le haces a una tarjeta en particular; getName (), changeName (), setName () podrían ser métodos para la clase Agenda. Por lo tanto, cada tarjeta puede hacer lo mismo (getName (), changeName (), etc.), pero cada tarjeta conoce cosas únicas de esa tarjeta en particular. 13 Construyendo nuestro primero objeto 01 ¿Qué se necesita para crear y usar un objeto? Escribe tu clase Class Perro{ int tamaño; String raza; String nombre; variables instancia de Perro Un método void ladrar(){ System.out.println(“gua gua”); } raza tamaño nombre ladrar() } 02 Sólo un método main Escribe una clase de prueba 03 Class PruebaPerro{ public static void main(String[] args){ //El código de prueba de la clase // perro // se escribe aquí } } • Necesitas dos clases. Una clase para el tipo de objeto que desea usar (Perro, Despertador, Televisión, etc.) y otra clase para probar la nueva clase. La clase de prueba es donde se pone el método “main”, y en ese método main () creas y accedes a objetos de tu nuevo tipo de clase. La clase de prueba tiene un solo trabajo: probar los métodos y las variables del objeto de su nuevo tipo de clase. En la clase de prueba, construye un objeto y accede a las variables y métodos del objeto Class PruebaPerro{ public static void main(String[] args){ Perro d = new Perro(); Construir un objeto Perro d.tamaño=40; Usar el operador punto (.) para d.ladrar(); Operador establecer el tamaño del perro punto } } Y para llamar al método ladrar() 14 Construir y probar objetos tipo Cine - Ejercicio Cine titulo genero rating playIt() La clase PruebaCine crea objetos (instancias) de la clase Cine y utiliza el operador de punto para establecer las variables de instancia en un valor específico. La clase PruebaCine también invoca (llama) un método en uno de los objetos. Complete los siguientes cuadros con los valores que tienen los tres objetos luego de ejecutar el método main() titulo Objeto uno genero rating titulo Objeto dos genero rating titulo genero Objeto tres rating 15 UML y diagramas de clase Vamos a hablar mucho sobre clases y objetos, pero es bastante difícil mirar 200 líneas de código y enfocarnos en el panorama general. Por lo tanto, utilizaremos UML, el lenguaje de modelado unificado, que es un lenguaje utilizado para comunicar la estructura de la aplicación que necesitan otros desarrolladores y clientes, sin obtener detalles que no son necesarios Este es el nombre de la clase. Siempre está Así es como se muestra una clase en un diagrama de clase. Esa es la forma en que UML le permite representar detalles sobre las clases en su aplicación. Estas son las variables de instancia de la clase. Cada uno tiene un nombre y luego un tipo después de los dos puntos. Estos son los métodos de la clase. Cada uno tiene un nombre, y luego cualquier parámetro que tome el método, y luego un tipo de retorno después de los dos puntos. en negrita, en la diagrama de clase. Aeroplano velocidad: int parte superior del Esta línea separa las variables instancia de los métodos de la clase. getVelocidad():int setVelocidad(int) Un diagrama de clase hace que sea realmente fácil ver el panorama general: puede ver fácilmente lo que hace una clase de un vistazo. Incluso puede omitir las variables y/o métodos si le ayuda a comunicarse mejor. Ejercicio Escribe el esqueleto para la clase Aeroplano. Usando el diagrama de clase visto, escriba el esqueleto básico para la clase Aeroplano. ¿Encontraste algo que el diagrama de la clase deja de lado? Escriba esas cosas: 16 Solución - Ejercicio El diagrama de clase no nos decía si la velocidad debería ser públic, private o protected No había nada sobre un constructor en el diagrama de clases. Podría haber escrito un constructor que tomara un valor de velocidad inicial, y eso también estaría bien En realidad, los diagramas de clase pueden proporcionar esta información, pero en la mayoría de los casos, no es necesaria para una comunicación clara. El diagrama de clase no nos dijo qué hizo este método ... hicimos algunas suposiciones, pero no podemos estar seguros de si este código es realmente lo que se pretendía Aeroplano -velocidad: int +Aeroplano() +getVelocidad():int +setVelocidad(int) 17 Preguntas y respuestas Entonces, el diagrama de clase UML no es una representación muy completa de una clase, ¿verdad? Tengo mi propia forma de dibujar clases; ¿qué está mal con eso? ¿A quién se le ocurrió este acuerdo con UML? Si, pero debe ser así. Los diagramas de clase son solo una forma de comunicar los detalles básicos de las variables y métodos de una clase. También facilita hablar sobre el código sin obligarlo a navegar por cientos de líneas de Java No hay nada de malo en su propia notación, pero puede dificultar la comprensión de otras personas. Al usar un estándar como UML, todos podemos hablar el mismo idioma y estar seguros de que estamos hablando de lo mismo en nuestros diagramas. La especificación UML fue desarrollada por Rational Software, bajo el liderazgo de Grady Booch, Ivar Jacobson y Jim Rumbaugh (tres tipos realmente inteligentes). En la actualidad, está administrado por OMG Suena como un gran alboroto por ese simple diagrama de clase UML es en realidad mucho más que ese diagrama de clase. UML tiene diagramas para el estado de sus objetos, la secuencia de eventos en su aplicación, e incluso tiene una forma de representar los requisitos del cliente y las interacciones con su sistema 18 Representación completa de una clase en UML NombreClase +nombreAtributo1:tipoAtributo1[extremoInf…extremoSup] = valorDefecto{propiedades} #nombreAtributo2:tipoAtributo2[extremoInf…extremoSup] = valorDefecto{propiedades} -nombreAtributo3:tipoAtributo3[extremoInf…extremoSup] = valorDefecto{propiedades} +nombreMetodo1(param1:tipoParam1[extremoInf…extremoSup]=valorDefecto{propiedades},inout param2:tipoParam2):tipoRetorno +nombreMetodo2(out param:tipoParam[extremoInf…extremoSup]=valorDefecto{propiedades}):tipoRetorno[extremoInf..extremoSup]{propiedades} 19 Herencia Una clase hereda el comportamiento de otra clase, y luego puede cambiar ese Jet se extiende desde la clase comportamiento si es necesario Eso significa que hereda Jet es llamado una subclase de avión. Aeroplano es la superclase de Jet. comportamiento para sí mismo. de Aeeroplano Aeroplano. todo el para usarlo La subclase puede agregar sus propias variables a las que hereda de Aeroplano super es una palabra clave especial. Se refiere a la clase de la que esta clase ha heredado el comportamiento. Entonces aquí, esto llama al constructor de Aeroplano, la superclase de Jet. La subclase puede cambiar el comportamiento de su superclase, así como llamar a los métodos de la superclase. Esto se llama sobre escribir el comportamiento de la superclase. Una subclase puede agregar sus propios métodos a los métodos que hereda de su superclase Jet también hereda el método getVelocidad() de Aeroplano. Pero dado que Jet usa la misma versión de ese método, no necesitamos escribir ningún código para cambiarlo. Aunque no puede verlo en Jet, está perfectamente bien llamar a getVelocidad() en Jet. Puede llamar a super.getVelocidad(), pero también puede llamar a getVelocidad(), como si getVelocidad() fuera un método normal definido en Jet. La herencia le permite crear clases basadas en otras clases y evitar duplicar y repetir código. 20 Ejercicio - Rompecabeza Su trabajo es tomar fragmentos de código del grupo de abajo y colocarlos en las líneas en blanco en el código. Puede usar el mismo fragmento de código más de una vez, y no necesitará usar todos los fragmentos. Su objetivo es crear una clase que compile, ejecute y produzca el siguiente resultado Se tienen las siguientes clases: 21 Polimorfismo El polimorfismo está estrechamente relacionado con la herencia. Cuando una clase hereda de otra, el polimorfismo permite que una subclase sustituya a la superclase. Aquí hay otro diagrama de clase, esta vez con dos clases. Aeroplano velocidad: int getVelocidad():int setVelocidad(int) Jet es una subclase de aeroplano. Eso significa que en cualquier lugar donde pueda usar un avión Entonces, en el lado izquierdo, tienes la superclase.. Esta pequeña flecha significa que Jet hereda de Airplane. Jet MULTIPLICADOR: int acelerar() ... también podrías usar un Jet ... y a la derecha, puedes tener la superclase o cualquiera de sus subclases. 22 Preguntas y respuestas ¿Qué es tan útil sobre el polimorfismo? Puede escribir código que funcione en la superclase, como Aeroplano, y funcionará con cualquier tipo de subclase, como Jet o Cohete. Entonces su código es más flexible Todavía no entiendo cómo el polimorfismo hace que mi código sea flexible Bueno, si necesita una nueva funcionalidad, podría escribir una nueva subclase de Avión. Pero como su código usa la superclase, su nueva subclase funcionará sin ningún cambio en el resto de nuestro código. Eso significa que su código es flexible y puede cambiar fácilmente 23 Encapsulación La encapsulación hace que la clase actúe como una caja negra que proporciona un servicio a sus usuarios, pero no abre el código para que alguien pueda cambiarlo o usarlo de manera incorrecta. Ahora cualquiera puede configurar la velocidad directamente Hicimos que la variable velocidad fuera pública, en lugar de privada, y ahora todas las partes de su aplicación pueden acceder a la velocidad directamente. Este cambio significa que el resto de su aplicación ya no tiene que llamar a setVelocidad() para establecer la velocidad de un avión; La variable de velocidad se puede configurar directamente. Entonces el sgte. código se compilaría bien: Ya no tenemos que usar setVelocidad() y getVelocidad() ...podemos acceder a la velocidad directamente. La encapsulación es cuando protege la información en su código para que no se use incorrectamente Pruebe este código ... ¿hay algo sorprendente en los resultados que obtiene? 24 ¿Así que, cuál es el problema? No parece ser un gran problema, ¿verdad? Pero qué sucede si crea un Jet y establece su velocidad de esta manera: Usando Jet sin encapsulación Usando Jet encapsulación con Dado que Jet hereda de Aeroplano, puede usar la variable velocidad de su superclase como si fuera parte de Jet. Así es como configuramos y accedemos a la variable de velocidad cuando ocultamos que la velocidad no sea accedida directamente Aquí está la definición oficial de encapsulación ... El proceso de encerrar elementos de programación dentro de entidades más grandes y más abstractas. También conocido como ocultamiento de información o separación de preocupaciones. 25 ¿Cuál es el valor de encapsular sus datos? Escriba, compile y ejecute el código de la diapositiva anterior. ¿Cómo se verá la salida? Escriba las dos líneas de salida en los espacios en blanco a continuación: Velocidad del jet1: ________________ Velocidad del jet2: ________________ ¿Qué crees que pasó aquí? Escriba por qué cree que obtuvo las velocidades que obtuvo para cada instancia de Jet: En la clase Jet, setVelocidad () toma el valor suministrado y lo multiplica por dos antes de configurar la velocidad del jet. Cuando configuramos la variable de velocidad manualmente, no se multiplicó por dos. Finalmente, resuma cuál cree que es el valor de la encapsulación: La encapsulación protege los datos para que no se configuren de manera incorrecta. Con los datos encapsulados, se conservan todos los cálculos o comprobaciones que la clase realiza sobre los datos, ya que no se puede acceder a los datos directamente. Entonces, la encapsulación hace más que solo ocultar información; ¡se asegura de que los métodos que escribe para trabajar con sus datos se usen realmente! 26 Preguntas y respuestas ¿Entonces la encapsulación se trata de hacer privadas todas sus variables? Entonces, ¿hay otras formas de usar la encapsulación además de las variables? Entonces, la encapsulación se trata realmente de proteger sus datos, ¿verdad? No, la encapsulación se trata de separar la información de otras partes de su aplicación que no deberían interferir con esa información. Con las variables de instancia, no desea que el resto de su aplicación se meta directamente con sus datos, por lo que separa esos datos haciéndolos privados. Si los datos necesitan actualizarse, puede proporcionar métodos que funcionen de manera responsable, como se hizo con la clase Aeroplano, utilizando getVelocidad() y setVelocidad(). Por supuesto, se puede encapsular un grupo de propiedades lejos de un objeto y asegurarnos de que el objeto no use esas propiedades incorrectamente. A pesar de que trataremos con un conjunto completo de propiedades, todavía se trata de separar un conjunto de información del resto de su aplicación. En realidad, ¡es incluso más que eso! La encapsulación también puede ayudarlo a separar el comportamiento de otras partes de su aplicación. Por lo tanto, puede poner mucho código en un método y poner ese método en una clase; ha separado ese comportamiento del resto de su aplicación, y la aplicación tiene que usar su nueva clase y método para acceder a ese comportamiento. Sin embargo, son los mismos principios que con los datos: está separando partes de su aplicación para protegerlas de un uso inadecuado. La encapsulación separa sus datos del comportamiento de su aplicación. Luego puede controlar cómo cada parte es utilizada por el resto de su aplicación. 27 Como resolver un problema con POO Diseño de programas en la POO POO divide los problemas en función de los tipos de datos 01 encontrados en el problema, en lugar de dividir el problema basado en los algoritmos involucrados 02 Dada una declaración del problema, ¿qué cosas aparecen en el problema? 03 Los sustantivos del problema son candidatos a clases. Las acciones y los verbos de los problemas son candidatos a métodos de las clases. https://www.youtube.com/watch?v=tTPeP5dVuA4 28 Como resolver un problema con POO Diseño de clases 04 Las clases deben ser cohesivas: • Deben estar diseñados para hacer una cosa bien 05 Las clases deben estar débilmente acopladas. • Cambiar los detalles de implementación internos de una clase no debería afectar a otras clases. • Este débil acoplamiento también se puede lograr dentro de una https://www.youtube.com/watch?v=2X50sKeBAcQ clase 29 Rápido! Sal del método main() Está bien que un programa de prueba se ejecute dentro del método principal, pero en una verdadera aplicación OO, necesita objetos que se comuniquen con otros objetos Los dos usos de main: • Para probar tu clase • Para lanzar/iniciar su aplicación en Java Una aplicación real de Java no es más que objetos que hablan con otros objetos. En este caso, hablar significa objetos que invocan métodos entre sí. A continuación un ejemplo de cómo podría comportarse una aplicación real en Java El juego de adivinanzas Implementar un programa Orientado a Objetos, que simule un juego de adivinanza, donde tres jugadores deben adivinar un número aleatorio entre 0 y 9 generado por el programa. Los tres jugadores también deben adivinar de forma aleatoria (no se debe ingresar por teclado). 30 El juego de adivinanzas La lógica: 1) La clase GameLauncher es donde comienza la aplicación; tiene el método main(). 2) En el método main(), se crea un objeto GuessGame y se llama a su método startGame(). 3) El método startGame() del objeto GuessGame es donde se desarrolla todo el juego. Crea tres jugadores, luego "piensa" en un número aleatorio (el objetivo para que los jugadores adivinen). Luego le pide a cada jugador que adivine, verifica el resultado e imprime información sobre los jugadores ganadores o les pide que adivinen nuevamente. El juego de adivinanzas GameLauncher Main(String[] args) Involucra un objeto "juego" y tres objetos jugador". El juego genera un número aleatorio entre 0 y 9, y los 3 objetos GuessGame Variables de jugador intentan adivinarlo. p1 instancia para los 3 jugadores p2 el número que Player el jugador p3 adivinó number startGame() crea un GuessGame dice que el juego objeto y le inicie método para adivinar guess() 31 El juego de adivinanzas - Solución La clase GuessGame: GuessGame tiene tres variables de instancia para los tres objetos Player crear tres objetos Player y los asigna a sus tres variables de instancia declarar tres variables para mantener las respuestas de los jugadores a la adivinanza declarar tres variables para mantener un verdadero o falso basado en la respuesta del jugador Generar el número aleatorio (objetivo) que los jugadores tienen que adivinar llama al método guess () de cada objeto Player (jugador) 32 El juego de adivinanzas - Solución La clase GuessGame: obtenga la respuesta de cada jugador (el resultado de la ejecución de su método guess()) accediendo al valor del atributo o variable de instancia “number” de cada objeto Comprueba las respuestas de cada jugador para ver si coincide con el número objetivo. Si un jugador tiene razón, se configura la variable de ese jugador como verdadera (recuerde que se configuró como falsa por defecto) Si el jugador uno O el jugador dos O el jugador tres tiene razón De lo contrario, se sigue en el bucle intentado con la adivinanza 33 El juego de adivinanzas - Solución Salida: La clase GameLauncher: La clase Player: 34 Ejercicio – ¿Quién soy? Complete los espacios en blanco al lado de la oración con los nombres de uno o más de las opciones disponibles. Clase Método Frase Variable de instancia Objeto Opciones Me comporto como una plantilla Me gusta hacer cosas Puedo tener muchos métodos. Yo represento el "estado" Tengo comportamientos Estoy ubicado en objetos Vivo en el montón (heap) Estoy acostumbrado a crear instancias de objetos Mi estado puede cambiar Declaro métodos. Puedo cambiar en tiempo de ejecución 35 Ejercicio – Crucigrama Tómese un momento para revisar los conceptos revisados en esta presentación y luego estará listo para resolver este crucigrama Horizontal: 3. Cuando una subclase puede sustituir a su superclase utilizamos el .... 2. Los diagramas de clase no muestran detalles sobre esta parte de nuestra clase. 5. Una clase que hereda de otra clase es.. 6. Una clase de la que se hereda se llama ... 1 3 4 2 Vertical: 1. El polimorfismo ayuda a que tu código sea... 2. Use este tipo de diagrama UML para evitar navegar sobre mucho código. 4. La encapsulación le permite hacer esto con información. 5 6 36 Ejercicio – Ser el compilador Cada uno de los archivos Java en esta diapositiva representa un archivo fuente completo. Su trabajo es jugar al compilador y determinar si cada uno de estos archivos se compilará. Si no compilan, ¿cómo los arreglarías?. A B 37 Ejercicio - Rompecabeza Su trabajo es tomar fragmentos de código de la piscina y colocarlos en las líneas en blanco del código. Puedes usar el mismo fragmento de código más de una vez, y no necesitará usar todos los fragmentos. Su objetivo es crear una clase que compile, ejecute y produzca el siguiente resultado Pregunta extra Si la última línea de salida fuera 24 en lugar de 10, ¿cómo completarías el rompecabezas? Nota: ¡Cada fragmento del grupo se puede usar más de una vez! 38 ¿Preguntas? 39 Resumen • La programación orientada a objetos nos permite extender un programa sin tener que tocar el código previamente trabajado y probado. (Herencia) • Todo el código java es definido en una clase (Jerarquía) • Una clase describe como construir un objeto de esa clase. Una clase es como un plano. • Un objeto puede cuidarse solo; no tiene que saber o importarle cómo el objeto lo hace. (encapsulación) • Un objeto sabe y hace cosas. Las cosas que un objeto sabe sobre si mismo se llaman variables de instancia. Representan el estado de un objeto. • Las cosas que hace un objeto se llaman métodos. Representan el comportamiento de un objeto. 40 Resumen • UML significa el lenguaje de modelado unificado. UML lo ayuda a comunicar la estructura de su aplicación a otros desarrolladores, clientes y gerentes. • Un diagrama de clase le ofrece una visión general de su clase, incluidos sus métodos y variables. • La herencia es cuando una clase extiende a otra clase para reutilizar o construir sobre el comportamiento de la clase heredada. • En herencia, la clase de la que se hereda se llama superclase; La clase que está haciendo la herencia se llama subclase. • Una subclase obtiene todo el comportamiento de su superclase automáticamente. • Una subclase puede anular el comportamiento de su superclase para cambiar el funcionamiento de un método. 41 Resumen • El polimorfismo es cuando una subclase "sustituye" a su superclase. • El polimorfismo permite que sus aplicaciones sean más flexibles y menos resistentes al cambio. • La encapsulación es cuando separas u ocultas una parte de tu código del resto de tu código. • La forma más simple de encapsulación es cuando hace que las variables de sus clases sean privadas, y solo expone esos datos a través de métodos en la clase. • Una subclase obtiene todo el comportamiento de su superclase automáticamente. • También puede encapsular grupos de datos, o incluso comportamientos, para controlar cómo se accede a ellos. 42 FIN 43