Download Programación orientada a objetos - ISTR
Document related concepts
no text concepts found
Transcript
G80 - Advanced Computing Object oriented programming with Java Julio Medina José M. Drake LA CRISIS DEL SOFTWARE. El proceso de diseño en cascada que se había utilizado en ingeniería no es apropiado para el desarrollo de software: =>Proceso en espiral La modularización estructurada hace que el software sea fácil de diseñar pero inflexible y costoso de mantener: => Programación OO=> Programación basada en componentes => MDE La programación secuencial derivada del diseño de los procesadores con arquitectura Von Newmann conduce al alejamiento entre la solución software y el problema que se resuelve: => Programación concurrente La estrategia constructiva esencial para el desarrollo del software es la ingeniería. 2 Complejidad de los problemas Las aplicaciones software pueden ser extremadamente complejas: Puede estar constituidas por miles, millones de elementos diferentes. Los elementos corresponder a miles de tipos diferentes de elementos. Tiene una estructuras discretas de estados, por lo que un error en un elemento conduce a un sistema con un comportamiento radicalmente diferente. El desarrollo de las aplicaciones software requieren hacer uso de todos los recursos de gestión de la complejidad que ha desarrollado el ser humano: Modularización: Capacidad para descomponer los componentes complejos en otros mas simples. Abstracción: Capacidad de reducir la información de un componente a la necesaria para manejarlo en un nivel de desarrollo. Herencia: Capacidad de jerarquizar los componentes del dominio de acuerdo con las características comunes que presentan. 3 Complejidad del proceso Hay que satisfacer y dar coherencia a miles de requisitos. La especificación del problema la realiza el usuario y suele ser informal. A lo largo de la vida del producto puede ser revisada muchas veces. Hay que satisfacer requisitos funcionales y no funcionales: Fiabilidad, robustez, facilidad de uso, comportamiento temporal, tiempo de vida útil, seguridad, … Un proyecto software complejo debe ser desarrollado por un equipo, o un grupo de equipos, por los que requiere estrategias de ingeniería avanzadas. Y entornos de desarrollo automatizados. Un programa debe ser verificado para que se satisfaga todos los requisitos de su especificación. Dado que en un sistema complejo, es imposible asegurar la ausencia absoluta de errores, hay que delimitar su efecto. 4 La abstracción matemática no es una buena solución Dominio del problema Problema del Solución en el mundo real mundo real Representación abstracta del problema Formulación matemática Resultados del problema Interpretación de los datos salida Solución en el computador Datos de salida Dominio matemático 5 El efecto de la abstracción matemática Las aplicaciones son fáciles de diseñar pero muy difíciles de mantener Pruebas de integración 7º Pruebas de módulos 8% Codificación 7% Diseño 5% Especificación 3º Análisis 3º Mantenimiento 67% Costo de las fases del desarrollo de una aplicación 6 Paradigma de programación orientada a objetos Las bases del paradigma de desarrollo del software denominado orientación a objetos son: Se utiliza como criterio de modularización la identificación de los objetos del dominio del problema. Cada módulo de la aplicación software corresponde a un objeto existente en el dominio del problema y en él se incluyen todos los aspectos (funcionalidad, estados, datos, etc.) que son propios del objeto. Cuando se aborda una aplicación utilizando el paradigma orientado a objetos la pregunta clave es: ¿Qué objetos constituyen el sistema? Y no lo que era propio de la programación estructurada, que es: ¿Qué hace la aplicación? 7 Modularización basada en el dominio del problema Dominio del problema Problema del mundo real Solución en el mundo real Representación abstracta del problema Formulación matemática Resultados del problema Interpretación de los datos salida Solución en el computador Datos de salida Dominio matemático 8 Ejemplo de aplicación del paradigma OO. Diseño de la aplicación de control de la puerta de un garaje: La puerta se abre cuando desde un coche se pulsa un mando. El motor mueve la puerta para abrirla o cerrarla. Cuando a transcurrido 10 segundos sin eventos la puerta se cierra. Si mientras que se está cerrando ocurre un evento de mando u obstáculo se vuelve a abrir El sistema se apaga coherentemente con un interruptor. 9 Ejemplo Garaje:Diseño OO 10 Claves de las metodología orientadas a objetos. Abstracción: Busca una definición conceptual común a muchos objetos, tratando de identificar sus características esenciales y agrupándolos por clases. Encapsulación: define de forma independiente la abstracción o interfaz del módulo y su implementación y estructura interna. Modularidad: Describe el sistema como conjunto de módulos(objetos) descentralizados y débilmente acoplados. Herencia: Jerarquiza las clases de acuerdo con afinidades de sus abstracciones. Tipado: Clasifica los objetos de forma estricta, restringiendo las interacciones a solo aquellas que son coherentes. Concurrencia: Enfatiza la naturaleza independiente de cada objeto, adjudicándole si procede líneas de control de flujo independientes. Persistencia: Enfatiza la naturaleza independiente de los objetos, adjudicándole una existencia que sobrepasa a quien lo creó. 11 Beneficios de la programación orientada a objetos Descomponibilidad : Se consigue de forma natural al problema. Componibilidad y Reusabilidad: Los objetos son reales y se comparten con cualquier otra aplicación del mismo dominio. Comprensibilidad y consistencia con el dominio del problema: La función y abstracción de un objeto es obvia ya que coincide con la del objeto del dominio real que representa. Continuidad y estabilidad frente a cambios: La evolución de una aplicación es consecuencia de cambios en los objetos que la componen, y solo afecta a un módulo. Robustez y protección frente a fallos: Cada objeto se implementa como un ente independiente y los estados de excepción que se puedan generar, pueden ser tratados dentro del propio objeto. Soporte inherente de la concurrencia: La concurrencia propia de los dominios reales se transfiere de forma natural a la aplicación. Escalabilidad: La complejidad de la aplicación crece linealmente con la complejidad del problema que se aborda. 12 Ambitos de aplicación de la orientación a objetos. Los métodos orientados a objetos son aplicables a todas las fases de desarrollo de una aplicación software. (OOA) Análisis orientado a objetos: Es un método de análisis que examina los requerimientos desde el punto de vista de las clases y objetos encontrados en el vocabulario del dominio (problema). (OOD) Diseño orientado a objetos: Es un método de diseñar un programa basado en identificar los módulos de que se compone, mediante componentes que representan conjuntamente los datos y las operaciones de una abstracción. (OOP) Programación orientada a objetos: Es una forma de expresar un programa basada en construcciones léxicas que se denominan clases y que describen los datos y el comportamiento común de conjuntos de objetos, que cada uno de ellos representa una instancia independiente de la clase. 13 Clases y objetos Las clases son los módulos de diseño que describen el estado y el comportamiento de algún tipo de elemento que constituyen la aplicación (y en OO también algún elemento del problema). Una clase contiene; Los atributos que describen la información relativa al objeto que describe la clase. Los métodos u operaciones que describen el comportamiento de los objetos que describe la clase. Los objetos o instancias son los módulos de ejecución que constituyen un escenario de análisis o el programa de la aplicación que se ejecuta en un computador. Los objetos se instancian (construyen) a partir de una clase: La clase constituyen la plantilla que describe los tipos de datos y la funcionalidad (comportamiento)de los objetos que son instancias suyas. Los objetos definen los valores concretos de la propiedades definidas en las clases que se asignan a un elemento específico del problema o aplicación. 14 Ejemplo de clases y objetos Objetos Clases 15 Atributos de una clase Son las variables que define la clase para contener la información que requiere cada objetos descritos por ella para describir: El estado en que se encuentran como consecuencia de su evolución. Las propiedades de configuración cuando se crean. Cada atributo tienen definido el tipo de dato, esto es la información que se le puede asignar. Los tipos pueden ser un tipo primitivo (Integer, Float, Boolean, etc.) o la referencia a una clase. Se puede cualificar la visibilidad (quien puede leer o modificar el valor asignado) de los atributos como públicos o privados: El valor de un atributos privado sólo puede ser accedido por los métodos del propio objeto. El valor de los atributos públicos pueden ser también leídos por los métodos de cualquier objetos que tenga la referencia al objeto. Un buen criterio es declarar los atributos de las clases como privados y definir funciones de acceso si deben ser accedidos externamente. Cuando la clase es sólo un tipo complejo de dato, suelen ser públicos. 16 Atributos estáticos Son variable que contienen información relativa a la clase, o a alguna propiedad relativa al conjunto de las instancias de la clase. Para acceder a los atributos estáticos, hay que hacer referencia a la clase o a cualquier instancia de la misma. En la representación UML, los atributos estáticos se representan subrayados, los públicos con un prefijo + y los privados con un prefijo -. 17 Métodos (1) Son funciones y operaciones definidas con referencia a los objetos de una clase. Los métodos definidos en una clase definen su comportamiento: Proporcionan información deducible del estado de la instancia a la que se aplica. Produce cambios del estado de las instancia. Define operaciones básica, que sirven para construir otras mas complejas. Crear y construir nuevas instancias. Cuando se invoca un método puede retornar o no, un valor. Los valores retornados tienen un tipo definido: Si el tipo retornado es un tipo primitivo, retorna un valor. Si el tipo retornado es una clase, retorna una referencia a un objeto de la clase. Los métodos pueden definir parámetros con tipo, a los que se asignan valores cuando se invocan. Los valores de los parámetros son visibles en la implementación del método. Si el tipo del parámetro es primitivo el valor se pasa por valor. Si el tipo de parámetro es una clase el valor se pasa por referencia. Los métodos pueden definirse con visibilidad privada o pública. Los métodos privados sólo pueden ser invocados por métodos del mismo objeto. 18 Métodos (2) El conjunto de métodos públicos ofertados por una clase constituyen la interfaz pública de los objetos de las clases y definen su comportamiento como caja negra. Los cambios internos de una clase no afecta a las aplicaciones que las usan, siempre que mantenga su interfaz pública. 19 Métodos estáticos Son métodos que tienen acceso sólo a la información estática de la clase y/o a la que recibe a través de los parámetros de invocación, y no al estado propio de cualquier instancia de la clase. Pueden utilizarse para construir librerías de funciones que procesan la información de los parámetros sin referencia a ningún objeto. En UML se representan subrayadas. 20 Herencia La herencia es el mecanismo por el que se especializan o extienden la funcionalidad de una clase, diseñando a partir de ella nuevas clases. La clase A es una extensión de la clase B si es cierto que A es-un B, Cuando una clase extiende a otra, significa que hereda todo lo definido en ella (atributos y métodos). La clase que resulta de la extensión puede añadir nuevos elementos (atributos y métodos) a los heredados (Extensión), o modificar su comportamiento (Refinamiento). Principales usos de la herencia: Herencia de implementación: La herencia como reutilización de código. Una clase derivada puede heredar comportamiento de una clase base, por tanto, el código no necesita volver a ser escrito para la derivada. Herencia de interfaz: La herencia como reutilización de conceptos: Esto ocurre cuando una clase derivada sobrescribe el comportamiento definido por la clase base. Aunque no se comparte ese código entre ambas clases, ambas comparten el prototipo del método (comparten el concepto). La herencia puede ser Simple o Múltiple. 21 Ejemplo de herencia 22 Clase abstracta e interface Una clase abstracta es la que representa la parte común de la clases que se derivan de ellas, pero que no representan ningún objeto existente. Una clase abstracta puede utilizarse como base de herencia, pero no para instanciar objetos. Una interfaz definen una interfaz pública (conjunto de métodos) sin especificar su implementación. Cuando una clase implementa una interfaz tiene que incluir en su interfaz pública la declaración de todos los métodos definidos en ella. 23 Organización del diseño El diseño de una aplicación puede requerir la definición de muchas clases. Estas clases se organizan en contenedores que se denominan paquetes. Algunos paquetes son desarrollados como parte del diseño, pero la mayoría de los paquetes y de las clases son legados (previamente diseñados) e importados en el proyecto de la aplicación. 24 Aplicación orientada a objetos Una aplicación orientada a objetos se ejecuta invocando desde el entorno un método estático <<main>> de una clase definida en el proyecto. Normalmente, se reciben como parámetros del método los datos de configuración En la ejecución del método <<main>>, y organizada en base al thread que lo invoca: Se crean recursivamente los objetos que participan en la aplicación haciendo uso de los datos de configuración. Se invocan los métodos públicos de los objetos creados, de acuerdo con la lógica del problema La aplicación termina cuando finaliza la ejecución del método<<main>> ya sea por el fin de su lógica, o por alcanzar una situación de excepción no atendida. 25 Lenguaje Java El lenguaje de programación Java fue originalmente desarrollado por James Gosling de Sun Microsystems(actualmente adquirida por la compañía Oracle) y publicado en el 1995. Las aplicaciones de Java son normalmente compiladas a bytecode que puede ejecutarse en cualquier máquina virtual Java (JVM) sin importar la arquitectura de la computadora subyacente. Su objetivo era independizar los desarrolladores de aplicaciones del la plataforma en la que se ejecuta ("write once, run anywhere"). Es un lenguaje muy sencillo pero muy moderno, que además de ser OO de propósito general es concurrente, está pensado para programar en base a patrones de diseño y tiene extensiones para sistemas basados en componente (EJB), sistemas distribuidos (RMI) y da soporte a la tecnología WEB, MDE, etc. Por su productividad posiblemente sea actualmente el lenguaje de mayor uso. 26 Programación OO con Java Java es un lenguaje orientado a objetos puro, por lo que todo problema diseñado como OO, tiene una implementación directa y en gran parte automática con Java. En esta asignatura los programas los diseñamos utilizando el modelado UML gráfico OO y luego los trasladamos directamente a Java. Aspectos que hay que desarrollar: 1. 2. 3. 4. Restricciones que introduce Java: Modelo OO de Java. Tipos primitivos de Java y operaciones básicas Sentencias de control del flujo de Java. Librerías Java. 27 Restricciones de Java Java introduce un conjunto de restricciones sobre el modelo conceptual general OO de programación: Herencia de implementación simple y herencia de interface múltiple. Gestión de memoria basada en Heap y recolector de basura. Representación física de la información no específicada. Modelo de concurrencia basada en secciones críticas y monitores. ……. La mayoría de las restricción han sido impuestas para incrementar la sencillez y la produtividad de la programación. 28 Tipos primitivos de Java (Tipos enteros) Tipos enteros: byte: Es un entero de 8 bits complemento a dos. Su rango es -128 a 127 (ambos inclusivos). Es muy importante en las interfaces de I/O. short: Es un entero de 16 bits complemento a dos. Su rango es -32,768 a 32,767 (ambos inclusivos). Es muy importante en las interfaces de I/O y en sistemas con restricciones de memoria. int: El el entero genérico de 32 bits complemento a dos. Su rango es 2,147,483,648 a 2,147,483,647 (ambos inclusive). Generalmente este tipo es la elección predeterminada para valores enteros. long: Es un entero de 64 bits complemento a dos. Su rango es 9,223,372,036,854,775,808 a 9,223,372,036,854,775,807 (ambos inclusivos). Lo utilizaremos frecuentemente para codificar información temporal. 29 Tipos primitivos en Java (Tipos reales) float: Es un real en coma flotante IEEE 754 de 32 bits y precisión simple. Se suele utilizar en problemas que no requieren excesiva resolución. double: Es un real en coma flotante IEEE 754 de 64 bits y precisión doble. Normalmente este tipo de dato es la elección predeterminada para valores reales. 30 Tipos primitivos en Java (Tipos discretos) boolean: El tipo de dato booleano con sólo dos valores posibles: true (verdadero) y false (falso). Se utiliza en relaciones lógicas. Su «tamaño» no está definido en la especificación Java. char: El tipo de dato char es un solo carácter Unicode de 16 bits. Tiene un valor mínimo de '\u0000' (o «0») y un máximo de '\uffff' (o 65.535 inclusive). 31 Literales Los tipos primitivos no se crean sino se especifican como un literal. Literales boolean: true y false. Literales Enteros: Se pueden expresar su tipo y con codificación decimal, octal y hexadecimal: Ej.: decimal: 26 decimal: 26L octal: 032 hexadecimal: 0x1A Literales Reales: Con formulación punto fijo y punto flotante. Ej.: 123.4F 123.4D 1.234E2 Literales char: Como un carácter o por su código Unicode de 16 bits, mediante \. Ej: ‘a’ \u0108 \b (retroceso de carácter), \t (tabulación), \n (cambio de línea), \f (salto de página), \r (retorno de carro), \" (comillas dobles), \' (comillas simples) y \\ (barra invertida). 32 Tipos básicos no primitivos Tipo String es definido a través de la clase predefinida java.lang.String. Tipos enumerados: Se definen mediante clases derivadas de la clase predefinida java.lang.enum enum DiaSemana {LUNES, MARTES, MIÉRCOLES, JUEVES, VIERNES, SABADO, DOMINGO} Arrays: Son también clases y se pueden definir de tipos primitivos o de clases. Ej.: int[] elArray1= new int[4]; int[] elArray2={100,200,302,400}; 33 Operaciones sobre tipo primitivos (Aritméticos) Binarios + * / % suma resta multiplicación división módulo . Unarios + - No modifica el signo Invierte el signo 34 Operaciones sobre tipo primitivos (Relacionales) Operador Expresión Resultado > A>B true si A es mayor que B >= A >= B false si A es mayor o igual que B < A<B true si A es menor que B <= A <= B true si A es menor o igual que B == A == B true si A es igual a B != A != B true si A es distinto de B 35 Operaciones sobre tipo primitivos (Booleanos) Nombre Operador Expresión Resultado AND && A && B verdadero cuando A y B son verdaderos. Evaluación condicional. OR || A || B verdadero cuando A o B son verdaderos. Evaluación condicional. NOT ! !A verdadero si A es falso. AND & A& B verdadero cuando A y B son verdaderos. Siempre evalúa ambos operandos. OR | A|B verdadero cuando A o B son verdaderos. Siempre evalúa ambos operandos. XOR ^ A^B verdadero cuando A y B son diferentes 36 Operaciones sobre tipo primitivos (Bits) Operador Expresión Resultado << A << B Desplazamiento de A a la izquierda en B posiciones >> A >> B Desplazamiento de A a la derecha en B posiciones, tiene en cuenta el signo. >>> A >>> B Desplazamiento de A a la derecha en B posiciones, no tiene en cuenta el signo. & A&B Operación AND a nivel de bits | A|B Operación OR a nivel de bits ^ A^B Operación XOR a nivel de bits ~ ~A Complemento de A a nivel de bits 37 Operaciones sobre tipo primitivos (Asignación) Operación Operador Expresión Operación equivalente Asignación = A=B El valor de A toma el valor de B Suma += A += B A=A+B Resta -= A -= B A=A- B Multiplicación *= A *= B A=A*B División /= A /= B A=A/B Resto de división %= A %= B A=A%B Desplazamiento a la izquierda <<= A <<= B A = A << B Desplazamiento a la derecha >>= A >>= B A = A >> B Desplazamiento a la derecha sin signo >>>= A >>>= B A = A >>> B AND de bits &= A &= B A=A&B OR de bits |= A |= B A=A|B XOR de bits ^= A ^= B A=A^B 38 Operación cast (asignación explícita de tipo) Permite cambiar explícitamente el tipo de un dato. Este operador aparece como el nombre del tipo a obtener entre paréntesis; siempre antepuesto al resultado que se debe modificar. Ej: byte a=(byte)(22+15); 39 Precedencia de las operaciones Descripción Operadores operadores posfijos op++ op-- operadores unarios ++op --op +op -op ~ ! multiplicación y división */% suma y resta +- desplazamiento << >> >>> operadores relacionales < > <= => equivalencia == != operador AND & operador XOR ^ operador OR | AND booleano && OR booleano || condicional ?: operadores de asignación = += -= *= /= %= &= ^= |= <<= >>= >>>= Mayor precedencia Menor precedencia 40 Sentencias de control de flujo Como regla general las sentencias de un programa se ejecutan secuencialmente en el orden en que se han escrito. Las sentencias de control de flujo permiten cambiar el orden de ejecución de las sentencias dentro de la ejecución de un programa. Tipos de sentencias: Sentencias de selección: Nos permite ejecutar diferentes segmentos de código a partir del estado de la clase. Sentencia if-else Sentencia switch Sentencia ? Sentencias de iteración: Nos permite ejecutar repetidamente una sección de código: Sentencia while Sentencia do-while Sentencia for Sentencia try-catch-finally 41 Sentencia de control if-else La sentencia if-else permite ejecutar una de dos secciones de código en base a una condición booleana. if ( expresión booleana){ Bloque de código a ejecutar si la expresión es true }else { Bloque de código a ejecutar si la expresión es false } El bloque else es opcional. 42 Sentencia switch-case Se ejecuta selectivamente una sentencia según el valor de cierta expresión discreta. switch ( expresionDiscreta ) { case valor1 : conjuntoDeSentencias1; break; case valor2 : conjuntoDeSentencias2; break; case valor3: conjuntoDeSentencias3; break; default: conjuntoDeSentencias4; } 43 Sentencia condicional ? Es un tipo de estructura if-else que se puede utiliza como una expresión dentro de una sentenciaExpresión booleana1 ? SentenciaTrue : SentenciaFalse Ejemplo de utilización System.out.println((num%2)==0 ? "PAR" : "IMPAR"); 44 Bucle while Es el bucle básico de iteración que realizar una acción sucesivamente mientras se cumpla una determinada condición. while ( expresiónBooleana ) { Bloque de sentencias; }; 45 Bucle do-while Es un bucle while, pero en el que la expresión booleana se evalúa al final del bucle. do { Bloque de sentencias; } while ( ExpresiónBooleana ); 46 Sentencia for Sentencia de iteración sobre un conjunto discretos de valores. for ( iniciación ; terminación ; incremento ){ Bloque de sentencias; } Ejemplo: for( int i=1; i<10; i++ ){ System.out.print(" i="+i); } Otra forma más modernma de uso del for (versiones 1.5 o más): int[] numbers = {1,2,3,4,5,6,7,8,9,10}; for (int item : numbers) System.out.println("Count is: " + item); (esto funciona para arrays, colecciones y tipos enumerados) for (Planet p : Planet.values()) { System.out.printf("Your weight on %s is %f%n", p, p.surfaceWeight(mass)); } (https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html) 47 Sentencia intermedias para bucles de iteración Sentencia break: Provoca que el flujo de control salga del bloque en curso. int k= ....; for ( int i = 0 ; i < 10 ; i++ ) { if ( ( i >=k ) break; System.out.print( " " + i ); } Sentencia continue : Salta a ejecutar la siguiente iteración. Ejemplo: for ( int i = 0 ; i < 10 ; i++ ) { if ( ( i % 3 ) == 0 ) continue; System.out.print( " " + i ); } (si hay varios Loops anidados se puede etiquetar el requerido y saltar a él) Sentencia return: Sale del método en curso y retornar a la sentencia dentro de la cual se realizó la llamada. 48 Gestión de excepciones Las excepciones son una forma diferente de controlar el flujo de un programa. Con ellas se podrán realizar acciones especiales en el momento que determinadas condiciones o eventos asíncronos (Excepciones) se produzcan. Existen varios tipos fundamentales de excepciones: Error: Excepciones que indican problemas muy graves, que suelen ser no recuperables y no suelen casi nunca ser capturadas. Exception: Excepciones recuperables, pero que se prevén como posibles fuera del tiempo de ejecución. RuntimeException: Excepciones que se dan durante la ejecución del programa a menudo por errores en la lógica del programa o el uso del lenguaje. Sentencia de atención de interrupciones try { Bloque de sentencias supervisado } catch( Tipo de excepción e ) { Bloque de sentencias si hay excepción } catch( Tipo de excepción e ) { Bloque de sentencias si hay excepción } finally { Bloque de sentencias que se ejecuta en cualquier caso } https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html 49 Paquetes predefinidos Java tiene predefinidos una enorme cantidad de clase organizadas por paquetes. Todos ellos bastante bien documentados. Saber programar Java es en gran medida saber que esos paquetes existen The Java Language Specification, Java SE 7 Edition Java API - Oracle Documentation https://docs.oracle.com/javase/tutorial/ https://docs.oracle.com/javase/tutorial/java/index.html 50