Universidad tecnológica oteima Trabajo de Investigación Presentado por: Alan Pineda 4-813-1871 Facilitador: Carlos Casasola Tema (Fundamentos de programación orientada a objetos) II Segundo Cuatrimestre de Informática Introducción Historia de la Programación Orientada a Objetos. Conceptos Fundamentales de la Programación Orientada a Objeto. Características Del Modelo Orientado a Objetos. Elementos Primordiales en el Modelo de Objetos. Relaciones Entre Clases y Objetos. Lenguajes Orientados a Objetos. Relación Entre La Programación Orientada a Objetos y La Estructurada. Historia de la Programación Orientada a Objetos La Programación Orientación a Objetos (P.O.O.) surge en Noruega en 1967 con un lenguaje llamado Simula 67, desarrollado por Krinsten Nygaard y Ole-Johan Dahl, en el centro de cálculo noruego. Simula 67 introdujo por primera vez los conceptos de clases, corrutinas y subclases (conceptos muy similares a los lenguajes Orientados a Objetos de hoy en día). El nacimiento de la Programación Orientación a Objetos en Europa pasó inadvertido para gran parte de los programadores. Hoy tenemos la Orientación a Objetos como un niño de 33 años al que todos quieren bautizar. Uno de los problemas de inicio de los años setentas era que pocos sistemas lograban terminarse, pocos se terminaban con los requisitos iniciales y no todos los que se terminaban cumpliendo con los requerimientos se usaban según lo planificado. El problema consistía en cómo adaptar el software a nuevos requerimientos imposibles de haber sido planificados inicialmente. Este alto grado de planificación y previsión es contrario a la propia realidad. El hombre aprende y crea a través de la experimentación, no de la planeación. La Orientación a Objetos brinda estos métodos de experimentación, no exige la planificación de un proyecto por completo antes de escribir la primera línea de código. En los 70’s científicos del centro de investigación en Palo Alto Xerox (Xerox park) inventaron el lenguaje Small talk que dio respuesta al problema anterior (investigar no planificar). Small talk fue el primer lenguaje Orientado a Objetos puro de los lenguajes Orientados a Objetos, es decir, únicamente utiliza clases y objetos (Java usa tipos de datos primitivos, o bien los Wrappers que son clases que encapsulan tipos de datos primitivos). Quien tuvo la idea fue D. Parnas cuando propuso la disciplina de ocultar la información. Su idea era encapsular cada una de las variables globales de la aplicación en un solo módulo junto con sus operaciones asociadas, sólo mediante las cuales se podía tener acceso a esas variables. El resto de los módulos (objetos) podían acceder a las variables sólo de forma indirecta mediante las operaciones diseñadas para tal efecto. En los años 80’s Bjarne Stroustrup de AT&T Labs., amplió el lenguaje C para crear C++ que soporta la programación Orientada a Objetos. En esta misma década se desarrollaron otros lenguajes Orientados a Objetos como Objective C, Common Lisp Object System (CIOS), object Pascal, Ada y otros. Posteriores mejoras en herramientas y lanzamientos comerciales de C++ por distintos fabricantes, justificaron la mayor atención hacia la programación Orientada a Objetos en la comunidad de desarrollo de software. El desarrollo técnico del hardware y su disminución del costo fue el detonante final. Con más computadoras al alcance de más personas más programadores, más problemas y más algoritmos surgieron. En el inicio de los 90’s se consolida la Orientación a Objetos como una de las mejores maneras para resolver problemas. Aumenta la necesidad de generar prototipos más rápidamente (concepto RAD Rapid Aplication Developments). Sin esperar a que los requerimientos iniciales estén totalmente precisos. En 1996 surge un desarrollo llamado JAVA (extensión de C++). Su filosofía es aprovechar el software existente. Facilitar la adaptación del mismo a otros usos diferentes a los originales sin necesidad de modificar el código ya existente. En 1997-98 se desarrollan herramientas ‘CASE’ orientadas a objetos (como el diseño asistido por computadora). Del 98 a la fecha se desarrolla la arquitectura de objetos distribuidos RMI, Corba, COM, DCOM. Actualmente la orientación a objetos parece ser el mejor paradigma, no obstante, no es una solución a todos los problemas. Trata de eliminar la crisis del software. Entre los creadores de metodologías orientadas a objetos se encuentran: G. Booch, Rambaught, Ivar Jacobson y Peter Cheng. Conceptos Fundamentales de la Programación Orientada a Objeto A continuación te mostramos algunas cuantas definiciones que serán de utilidad en las futuras prácticas que se realicen. Programación: La programación se basa en la edición, manipulación e interpretación de la información dada por el usuario hacia un software. Existen un sin fin de lenguajes de programación y se debe ocupar el adecuado para interactuar con un software determinado. Software: El concepto más utilizado (en electrónica basándonos en Visual Basic) es que es el software es un programa informático intangible que se encarga de realizar una o varias acciones dentro de un entorno en constante cambio de información. Sin embargo algo más acertado es que Software es toda información que el usuario le entrega a una computadora para que posteriormente esta sea interpretada y manipulada (dependiendo de las ordenes que posea la computadora u ordenador) para obtener un resultado final. Atributo: Esto puede definirse como una propiedad, método o característica a un elemento de clase. Un atributo es utilizado para definir bajo qué condiciones el código será accesible en otras partes del programa. Los atributos más comunes son Private y Publicó, estos atributos son utilizados en muchos lenguajes de programación, en el caso de visual Basic el atributo Private solo puede ser llamado o usado dentro la misma clase, en cambio el atributo Publicó puede ser llamada desde cualquier parte del programa. Clase: Esta puede ser definida como la estructura dentro de una plantilla de programación, esta también puede regir el comportamiento de objetos de un tipo determinado. En visual Basic se ocupa una clase por cada elemento gráfico dentro del entorno de programación. Jerarquía de clases: Una clase como se mencionó anteriormente es una plantilla de programación, la jerarquía de clases no es más que la herencia de características o datos a otras clases de mayor o menor nivel dentro del mismo programa. Constructor: método especial que se puede definir en una clase y que se llama para crear una instancia de la clase. Se suele utilizar un constructor para especificar valores predeterminados o realizar operaciones de configuración del objeto. Tipo de datos: Cuando se realiza una programación se debe tener en cuenta que el programa no entiende que los caracteres que ingresamos son numéricos o alfanuméricos, por lo tanto se debe especificar qué tipos de datos ingresamos en caso de necesitar realizar procedimientos matemáticos o físicos. Variables: Al trabajar con programación orientada a objetos es muy común el uso de variables, por ejemplo en el caso de una calculadora que suma 2 números y entrega un resultado, los 3 datos son variables y pueden interpretarse como X1 + X2 = Xt, una vez que ingresemos los valores las variables ya poseen datos definidos y en dicha operación se transforman en constantes siempre y cuando tengan datos asignados. Constantes: Si un dato está definido es muy común el uso de constantes, por ejemplo al realizar un programa para encontrar la resistencia en un circuito que se mantiene con un voltaje constante de 5 V, podemos decir que 5 V es una constante ya que no cambiara en el procedimiento y podemos expresar esto de la siguiente forma: R = (5 V) * (I1). R se mantiene como variable hasta que se le asigne un valor a I1 y se realice la operación. Nombres: En el caso de la programación orientada a objetos se debe nombrar a cada objeto para que este se rija en base a la programación asignada, es muy importante con confundir al nombre que se le asigna al objeto con el Texto que se muestra en la pantalla ya que son muy diferentes. Una analogía de esto sería: En la escuela te llaman de una manera en tu casa te llamaran por tu nombre, el apodo que te han dado en la escuela te representa pero no posee ninguno valor que te autentifique ante otros elementos. Siclos: Dentro de un programa hay algunos siclos de programación utilizados para comparar valores o instrucciones, por ejemplo si creamos un programa para ingresar una imagen pero esta no debe sobrepasar de 1 Mb de peso, nosotros debemos decirle al programa con un ciclo que compare el peso de la imagen con el peso máximo permitido, si la imagen pesa menos entonces esta puede pasar a la siguiente instrucción que le asignemos al programa, en cambio si la imagen pesa más del máximo permitido el programa devuelve una ventana de erro y pide ingresar una imagen de menor tamaño. Interfaz gráfica: Es la plantilla que usaremos el blanco para diseñar nuestro programa, en este se pueden agregar botones, textos y otros elementos que interactúen con el programa que hemos creado. Herencia: mecanismo de la programación orientada a objetos que permite a una definición de clase incluir toda la funcionalidad de una definición de clase distinta (y añadir nueva funcionalidad). Instancia: objeto real creado en un programa. Características Del Modelo Orientado a Objetos Abstracción: Denota las características esenciales de un objeto, donde se capturan sus comportamientos. sirve como modelo de un "agente" abstracto que puede realizar trabajo, informar y cambiar su estado, y "comunicarse" con otros objetos en el sistema sin revelar cómo se implementan estas características. podemos llegar a armar un conjunto de clases que permitan modelar la realidad o el problema que se quiere atacar. Encapsulamiento: Significa reunir todos los elementos que pueden considerarse pertenecientes a una misma entidad, al mismo nivel de abstracción. Esto permite aumentar la cohesión (diseño estructurado) de los componentes del sistema. Algunos autores confunden este concepto con el principio de ocultación, principalmente porque se suelen emplear conjuntamente. Polimorfismo: Comportamientos diferentes, asociados a objetos distintos, pueden compartir el mismo nombre; al llamarlos por ese nombre se utilizará el comportamiento correspondiente al objeto que se esté usando. O, dicho de otro modo, las referencias y las colecciones de objetos pueden contener objetos de diferentes tipos, y la invocación de un comportamiento en una referencia producirá el comportamiento correcto para el tipo real del objeto referenciado. Cuando esto ocurre en "tiempo de ejecución", esta última característica se llama asignación tardía o asignación dinámica. Algunos lenguajes proporcionan medios más estáticos (en "tiempo de compilación") de polimorfismo, tales como las plantillas y la sobrecarga de operadores de C++. Herencia: Las clases no se encuentran aisladas, sino que se relacionan entre sí, formando una jerarquía de clasificación. Los objetos heredan las propiedades y el comportamiento de todas las clases a las que pertenecen. La herencia organiza y facilita el polimorfismo y el encapsulamiento, permitiendo a los objetos ser definidos y creados como tipos especializados de objetos preexistentes. Estos pueden compartir (y extender) su comportamiento sin tener que volver a implementarlo. Esto suele hacerse habitualmente agrupando los objetos en clases, y estas en árboles o enrejados que reflejan un comportamiento común. Cuando un objeto hereda de más de una clase, se dice que hay herencia múltiple; siendo de alta complejidad técnica por lo cual suele recurrirse a la herencia virtual para evitar la duplicación de datos. Modularidad: Se denomina "modularidad" a la propiedad que permite subdividir una aplicación en partes más pequeñas (llamadas módulos), cada una de las cuales debe ser tan independiente como sea posible de la aplicación en sí y de las restantes partes. Estos módulos se pueden compilar por separado, pero tienen conexiones con otros módulos. Al igual que la encapsulación, los lenguajes soportan la modularidad de diversas formas. Principio de ocultación: Cada objeto está aislado del exterior, es un módulo natural, y cada tipo de objeto expone una "interfaz" a otros objetos que específica cómo pueden interactuar con los objetos de la clase. El aislamiento protege a las propiedades de un objeto contra su modificación por quien no tenga derecho a acceder a ellas; solamente los propios métodos internos del objeto pueden acceder a su estado. Esto asegura que otros objetos no puedan cambiar el estado interno de un objeto de manera inesperada, eliminando efectos secundarios e interacciones inesperadas. Algunos lenguajes relajan esto, permitiendo un acceso directo a los datos internos del objeto de una manera controlada y limitando el grado de abstracción. La aplicación entera se reduce a un agregado o rompecabezas de objetos. Recolección de basura: La recolección de basura (garbage collection) es la técnica por la cual el entorno de objetos se encarga de destruir automáticamente, y por tanto desvincular la memoria asociada, los objetos que hayan quedado sin ninguna referencia a ellos. Esto significa que el programador no debe preocuparse por la asignación o liberación de memoria, ya que el entorno la asignará al crear un nuevo objeto y la liberará cuando nadie lo esté usando. En la mayoría de los lenguajes híbridos que se extendieron para soportar el Paradigma de Programación Orientada a Objetos como C++ u Object Pascal, esta característica no existe y la memoria debe desasignarse expresamente. Elementos Primordiales en el Modelo de Objetos La programación Orientada a Objetos trata de cumplir las necesidades de los usuarios finales, estás tareas se realizan mediante la modelización del mundo real, el soporte fundamental es el modelo objeto. Los elementos más importantes de este modelo son: Abstracción La abstracción, un principio por el cual se aísla toda aquella información que no resulta relevante a un determinado nivel de conocimiento. Encapsulamiento En programación modular, y más específicamente en programación orientada a objetos, se denomina encapsulamiento al ocultamiento del estado, es decir, de los datos miembro, de un objeto de manera que sólo se puede cambiar mediante las operaciones definidas para ese objeto. Cada objeto está aislado del exterior, es un módulo natural, y la aplicación entera se reduce a un agregado o rompecabezas de objetos. El aislamiento protege a los datos asociados a un objeto contra su modificación por quien no tenga derecho a acceder a ellos, eliminando efectos secundarios e interacciones. De esta forma el usuario de la clase puede obviar la implementación de los métodos y propiedades para concentrarse sólo en cómo usarlos. Por otro lado se evita que el usuario pueda cambiar su estado de maneras imprevistas e incontroladas. Modularidad La modularidad es la capacidad que tiene un sistema de ser estudiado, visto o entendido como la unión de varias partes que interactúan entre sí y que trabajan para alcanzar un objetivo común, realizando cada una de ellas una tarea necesaria para la consecución de dicho objetivo. Cada una de esas partes en que se encuentre dividido el sistema recibe el nombre de módulo. Idealmente un módulo debe poder cumplir las condiciones de caja negra, es decir, ser independiente del resto de los módulos y comunicarse con ellos (con todos o sólo con una parte) a través de unas entradas y salidas bien definidas. Jerarquía y Herencia La Jerarquía es una propiedad que permite la ordenación de las abstracciones. Las dos jerarquías más importantes de un sistema complejo son: estructura de clases (jerarquía “es-un” (is-a): generalización/especialización) y estructura de objetos (jerarquía “parte-de” (part-of): agregación). Las jerarquías de generalización/especialización se conocen como herencia. Básicamente, la herencia define una relación entre clases, en donde una clase comparte la estructura o comportamiento definido en una o más clases (herencia simple y herencia múltiple, respectivamente). La agregación es el concepto que permite el agrupamiento físico de estructuras relacionadas lógicamente. Así, un camión se compone de ruedas, motor, sistema de transmisión y chasis; en consecuencia, camión es una agregación, y ruedas, motor, transmisión y chasis son agregados de camión. Polimorfismo La quinta propiedad significativa de los lenguajes de programación orientados a objetos es el polimorfismo. Es la propiedad que indica, literalmente, la posibilidad de que una entidad tome muchas formas. En términos prácticos, el polimorfismo permite referirse a objetos de clases diferentes mediante el mismo elemento de programa y realizar la misma operación de diferentes formas, según sea el objeto que se referencia en ese momento. Por ejemplo, cuando se describe la clase mamíferos se puede observar que la operación comer es una operación fundamental en la vida de los mamíferos, de modo que cada tipo de mamífero debe poder realizar la operación o función comer. Por otra parte, una cabra o una vaca que pastan en un campo, un niño que se come un caramelo y un león que devora a otro animal, son diferentes formas que utilizan diferentes mamíferos para realizar la misma función (comer). El polimorfismo adquiere su máxima expresión en la derivación o extensión de clases, es decir, cuando se obtiene una clase a partir de una clase ya existente, mediante la propiedad de derivación de clases o herencia. El polimorfismo requiere ligadura tardía o postergada (también llamada dinámica), y esto sólo se puede producir en lenguajes de programación orientados a objetos. Los lenguajes no orientados a objetos soportan ligadura temprana o anterior (también llamada estática), esto significa que el compilador genera una llamada a un nombre específico de función y el enlazador (linker) resuelve la llamada a la dirección absoluta del código que se ha de ejecutar. En POO, el programa no puede determinar la dirección del código hasta el momento de la ejecución. Cuando se envía un mensaje a un objeto, el código que se llama no se determina hasta el momento de la ejecución. El compilador asegura que la función existe y realiza verificación de tipos de los argumentos y del valor de retorno, pero no conoce el código exacto a ejecutar. Relaciones Entre Clases y Objetos Ahora que ya conocemos los objetos, sus tipos, sus atributos, su comportamiento (métodos), sus características, podemos seguir con el reconocimiento de ellos dentro de la especificación de problemas que deseamos solucionar aplicando la orientación a objetos. La interacción entre objeto se efectúa mediante mensajes. Un mensaje se envía a un objeto utilizando un método de la clase. En ocasiones un objeto envía un mensaje a otro objeto de la misma clase o de otra clase, a veces un objeto se envía asimismo el mensaje. Por ejemplo, un chofer (objeto) envía el mensaje Avanzar a un objeto carro. La forma del mensaje seria: carro. Avanza. Vemos que la sintaxis para construir un mensaje está compuesta de 2 partes: el nombre del objeto y el nombre del método. Ambos deben pertenecer a la clase, tanto el objeto como el método. Otro mensaje podría ser el que usa el método Arrancar, carro. Arrancar. Los métodos reciben parámetros para caracterizar de manera definida a su acción. Por ejemplo cuando usamos el mensaje carro. Avanzar, podemos enviar al metodoAvanzar un parámetro que indique la velocidad, de manera que ahora escribiríamos el mensaje de la siguiente forma: Carro. Avanzar o carro. Avanzar (reversa) o carro. Avanzar (segunda), y así por el estilo. Observamos que el parámetro se ha incluido entre paréntesis. Un método que no reciba parámetro, puede escribirse con los paréntesis vacíos. Por ejemplo: Carro. Encender () Cuando escribimos programas orientados a objetos, estos están compuestos de mensajes. Lenguajes Orientados a Objetos Los lenguajes de programación orientados a objetos tratan a los programas como conjuntos de objetos que se ayudan entre ellos para realizar acciones. Entendiendo como objeto al entidades que contienen datos. Permitiendo que los programas sean más fáciles de escribir, mantener y reutilizar. Los objetos tienen toda la información (atributos) que los diferencia de otros pertenecientes a otra clase. Por medio de unos métodos se comunican los objetos de una misma o diferente clase produciendo el cambio de estado de los objetos. Esto hace que a los objetos se les trate como unidades indivisibles en las que no se separan la información ni los métodos usados en su tratamiento. Los lenguajes de programación orientados a objetos tienen su origen en un lenguaje que fue diseñado por los profesores Ole-Johan Dahl y Kristen Nygaard en Noruega. Este lenguaje de programación orientado a objetos fue el “Simula 67” que fue un lenguaje creado para hacer simulaciones de naves. Los lenguajes de programación orientadas a objetos son lenguajes dinámicos en los que estos objetos se pueden crear y modificar sobre la marcha. Esta programación orientada a objetos (POO) tomo auge a mediados de los años ochenta debido a la propagación de las interfaces gráficas de usuarios, para lo que los lenguajes de programación orientados a objetos están especialmente dotados. Los principales lenguajes de programación orientados a objetos son: Ada, C++, C#, VB.NET, Clarión, Delphi, Eiffel, Java, Léxico (en castellano), Objective-C, Ocaml, Oz, PHP, PowerBuilder, Python, Ruby y Smalltalk. No todos estos lenguajes de programación orientados a objetos son específicamente orientados a objetos. Sino que algunos de ellos se le han añadido extensiones orientadas a objetos. Un nuevo paso en los lenguajes de programación es la Programación orientada a aspectos (POA). Actualmente está en fase de desarrollo, pero cada vez atrae a más investigadores y empresas de todo el mundo. Relación Entre La Programación Orientada a Objetos y La Estructurada Diferencias con la programación estructurada y la programación orientada a objetos Aunque la programación estructurada (a veces llamada procedural o procedimental) condujo a mejoras de la técnica de programación secuencial, los métodos modernos de diseño de software orientado a objetos incluyen mejoras entre las que están el uso de los patrones de diseño, diseño por contrato, y lenguajes de modelado (ej.: UML). Las principales diferencias entre la programación estructurada y la orientada a objetos son: · La programación orientada a objetos es más moderna, es una evolución de la programación estructurada que plasma en el diseño de una familia de lenguajes conceptos que existían previamente con algunos nuevos. · La programación orientada a objetos se basa en lenguajes que soportan sintáctica y semánticamente la unión entre los tipos abstractos de datos y sus operaciones (a esta unión se la suele llamar clase). · La programación orientada a objetos incorpora en su entorno de ejecución mecanismos tales como el polimorfismo y el envío de mensajes entre objetos. Erróneamente se le adjudica a la programación estructurada clásica ciertos problemas como si fueran inherentes a la misma. Esos problemas fueron haciéndose cada vez más graves y antes de la programación orientada a objetos diversos autores (de los que podemos destacar a Yourdon) encontraron soluciones basadas en aplicar estrictas metodologías de trabajo. De esa época son los conceptos de cohesión y acoplamiento. De esos problemas se destacan los siguientes: · Modelo mental anómalo. Nuestra imagen del mundo se apoya en los seres, a los que asignamos nombres sustantivos, mientras la programación clásica se basa en el comportamiento, representado usualmente por verbos. · Es difícil modificar y extender los programas, pues suele haber datos compartidos por varios subprogramas, que introducen interacciones ocultas entre ellos. · Es difícil mantener los programas. Casi todos los sistemas informáticos grandes tienen errores ocultos, que no surgen a la luz hasta después de muchas horas de funcionamiento. · Es difícil reutilizar los programas. Es prácticamente imposible aprovechar en una aplicación nueva las subrutinas que se diseñaron para otra. · Es compleja la coordinación y organización entre programadores para la creación de aplicaciones de media y gran envergadura. En la programación orientada a objetos pura no deben utilizarse llamadas de subrutinas, únicamente mensajes. Por ello, a veces recibe el nombre de programación sin CALL, igual que la programación estructurada se llama también programación sin GOTO. Sin embargo, no todos los lenguajes orientados a objetos prohíben la instrucción CALL (o su equivalente), permitiendo realizar programación híbrida, imperativa y orientada a objetos a la vez.