I.T.S.C. Técnico Superior en Desarrollo de Software Programación II PROGRAMACIÓN ORIENTADA A OBJETOS RESEÑA HISTÓRICA En la siguiente imagen vemos la evolución de los lenguajes de programación orientados a objetos, esta metodología no es nueva, sin embargo es hoy en día que este concepto o tecnología está acaparando los desarrollos de software debido a la gran aceptación, implementación y popularidad. Comúnmente se piensa que la programación orientada a objetos es un fenómeno relativamente reciente dentro de la ciencia de la computación. Por el contrario, en realidad, casi todos los conceptos principales actualmente asociados con los programas orientados a objetos, tales como objetos, clases y jerarquías de herencia, fueron desarrollados en los años 60 como parte de un lenguaje llamado Simula, diseñado por investigadores en el Centro de Computación Noruego (Norwegian Computing Center). Como el nombre lo indica, Simula fue un lenguaje inspirado por los problemas involucrados en la simulación de sistemas de la vida real. Sin embargo, la importancia de estas construcciones, aún para los propios desarrolladores de Simula, fue reconocida parcialmente En la década del 70 Alan Kay organizó un equipo de investigación en Xerox PARC (Palo Alto Research Center o “Centro de Investigación Palo Alto”). Con una gran presciencia o previsión, Kay predijo la próxima revolución en la computación personal que se desarrollaría cerca de una década más tarde (ver, por ejemplo, su artículo de 1977 en Scientific American). Kay estaba interesado en descubrir un lenguaje de programación que fuera entendible para aquellos profesionales ajenos a la computación, para la gente común sin ningún tipo de entrenamiento en el uso de computadoras. Encontró en las nociones de clases y en la computación como simulación una metáfora que fácilmente podría llegar a ser comprendida por los usuarios principiantes, como luego demostraría mediante una serie de experimentos dirigidos en PARC usando a los chicos como programadores. El lenguaje de programación desarrollado por su equipo fue llamado Smalltalk. Este lenguaje evolucionó a través de varias revisiones durante la década. Un artículo muy popular de la revista Byte de 1981 contribuyó para popularizar en gran medida los conceptos desarrollados por Kay y su equipo en Xerox. Casi contemporáneo al trabajo de Kay fue otro proyecto llevado a cabo al otro lado del continente. Bjarne Stroustrup, un investigador de los Laboratorios Bell que había aprendido Simula mientras Prof. Rearte, Judith 1/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II completaba su doctorado en la Universidad de Cambridge en Inglaterra, se encontraba desarrollando una extensión al lenguaje C que facilitaría la creación de objetos y clases. Esto se transformaría luego en el lenguaje C++ . Con la difusión de información sobre estos y otros proyectos similares, comenzó un aumento vertiginoso de la investigación sobre técnicas de programación orientada a objetos. Al momento de producirse la primera conferencia importante sobre programación orientada a objetos, en 1986, hubo literalmente docenas de nuevos lenguajes de programación compitiendo para ser aceptados. Entre estos incluidos Eiffel, Objective-C, Actor, Object Pascal, y varios dialectos de Lisp. En las dos décadas desde la conferencia de OOPSLA en 1986, la programación orientada a objetos ha pasado de ser revolucionaria a ser el movimiento principal, y en este proceso ha transformado gran parte de la ciencia de la computación. Simula: Por los años 60, los programadores comprendieron que era necesario descomponer los sistemas de programación en partes pequeñas más manejables. La introducción de Simula-67 trajo consigo la primera noción de objetos, las clases, y una especie de herencia; por lo tanto, Simula es un hito importante en cualquier debate sobre lenguajes de programación OO. El lenguaje fue diseñado por OleJohan Dahl, Bjørn Myhrhaug y Kristen Nygaard en el Norwegian Computing Center ubicado en Oslo. La primer versión del lenguaje, Simula-1, fue presentada en 1966. Los módulos de programación definidos por Simula no se basaron en procedimientos, sino en objetos físicos tangibles. Simula tuvo una novedosa manera de plantear los objetos, en donde que cada objeto tiene sus propios datos y comportamiento. Smalltalk: Muchos consideran que el primer lenguaje verdaderamente orientado a objetos fue Smalltalk, desarrollado en el Learning Research Group en Xerox's Palo Alto Research Center a principios de los 70. En Smalltalk, todo es realmente un objeto, lo que impone el paradigma OO y hace que sea prácticamente imposible escribir un programa en Smalltalk que no sea OO. Smalltalk es en realidad un ambiente de programación interactivo que interpreta código sobre la marcha (on-the-fly) lo que permite cambiar los parámetros y el código de un programa mientras el programa está corriendo. Smalltalk fue el primero en introducir muchos otros conceptos que luego aparecerían como revolucionarios al ser implementados en otras aplicaciones, como los buscadores o exploradores (browsers), las ventanas y los menús emergentes (pop-up menus). El ambiente se basa en una máquina virtual, permitiendo a las aplicaciones ser migradas entre diferentes plataformas. C++: Tiene su origen en un proyecto para simular software corriendo en un sistema distribuido. Este simulador, de hecho escrito en Simula, es donde Bjarne Stroustrup concibió la idea de combinar algunas de las características de Simula con la sintaxis de C. El concepto de clase en C++ brindaba el mecanismo de encapsulamiento, que hoy por hoy es un requisito esencial de cualquier lenguaje OO. Aunque C brindó una base sólida para C++, también se convirtió en una carga un tanto pesada. El hecho de hacer a C++ compatible con su predecesor trajo serios inconvenientes. Aunque C++ proporciona construcciones OO, también es posible usar técnicas de programación estructurada. Por este motivo, C++ no es considerado un lenguaje OO puro, si no un lenguaje híbrido. Java: Los orígenes de Java se encuentran en un lenguaje que se apodó Oak. Su creador decidió que basaría su lenguaje en el tan exitoso C++, pero que sólo incorporaría aquellas características de C++ que parecieran valer la pena. Las características que eliminó de C++ fueron la herencia múltiple, las conversiones automáticas de tipos, el uso de punteros, y el esquema de administración de memoria de C++. Pero el proyecto fue archivado por falta de interés en el mercado. Con la llegada de la Web y el surgimiento de los browsers, la gente de Sun comenzó a atar cabos, y así Oak fue rescatado de la inactividad y renombrado como Java. Prof. Rearte, Judith 2/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II C#: Microsoft respondió a la popularidad de Java produciendo una versión de Java llamada Visual J++. Sin embargo, Microsoft se decidió por una respuesta más integral. Usando muchas de las innovaciones que implementaba Java, Microsoft desarrolló un lenguaje denominado C# que se convirtió en la base para la plataforma .NET. De igual manera que Java, C# se basó fuertemente en los éxitos y fracasos de lenguajes anteriores. DISEÑO ORIENTADO A OBJETOS La programación orientada a objetos (POO, u OOP según sus siglas en inglés) es un paradigma de programación que usa objetos en sus interacciones, para diseñar aplicaciones y programas informáticos. Su uso se popularizó a principios de la década de 1990. En la actualidad, existe una gran variedad de lenguajes de programación que soportan la orientación a objetos. Hoy en día la tecnología orientada a objetos ya no se aplica solamente a los lenguajes de programación, además se viene aplicando en el análisis y diseño con mucho éxito, al igual que en las bases de datos. Es que para hacer una buena programación orientada a objetos hay que desarrollar todo el sistema aplicando esta tecnología, de ahí la importancia del análisis y el diseño orientado a objetos. La programación orientada a objetos es una de las formas S N más populares de programar y viene teniendo gran acogida en el desarrollo de proyectos de software desde los últimos años. Esta acogida se debe a sus grandes capacidades y ventajas frente a las antiguas formas de programar. (a < b) b = a+c a = b+c (b<c) b=a+c Tradicionalmente, la programación fue hecha en una manera secuencial o lineal, es decir una serie de pasos consecutivos con estructuras consecutivas y bifurcaciones. Los lenguajes basados en esta forma de programación ofrecían ventajas al principio, pero el problema ocurre cuando los sistemas se vuelven complejos. Estos programas escritos al estilo “espaguetti” no ofrecen flexibilidad y el mantener una gran cantidad de líneas de código en un sólo bloque se vuelve una tarea complicada. Frente a esta dificultad aparecieron los lenguajes basados en la programación estructurada. La idea principal de esta forma de programación es separar las partes complejas del programa en módulos o segmentos que sean ejecutados conforme se requieran. De esta manera tenemos un diseño modular, compuesto por módulos independientes que puedan comunicarse entre sí. Poco a poco este estilo de programación fue reemplazando al estilo “espaguetti” impuesto por la programación lineal. Entonces, vemos que la evolución que se fue dando en la programación se orientaba siempre a ir descomponiendo más el programa. Este tipo de descomposición conduce directamente a la programación orientada a objetos. Pues la creciente tendencia de crear programas cada vez más grandes y complejos llevó a los desarrolladores a crear una nueva forma de programar que les permita crear sistemas de niveles Prof. Rearte, Judith 3/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II empresariales y con reglas de negocios muy complejas. Para estas necesidades ya no bastaba la programación estructurada ni mucho menos la programación lineal. Es así como aparece la programación orientada a objetos (POO). La POO viene de la evolución de la programación estructurada; básicamente la POO simplifica la programación con la nueva filosofía y nuevos conceptos. La POO se basa en la dividir el programa en pequeñas unidades lógicas de código. A estas pequeñas unidades lógicas de código se les llama objetos. Los objetos son unidades independientes que se comunican entre ellos mediante mensajes. VENTAJAS DE UN LENGUAJE ORIENTADO A OBJETOS Fomenta la reutilización y extensión del código. Permite crear sistemas más complejos. Relacionar el sistema al mundo real. Facilita la creación de programas visuales. Construcción de prototipos Agiliza el desarrollo de software Facilita el trabajo en equipo Facilita el mantenimiento del software Lo interesante de la POO (programación orientada a objetos) es que proporciona conceptos y herramientas con las cuales se modela y representa el mundo real tan fielmente como sea posible. El concepto fundamental de la programación orientada a objetos es la clase y existen muchas de ellas implementadas en C#, y están listas para permitirnos crear la gran mayoría de objetos que podemos llegar a necesitar en un programa de consola, tipo Windows o tipo web. Aquellos objetos para los cuales no existan clases podemos crearlas Según Alan Kay (creador de Smalltalk, a principios de los ’70) La POO está basada en el principio de diseño recursivo: 1. Todo son objetos. 2. Los objetos funcionan haciéndose peticiones de uno a otro mediante paso de mensajes. 3. Cada objeto tiene su propia memoria, que consta de otros objetos. 4. Cada objeto es un ejemplar (instancia) de una clase. Una clase agrupa objetos similares. 5. La clase es el repositorio del comportamiento asociado con un objeto 6. Las clases están organizadas en una estructura arbórea que se denomina jerarquía de herencia El contexto del problema se ve como objetos que interactúan entre ellos Prof. Rearte, Judith 4/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II CARACTERÍSTICAS DE LA PROGRAMACIÓN ORIENTACIÓN A OBJETOS Los elementos fundamentales que caractericen a un verdadero lenguaje orientado a objetos, en la mayoría de teorías, son las siguientes: - Abstracción - Encapsulamiento - Herencia - Polimorfismo Abstracción La abstracción la posibilidad de visualizar únicamente aquellos aspectos que interesen de un todo, dejando de lado los detalles que, aunque importantes, no son de interés para un determinado propósito. Significa extraer las propiedades esenciales de un objeto que lo distinguen de los demás tipos de objetos y proporciona fronteras conceptuales definidas respecto al punto de vista del observador. Es la capacidad para encapsular y aislar la información de diseño y ejecución. Qué es ? Y Qué Hace ? Una ventana estándar en cualquier entorno gráfico, como Windows, tiene una forma rectangular y la caracterizan una barra de títulos, un icono que esconde un menú desplegable y tres botones, maximizar, restaurar y cerrar. Para crear esa ventana actuan una serie de complejas acciones que incluyen desde elementos matemáticos hasta principios electrónicos sobre procesamiento digital de gráficos. Pero, en las clases que ofrece .NET, todo eso ha sido aislado del interés del programador, y solo se pone a su disposición unas cuantas propiedades y métodos que le permiten modificar cualquier aspecto de la ventana sin tener que preocuparse de los detalles internos. En otras palabras se ha realizado una abstracción del mecanismo que permite construir una ventana. Prof. Rearte, Judith 5/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II Encapsulamiento El encapsulamiento hace referencia a la protección que debe hacer una clase de los elementos que la conforman, especialmente de aquellos que contienen los datos. Cómo? El encapsulamiento es el proceso de almacenar en un mismo compartimiento (una caja negra) los elementos de una Abstracción (toda la información relacionada con un objeto) que constituyen su estructura y su Comportamiento. Esta información permanece oculta tanto para los usuarios como para otros objetos Y puede ser accedida solo mediante la ejecución de los métodos adecuado. En general una clase es una capsula blindada que protege a sus miembros del mundo exterior y solo permite acceder a ellos mediante mecanismos que garanticen su adecuada modificación o lectura. Establecer esos mecanismos es una tarea del programador. El encapsulamiento exige que todos los campos de una clase se establezcan como privados, y la lectura o modificación de sus valores se realice a través de funciones, que de ser necesario realicen en el momento justo las verificaciones del caso para asegurar que no se han producido infracciones a la abstracción que representa. Herencia La herencia es la característica más importante de la programación orientada a objetos por que permite crear clases que se derivan de otras clases y este es uno de los aspectos vitales en la reutilización de componentes. Específicamente, la herencia es la capacidad que ofrece un lenguaje de programación de poder crear nuevas clases a partir de clases existentes, aprovechando el código de estas últimas. La herencia supone la existencia de una clase base y una o más clases derivadas. Tomando la analogía del mundo real se dice que una clase derivada hereda las características de la clase base, agregando sus propios elementos. En la práctica cuando un programador construye una clase, heredando las características de otra ya existente, lo que está haciendo es utilizar la estructura de esa clase e incorporándola a la suya, y adicional le agrega o incluso le quita algunas características que requiera su desarrollo. En la literatura sobre programación orientada a objetos existen muchos ejemplos didácticos para intentar explicar la herencia, como por ejemplo que las clases Ave, Felino y Mamífero se derivan de la superclase Animal porque todos estos especímenes comparten características, que se Prof. Rearte, Judith 6/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II pueden abstraer en la clase base. En el desarrollo de software lo que el programador debe hacer es identificar todos aquellos campos que se repitan en un conjunto de clases y con ellos formar una clase que le sirva como base para las demás. Los elementos que se incluyeron en la clase base, ya no será necesario especificarlos en las clases derivadas, trayendo como consecuencia una simplificación sustancial en el proceso de programación. Para hacer más didáctica la explicación, supongamos que en una entidad educativa se va a sistematizar, entre otros, los datos del personal vinculado a ella. Para empezar, sabemos que existen alumnos y docentes, cuyos datos los vamos a procesar a través de las clases Alumno y Docente, respectivamente. Alumno Docente NombreYApellido NombreYApellido FechaNacimiento FechaNacimiento Legajo Legajo Curso Horas Tanto los alumnos como los docentes tienen elementos o datos comunes, tales como nombres, apellidos, fecha de nacimiento y edad, y otros que no lo son. Aplicar la propiedad de la herencia en este caso, implica rediseñar las clases creando una nueva clase a partir de los campos que se encuentran repetidos en ambas. A esa clase bien podríamos llamarla Persona. Persona NombreYApellido FechaNacimiento A partir de esta clase se derivan las clases Alumno y Docente con los campos que les hacen falta a cada una de ellas, (En los diagramas UML se acostumbra a representar la herencia mediante una flecha que va desde la clase derivada hasta la clase base. La flecha así dibujada establece una relación de tipo es un.) Persona NombreYApellido FechaNacimiento Alumno Docente Legajo Legajo Curso Horas El nuevo diseño del conjunto de clases, en este ejemplo, va a simplificar la programación de algunos elementos de las clases. Por ejemplo, la edad, de un estudiante o un trabajador, que se puede calcular con base en la fecha de nacimiento, en este caso bastará con programar su cálculo una sola vez y en la clase base. Los resultados estarán disponibles tanto para los objetos que se Prof. Rearte, Judith 7/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II declaren a partir de cualquiera de las clases derivadas, como para aquellos que se definan a partir de la misma clase Persona. La herencia es una propiedad supremamente potente que exige especial cuidado al momento de diseñar un software. Esta propiedad bien utilizada simplifica enormemente la programación y sobre todo permite sacar el máximo provecho a los elementos que pone a disposición, tanto el entorno de desarrollo, como aquellos que sea capaz de crear el ingeniero de software. Dentro de la programación orientada a objetos existen dos tipos de herencia: simple y múltiple. Existe herencia simple cuando una clase solo se deriva de una clase base; y herencia múltiple cuando una clase se deriva de dos o más clases base. Polimorfismo En general se dice que el polimorfismo es la posibilidad de que una entidad tome muchas formas. En términos de programación orientada a objetos, y de forma práctica, el polimorfismo permite hacer referencia a objetos de diferentes clases por medio de una misma operación, la cual se ejecuta y aplica de acuerdo al objeto que la invoca. Dentro de la programación orientada a objetos, básicamente se trabaja relacionado con el concepto de herencia. Si una clase base implementa una serie de miembros (propiedades y métodos), que pueden ser heredados por otras clases, el polimorfismo es la propiedad que le permite al programador, que haga uso de las clases derivadas, modificar el comportamiento de tales miembros ya sea parcial o totalmente. En otras palabras, se dice que el polimorfismo le permite al programador, que herede clases a partir de una clase base, redefinir los miembros que le sean convenientes conversiones que se ajusten a las nuevas clases. Y … Modularidad La modularidad es la propiedad, de la programación orientada a objetos, que permite dividir una aplicación de software en componentes más pequeños, generalmente llamados módulos. Esta división debe realizarse de una manera coherente y cada uno de estos componentes debe ser lo más independiente posible tanto de la aplicación como de los demás componentes. Es el aspecto que nos obliga a dedicar más tiempo al diseño y ser muy cuidadosos en la forma como se debe asumir el desarrollo de una aplicación de software. Aunque existe una amplia documentación sobre el tema en libros, revistas, Internet o en las mismas cátedras universitarias, solo la experiencia será quién al final nos enseñe la forma como debemos subdividir una aplicación en diferentes componentes de software, de tal manera que podamos sacar el mayor provecho posible de los mismos. Una estrategia práctica que puede ser útil en la escogencia de una buena modularidad es no pensar que el proyecto en el cual se está trabajando actualmente es la única aplicación que se va a desarrollar, sino que existirán muchas otras en el futuro con características diferentes o semejantes, y determinar que partes de la actual me pueden ser útiles Prof. Rearte, Judith 8/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II en esas aplicaciones de software. Un buen programador, a medida que desarrolla programas, debe ir construyendo sus propias bibliotecas de componentes de software que le puedan ser útiles en otras aplicaciones o a otros programadores, sin necesidad de tener que recurrir a modificaciones de su programación. En la vida práctica, es el program programador quién debe tomar la mejor alternativa: deja las cosas como están, y dispone de un componente validador para programas tipo Windows, con un alto nivel de abstracción y encapsulamiento, o crea un componente más genérico que le sea útil en diversos tipos de aplicaciones. Solo la práctica y el objetivo que se busque en un proyecto de software serán quienes dicten las reglas que se deben seguir en lo que respecta a la forma como asumamos la modularidad. CLASES La clase no es más que una plantilla de software que sirve para construir cualquier cantidad de objetos. Por ejemplo, existe una clase llamada Form que sirve como molde para construir cualquier ventana que necesite una aplicación tipo Windows. Las ventanas que nosotros observamos en la pantalla de nuestro computador, son los objetos generados con esa plantilla. Pueden haber muchos objetos generados con esa plantilla, pero lo que los puede hacer diferentes a unos de otros, son los valores que se asignan a sus atributos atributos como: alto, ancho, color, título, etc. Desde la perspectiva del lenguaje de programación, una clase es un tipo tipo, que al igual que los tipos estándar, sirve para declarar variables cuya estructura es una fiel copia de ella. Estas variables reciben el nombre de objetos y son los elementos que manipula el programador para desarrollar su programa. En la evolución del desarrollo de software y los lenguajes de programación, es posible que en el futuro tan solo se hable de tipos, en vez de clases. Serán tantas tas las clases que cualquier programador podrá encontrar en las redes de comunicaciones, como Internet, que más que preocuparse por construir un molde deberá poner todo su potencial en manipular los objetos que de él se puedan obtener, y todo se verá con la la simpleza que hoy se mira a los tipos de datos como entero, cadena de texto, booleano o byte, entre otros. Pero, por ahora volvamos a nuestra realidad que nos exige a nosotros definir los tipos o clases que el entorno de desarrollo no haya definido, o que que siendo tantos, no sepamos que ya existen, y que los necesitemos para nuestros programas. En C# una clase se define mediante la palabra clave class y una sintaxis básica que encontramos para definirla, es la siguiente: class NombreClase { // Miembros } Por ejemplo, supongamos que deseamos un componente de software para procesos matemáticos que nos permitan manipular números complejos. La clase que nos permitirá procesar estos números la llamaremos Complejo, Complejo y se puede definir como, class Complejo { Prof. Rearte, Judith 9/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II //Miembros de la clase Complejo } Sin embargo, las clases deben cumplir unos niveles de seguridad que exigen el manejo del control de accesibilidad a ellas, sobre todo por parte de agentes externos al proyecto de software donde se hayan definido. Es por esto que la definición de cualquier clase debe ir antecedida de una palabra clave que determina la accesibilidad que admite dicha clase. La sintaxis C# para definir una clase es la siguiente: [public | private | protected | internal] class NombreClase { // Miembros } La sección entre corchetes, que indica las palabras clave de accesibilidad, public, private, protected, internal, que pueden utilizarse en la definición de una clase, es opcional e indica cual es el nivel de acceso que se va a permitir sobre la clase. Si no se especifica ningún nivel de accesibilidad, el compilador la define por defecto como internal, lo cual significa que solo se permite el acceso a las clases que hacen parte del mismo ensamblado. Mediante las palabras de accesibilidad se pueden especificar los siguientes cinco niveles de protección para una clase: Acceso Seguridad Public No existe ninguna restricción de acceso. protected Solo pueden tener acceso la clase contenedora o los tipos derivados de esta clase Internal Únicamente se permite el acceso al ensamblado actual. protected internal El acceso está limitado al ensamblado actual o los tipos derivados de la clase contenedora Private Solo se permite el acceso al tipo contenedor. Para nombrar una clase se sugiere utilizar una cadena de caracteres que inicia con una letra mayúscula y cuyo significado es familiar para el programador. Aquí es muy importante tener en cuanta cual es la funcionalidad básica de la clase, para darle un nombre que resulte significativo y fácil de recordar posteriormente. Podemos tener clases como: Complejo, Alumno, DocumentoImpresion, RedNeuronal, ConexionBaseDatos OBJETOS Cuando se diseña y programa una aplicación de software con el modelo de programación orientada a objetos, lo que se hace en la práctica es construir un conjunto de plantillas de objetos, o lo que se conoce como clases, las cuales permiten definir variables en memoria que se conocen con el nombre de objetos o instancias de clase. Desde esta perspectiva, el término clase gana mayor significado, ya que se puede definir como una plantilla que permite generar una clase de objetos. Para crear un objeto de una determinada clase, se procede básicamente en dos pasos: primero se declara una variable con el tipo que representa la clase y luego se le asigna memoria con el Prof. Rearte, Judith 10/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II operador new. Por ejemplo, tomando la clase Complejo definida anteriormente, la siguiente línea crea un objeto a partir de esta plantilla: Complejo z; Cuando el programa ejecuta esta línea, solo posee una dirección de memoria donde se inicia la estructura de la variable z. Para asignarle la memoria total conforme al tamaño de la estructura que describe la clase, es necesario aplicar el operador new, así: z = new Complejo(); A partir de aquí, el sistema conoce con exactitud la ubicación y tamaño ocupado en memoria por la variable z y estará en condiciones de colocar en el sitio que corresponda cada uno de los datos y demás elementos que conforman el objeto. En C#, tanto la declaración como la asignación de memoria para un objeto puede hacerse en una sola línea de código, como se muestra enseguida para nuestro ejemplo: Complejo z = new Complejo(); EJEMPLO: ENVIAR FLORES [De T. Budd, Introducción a la Programación Orientada a Objetos, cap. 1] Considérese el problema de enviar flores a una amiga que reside en una ciudad diferente. Por ejemplo, Juan quiere enviar flores a Inés. Juan no puede enviarlas directamente y para ello utiliza los servicios de su florista local, asociado a Interflora. Juan le indica al florista (que se llama Paco) la dirección de Inés, cuánto quiere gastar, el tipo de flores que enviar y un texto para poner en la tarjeta que acompaña al ramo. Paco contacta con una floristería en la ciudad de Inés, que se encarga de preparar el ramo de flores y buscar el repartidor que lo entregue. Si se piensa con detenimiento, puede haber además otras personas involucradas en esta transacción. Por ejemplo, el mayorista de flores, tal vez alguien que prepare el ramo, etc. Agentes y comunidades Lo primero que se puede ver es que los resultados se consiguen por la interacción de unos agentes, que llamamos objetos. Además, cualquier actividad no trivial requiere la interacción de una comunidad de objetos que trabajan juntos. Cada objeto tiene una parte que jugar, un servicio que proporcionar a los otros miembros de la comunidad. Elementos de la POO - Objetos Según el primer principio de Alan Kay: 1. Todo son objetos. Prof. Rearte, Judith 11/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II Las acciones en POO las realizan los objetos. Normalmente hay muchos objetos que colaboran en un escenario. Por ejemplo, D. Juan, el florista, el que prepara el ramo, etc. Cada objeto tiene una responsabilidad, y el resultado es el producto de la colaboración de todos los objetos en la solución del problema. Elementos de la POO – Mensajes El principio número 2: 2. Los objetos funcionan haciéndose peticiones de uno a otro mediante paso de mensajes. Las acciones en POO se producen como respuesta a las peticiones de acciones, que se llaman mensajes. Un objeto puede aceptar un mensaje y como respuesta realizará una acción y devolverá un valor. Para empezar el proceso de enviar flores, Juan le da un mensaje al florista, que a su vez envía un mensaje al florista en la localidad de la destinataria, que le da un mensaje al repartidor, y así sucesivamente. Ocultando información Obsérvese que como usuario de un servicio que proporciona un objeto lo único que se necesita saber es el nombre de los mensajes que aceptará el objeto. No hace falta tener ninguna idea sobre cómo se realizarán las acciones en respuesta a la petición. Una vez aceptado un mensaje, un objeto es responsable de llevarlo a cabo. Elementos de la POO – Receptores Los mensajes son diferentes de las llamadas a función tradicionales en dos aspectos importantes: • En un mensaje hay designado un receptor que acepta el mensaje. • La interpretación del mensaje puede ser diferente, dependiendo del receptor. Diferentes receptores, mismo mensaje, diferentes acciones var Paco : Florista Carmen : Hermana Sacamuelas : Dentista inicio Paco.enviaFloresA(miNovia); { funcionará} Carmen.enviaFloresA(miNovia); {también funcionará} Ken.enviaFloresA(miNovia); {probablemente no funcionará} El mismo mensaje ocasionará acciones distintas, dependiendo de a quién vaya dirigido. Prof. Rearte, Judith 12/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II Comportamiento e interpretación Aunque varios objetos diferentes puedan aceptar el mismo (comportamiento) que realizará el objeto podrán ser diferentes. mensaje, las acciones La determinación de qué comportamiento realizará el objeto se toma en tiempo de ejecución (vinculación tardía, o late binding). El hecho de que el mismo nombre pueda significar dos operaciones completamente diferentes es una forma de polimorfismo. Elementos de la POO – Diseño Recursivo 3. Cada objeto tiene su propia memoria, que consta de otros objetos. Cada objeto es como un computador en miniatura, un procesador especializado en realizar una tarea específica. Elementos de la POO – Clases 4. Cada objeto es un ejemplar (instancia) de una clase. Una clase agrupa objetos similares. 5. La clase es el repositorio del comportamiento asociado con un objeto. El comportamiento I que se espera de Paco está determinado por la idea general que yo pueda tener del comportamiento de los floristas. Se dice que Paco es una instancia de la clase Florista. El comportamiento está asociado con las clases, no con instancias individuales. Todos los objetos que son instancias de una clase utilizan el mismo método en respuesta a mensajes similares. Jerarquías de categorías Pero hay más cosas que puedo saber sobre Paco, además de que es un Florista. También es un Tendero, y un Humano, y un Mamífero, y muchas más cosas. En cada nivel de abstracción podemos registrar cierta información. Esa información será aplicable a todos los niveles inferiores, más especializados. Prof. Rearte, Judith 13/14 I.T.S.C. Técnico Superior en Desarrollo de Software Programación II Jerarquías de clases Objeto material cosa inanimada Ser vivo Animal Dentista Planta Reptil Mamífero Ser Humano Perro Tendero Artista Roca Agua Gato Elementos de la POO – Herencia 6. Las clases están organizadas en una estructura arbórea que se denomina jerarquía de herencia. La información (datos y comportamiento) que le asociamos a un nivel de abstracción en la jerarquía de clases es automáticamente aplicable a los niveles inferiores de la jerarquía. Elementos de la POO – Sobreescritura Las subclases pueden alterar o sobrescribir sobrescribir información heredada de las clases padre: Todos los mamíferos dan de mamar a los recién nacidos. La herencia combinada con la sobreescritura es una de las características más potentes de la POO. Computación como simulación La visión de la computación en POO es similar a crear un universo de objetos computacionales interactuando entre sí. En definitiva, la POO es similar a la manera en que la gente piensa cómo resolver problemas en la vida real: que sea otro agente quien hag haga el trabajo real Prof. Rearte, Judith 14/14