




























































































Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Encuentra los documentos específicos para los exámenes de tu universidad
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
Libro acerca de la programación orientada a objeto
Tipo: Apuntes
1 / 174
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!





























































































!"#$"%&%'()+,"(-.%/%+%+,01-.#2+3#"+4#0-".#+4#/"5$6-7+8'9-:-""5%;+<=:%"#+!"(-.#+4%�+8'%"%+>#2%+
?'9-7+2-+-'6-."%+0%1#+6%+@('-'(%+A"-%.(:-+A#&+4-'##'(&(-.#BC#A#&-"'(%=BA#&3%".("D$6%=+ EFG+H3#".-/F I%2%/%+-+6%+#0"%+-+JJJF=(0"-"(%%=:%"#F'#&K=(0"#3##F3/LF
“libropoo” — 2011/2/19 — 19:02 — page 2 — # ✐
En el sexto capítulo se define el concepto de estructura de datos y como ejemplo, se presenta una de las estructuras de datos más utilizadas: la estruc- tura árbol. Por su parte, en el capítulo siete, se presenta una metodología de identifi- cación y modelado de clases de objetos. Como último capítulo, en el capítulo ocho, se presentan otras características relevantes de C++ que se salen del ámbito de la programación orientada a objetos. Finalmente, en el apéndice se pueden encontrar una relación de los errores más comunes, así como una batería de ejercicios para que el lector practique y comprenda todos los conceptos expuestos en este libro.
- “libropoo” — 2011/2/19 — 19:02 — page 3 — # “libropoo” — 2011/2/19 — 19:02 — page 8 — # ✐
Dificultad en reutilización. Normalmente las subrutinas son demasiado dependientes del contexto de un programa como para poder aprovecharlas en un nuevo programa.
A la hora de afrontar la construcción de grandes aplicaciones, estos defectos pueden provocar que muchos proyectos sean inabordables. La Programación Orientada a Objetos surgió con el objetivo de erradicar los problemas expuestos.
1.1.2. Programación Orientada a Objetos: Características base La Programación Orientada a Objetos supone un cambio en la concepción del mundo de desarrollo de software, introduciendo un mayor nivel de abstrac- ción que permite mejorar las características del código final. De manera muy básica, las aportaciones de este paradigma se pueden resumir en:
Conceptos de clase y objeto, que proporcionan una abstracción del mundo centrada en los seres y no en los verbos.
Los datos aparecen encapsulados dentro del concepto de clase. El ac- ceso a los datos se produce de manera controlada e independiente de la representación final de los mismos. Como consecuencia, se facilita el man- tenimiento y la evolución de los sistemas, al desaparecer las dependencias entre distintas partes del sistema.
Mediante conceptos como la composición, herencia y polimorfismo se con- sigue simplificar el desarrollo de sistemas. La composición y la herencia nos permiten construir clases a partir de otras clases, aumentando en gran medida la reutilización.
La razón histórica del origen de estas aportaciones se explica en el siguiente apartado.
1.1.3. Programación Orientada a Objetos: Historia
Contrariamente a la creencia de mucha gente, la Programación Orientada a Objetos (POO a partir de ahora) no es un tema nuevo de discusión. Es cierto que en años recientes la POO ha tomado nueva fuerza y ha renacido como un paradigma. Sin embargo fue a finales de los años 60 cuando estas técnicas fueron concebidas. Para entender su origen hay que situarse en el contexto de la época, en el que el desarrollo y mantenimiento de proyectos software presentaban evidentes problemas de complejidad, coste y eficiencia. Uno de los grandes problemas que surgían consistía en la necesidad de adaptar el software a nuevos requisitos 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. La Orientación a Objetos brinda
“libropoo” — 2011/2/19 — 19:02 — page 9 — # ✐
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. Esto mismo pensaron en 1967, Krinsten Nygaard y Ole-Johan Dahl de la Universidad de Oslo, en el Centro Noruego de Computación, donde se dedica- ban a desarrollar sistemas informáticos que realizaban simulaciones de sistemas mecánicos, por ejemplo motores, para analizar su rendimiento. En este desa- rrollo se encontraban con dos dificultades, por un lado los programas eran muy complejos y, por otro, forzosamente tenían que ser modificados constantemen- te. Este segundo punto era especialmente problemático; ya que la razón de ser de los programas era el cambio y no sólo se requerían varias iteraciones para obtener un producto con el rendimiento deseado, sino que muchas veces se querían obtener diversas alternativas viables, cada una con sus ventajas e inconvenientes. La solución que idearon fue diseñar el programa paralelamente al objeto físico. Es decir, si el objeto físico tenía un número x de componentes, el pro- grama también tendría x módulos, uno por cada pieza. Dividiendo el programa de esta manera, había una total correspondencia entre el sistema físico y el sis- tema informático. Así, cada pieza física tenía su abstracción informática en un módulo. De la misma manera que los sistemas físicos se comunican enviándose señales, los módulos informáticos se comunicarían enviándose mensajes. Para llevar a la práctica estas ideas, crearon un lenguaje llamado Simula 67. Este enfoque resolvió los dos problemas planteados. Primero, ofrecía una forma natural de dividir un programa muy complejo y, en segundo lugar, el mantenimiento pasaba a ser controlable. El primer punto es obvio. Al dividir el programa en unidades informáticas paralelas a las físicas, la descomposición es automática. El segundo punto también se resuelve. En cada iteración de simulación, el analista querrá cambiar o bien piezas enteras o bien el compor- tamiento de alguna pieza. En ambos casos la localización de los cambios está perfectamente clara y su alcance se reduce a un componente, siempre y cuando la interfaz del mismo no cambie. Por ejemplo, si se estuviese simulando el motor de un coche, puede que se quisiera modificar el delco utilizado en la simulación anterior. Si el nuevo delco tuviera la misma interfaz (mismas entradas y salidas) o se cambiase sólo su comportamiento interno, nada del sistema (a parte del delco) estaría afectado por el cambio. Con Simula 67 se introducen por primera vez los conceptos de clases, obje- tos, herencia, procedimientos virtuales y referencias a objetos (conceptos muy similares a los lenguajes Orientados a Objetos de hoy en día). En esta época, Algol 60 era el lenguaje de moda y Cobol el más extendido en aplicaciones em- presariales, por lo que el nacimiento de Simula 67 y la Orientación a Objetos en Europa pasó inadvertido para gran parte de los programadores. En la actuali- dad Simula 67 se conoce simplemente como Simula, y contrariamente a lo que pudiera pensarse, todavía está en uso, mantenido por una pequeña comunidad de programadores, en su mayoría noruegos, y compiladores disponibles en la red.
“libropoo” — 2011/2/19 — 19:02 — page 11 — # ✐
la orientación a objetos. 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. En esta misma década se desarrollaron otros lenguajes Orien- tados a Objetos como Objective C, Object Pascal, Ada y otros. En el inicio de los años 90 se consolida la Orientación a Objetos como una de las mejores maneras para resolver problemas de programación. Aumenta la necesidad de generar prototipos más rápidamente (concepto RAD Rapid Apli- cation Development) sin esperar a que los requisitos iniciales estén totalmente precisos. En esta década se implanta con fuerza el concepto de reutilización, cuyo sentido es facilitar la adaptación de objetos ya creados a otros usos di- ferentes a los originales sin necesidad de modificar el código ya existente. A medio y largo plazo, el beneficio que puede obtenerse derivado de la reutiliza- ción es muy importante, y, quizás, es la razón principal por la que la industria informática se ha abocado a la orientación a objetos. Avanzando algunas cifras, se puede indicar que los niveles de reutilización de software pasan del 5-15 % en centros no orientados a objetos, a niveles por encima del 80 % en los orientados a objetos. Con la reutilización como pilar básico de su filosofía, un equipo de Sun Microsystems crea Java en 1995, con el objetivo de conquistar el mundo de la programación, teniendo gran éxito en aplicaciones en red. No en vano, captó mucha atención en los primeros meses de 1996 en base a ser considerado el medio para dominar Internet. Java es totalmente orientado a objetos. Está basado en C++, intentando evitar los principales problemas del mismo, como, por ejemplo, el acceso directo a memoria dinámica. Se fundamenta en el uso de bytecode (código de bajo nivel, portable e interpretable) y una máquina virtual accesible para todo el mundo que ejecuta esos bytecodes. Hoy en día es lo más cercano a lo que podría denominarse una máquina universal. El mundo de los lenguajes de programación orientados a objeto evolucio- na día a día y, continuamente, surgen nuevos lenguajes o nuevas versiones de lenguajes ya consolidados.
1.2. Procesos de Desarrollo Software
Evidentemente, el desarrollo de un sistema software debe seguir un proceso que especifique cómo debe ser, que permita controlar y seguir la evolución del sistema y que permita establecer aproximadamente su coste. El estudio de las características de estos procesos se lleva a cabo en el ámbito de la comunidad de Ingeniería del Software. Básicamente, podemos hablar de dos tipos procesos:
En cascada.
“libropoo” — 2011/2/19 — 19:02 — page 12 — # ✐
Iterativo (o incremental).
La diferencia fundamental entre ellos consiste en la forma de dividir un proyecto en partes más pequeñas. Los procesos en cascada dividen un proyecto según las actividades. La cons- trucción de un sistema software conlleva una serie de actividades que componen el ciclo de vida software: análisis de requisitos, diseño, implementación y prue- bas. De esta manera, los procesos en cascada dividirán un proyecto de 1 año de duración en, por ejemplo, una fase de análisis de 2 meses, una fase de diseño de 4 meses, una fase de implementación de 3 meses y una de prueba de 3 meses. Por su parte, los procesos iterativos dividen un proyecto en subconjuntos de funcionalidad. De esta forma, un proyecto de 1 año se dividiría en 3 iteraciones de 4 meses. En la primera iteración, se realizaría todo el ciclo de vida software para la cuarta parte de los requisitos. El resultado de la primera iteración sería un sistema software con la cuarta parte de la funcionalidad. En las siguientes iteraciones se continuaría evolucionando ese sistema, introduciendo el resto de funcionalidad. Dentro de la comunidad orientada a objetos, se suele optar por procesos iterativos que responden mejor al problema derivado de los cambios en los requisitos. En muchos campos de aplicación, los requisitos van cambiando a lo largo del desarrollo del sistema. Por lo tanto, los procesos en cascada se muestran menos efectivos; ya que, su flexibilidad ante estos cambios es mucho menor.
1.3. El lenguaje C++
Como ya vimos anteriormente, C++ nace a mediados de los ochenta de la mano de Bjarne Strouptup. En las primeras versiones era un simple preproce- sador que convertía las modificaciones añadidas, clases y tratamiento riguroso de tipos, a lenguaje C. De hecho, el nombre de C++ le viene en parte por ser considerado una evolución natural del lenguaje C. En la actualidad, C++ provee mecanismos suficientes para implementar, entre otras cosas, todos los conceptos de la POO de manera adecuada y, por supuesto, tiene su propio compilador nativo, sin que ello sea obstáculo para que, la mayoría de los com- piladores de C++ existentes, también compilen C puro. Quizás sea este soporte de múltiples paradigmas una de las claves de su éxito. Algunas de las características más importantes de C++ son:
Soporte de diferentes estilos de programación.
Espacios de nombres.
Encapsulación de información mediante el concepto de clases, apoyado también en los modificadores de acceso.
“libropoo” — 2011/2/19 — 19:02 — page 14 — # ✐
1.4. Resumen
Este capítulo pretende situar al lector en el contexto que dio origen al para- digma de programación orientada a objetos. El objetivo consiste en proporcio- nar una dimensión histórica a los conceptos introducidos por este paradigma, de manera que se pueda lograr una comprensión global de cada uno de ellos. En definitiva, este capítulo indaga sobre las causas que motivaron el origen de estos conceptos, de esta nueva forma de representación de la realidad. Por otra parte, se introduce el lenguaje C++ que va a servir de herramienta para llevar a la práctica todos los conceptos de programación que presenta este libro.
“libropoo” — 2011/2/19 — 19:02 — page 15 — # ✐
El mundo está lleno de objetos: el coche, la lavadora, la mesa, el teléfono, etc. El paradigma de programación orientada a objetos proporciona las abs- tracciones necesarias para poder desarrollar sistemas software de una forma más cercana a esta percepción del mundo real. Mediante la POO, a la hora de tratar un problema, podemos descomponer- lo en subgrupos de partes relacionadas. Estos subgrupos pueden traducirse en unidades autocontenidas llamadas objetos. Antes de la creación de un objeto, se debe definir en primer lugar su formato general, su plantilla, que recibe el nombre de clase. Por ejemplo, pensemos que estamos intentando construir una aplicación de dibujo de cuadrados. Nuestro programa va a ser capaz de pintar cuadrados con diferentes tamaños y colores: uno será rojo y de 3 centímetros de lado, otro verde y de 5 centímetros de lado, etc. Como podemos deducir, cada cuadrado está definido por dos características, lado y color, y contiene la operación dibuja. Desde el punto de vista de la POO, cada cuadrado se va a representar como un objeto de la clase Cuadrado que es la contiene las carac- terísticas y operaciones comunes de los objetos. En realidad, estamos creando un nuevo tipo, el tipo Cuadrado, y cada variable de este tipo especial recibe el nombre de objeto. Una clase, por lo tanto, puede definirse como un tipo de datos cuyas va- riables son objetos o instancias de una clase. Puede decirse que el concepto de clase es estático y el concepto de objeto es dinámico; ya que, sólo existe en tiempo de ejecución. Cada objeto de una clase comparte con el resto las operaciones, y a la vez posee sus propios valores para los atributos que posee: esto es, su estado. Las operaciones, también llamadas mensajes, se usarán tanto para cambiar el estado de un objeto como para comunicar objetos entre sí mediante el paso de mensajes.
“libropoo” — 2011/2/19 — 19:02 — page 17 — # ✐
void Cuadrado::dibuja( ){ //Algoritmo para dibujar un cuadrado }
Cuando se definen varios objetos de una misma clase, todos ellos comparten las funciones miembro definidas en la clase. Los objetos se diferencian por los valores que toman sus atributos. A este conjunto de atributos que distinguen a unos objetos de otros se les llama estado del objeto. Por ejemplo, todos los cuadrado comparten la misma definición de la función dibuja, pero poseen diferentes valores de sus atributos miembro lado y color.
2.1.2. El operador this La palabra clave this puede utilizarse en cualquier método de la clase para referirse al objeto actual. Cada vez que se llama a una función miembro, au- tomáticamente se pasa un puntero al objeto que la llama. Se puede acceder a este puntero utilizando this. Veamos el uso del operador this en el ejemplo anterior.
class Cuadrado { int lado; Color color; public: void dibuja( ); void modifica(int lado, Color color){ this->lado = lado; this->color = color; } };
Hemos introducido una nueva función miembro a la clase Cuadrado: la función modifica. En el cuerpo de esta función estamos usando el operador this para distinguir, en este caso, los atributos de los parámetros de la función modifica; ya que tienen el mismo nombre. Este ejemplo sencillo sólo quiere poner de manifiesto la posibilidad de acceder al objeto actual a través del puntero this. En el caso de no utilizarse en este ejemplo el puntero this, la modificación no se habría producido en los atributos lado y color.
2.2. Encapsulación
Una de los pilares básicos de la POO es la encapsulación de los datos. Según los principios de este paradigma de programación, el acceso a los datos de una clase debe realizarse de forma controlada, protegiéndolos de accesos no deseados. Cuando se desarrolla una aplicación, a veces es necesario ocultar los
“libropoo” — 2011/2/19 — 19:02 — page 18 — # ✐
tipos de datos usados para que el usuario permanezca independiente de los detalles de los mismos. De esta manera, el usuario no es sensible a los cambios que se puedan producir en los tipos de datos elegidos dentro de una clase. La encapsulación en los lenguajes orientados a objeto suele lograrse al de- clarar algunos datos como privados. El acceso a estos datos sería siempre con- trolado; ya que, se haría siempre a través de funciones miembro que realizarían las modificaciones oportunas de una forma transparente al usuario. La encapsulación es el mecanismo que enlaza el código y los datos, a la vez que los asegura frente a accesos no deseados. La principal razón del uso de la encapsulación es evitar el acceso directo a atributos de una clase desde fuera de la propia clase. Se busca, principalmente, que el acceso a estos atributos se realice siempre mediante funciones miembro de la propia clase. El acceso a ciertos elementos de datos se puede controlar de forma estricta considerándolos privados. Una vez presentado el concepto encapsulación, se puede definir de nuevo un objeto como una entidad lógica que encapsula los datos y el código que manipula dichos datos. Dentro de un objeto, parte del código y/o los datos puede ser privada al objeto y, por tanto, inaccesible desde fuera del mismo. Se podrá asegurar un acceso correcto al objeto utilizando las funciones miembro del objeto para acceder a los datos privados. El acceso a los datos de una clase se establece por lo tanto a través de los métodos que implementa la propia clase y que pone a disposición del usuario. Este mecanismo recibe el nombre de paso de mensajes o interfaz y es la forma de comunicación que se establece entre objetos.
2.2.1. Encapsulación en C++. Modificadores de acceso
Una clase puede contener tanto partes privadas como partes públicas. Por defecto, todos los elementos de la clase son privados, lo que significa que no son accesibles desde ninguna función que no sea miembro de la clase. El mecanismo aportado por C++ para conseguir la encapsulación es la utilización de los modificadores de acceso private y public. Los miembros privados ocultan las estructuras de datos y los procedimientos internos de un objeto. Si se incluye el modificador de acceso private en la lista de atributos y funciones miembro, todos los miembros que aparezcan a continuación serán miembros privados. Los atributos serán atributos miembro privados y las fun- ciones serán funciones miembro privadas. Por su parte, para hacer públicas ciertas partes de una clase, se deben decla- rar a continuación del modificador de acceso public. Aunque el lenguaje C++ permite tener atributos public, debe restringirse su utilización. En su lugar, por norma general, para lograr la encapsulación de los datos, es aconsejable crear todos los datos privados y proporcionar acceso a los mismos mediante funciones públicas. Introduciendo los modificadores de acceso, el formato de declaración de una clase quedaría así: