Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO Pensar en C++ (Volumen 1) - Grupo ARCO
✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 6 — #44 ✐ Capítulo 1. Introducción a los Objetos ría cambiar la implementación interna de la clase sin preocuparse de cómo afectará a los programadores clientes. Por ejemplo, podría implementar una clase particular de una manera sencilla para un desarrollo fácil, y más tarde descubrir que necesita reescribirla para hacerla más rápida. Si la interfaz y la implementación están claramente separadas y protegidas, puede lograrlo fácilmente y sólo requiere que el usuario vuelva a enlazar la aplicación. C++ utiliza tres palabras reservadas explícitas para poner límites en una clase: public, private, y protected. Su uso y significado son bastante sencillos. Estos especificadores de acceso determinan quién puede usar las definiciones que siguen. public significa que las definiciones posteriores están disponibles para cualquiera. La palabra reservada private, por otro lado, significa que nadie puede acceder a estas definiciones excepto el creador del tipo, es decir, los métodos internos de la clase. p- rivate es una pared entre el creador de la clase y el programador cliente. Si alguien intenta acceder a un miembro privado, obtendrá un error al compilar. protected actúa como private, con la excepción de que las clases derivadas tienen acceso a miembros protegidos, pero no a los privados. La herencia se explicará en breve. 1.4. Reutilizar la implementación Una vez que una clase se ha creado y probado, debería constituir (idealmente) una unidad útil de código. Sin embargo, esta reutilización no es tan fácil de conseguir como muchos esperarían; producir un buen diseño requiere experiencia y conocimientos. Pero una vez que lo tiene, pide ser reutilizado. El código reutilizado es una de las mejores ventajas de los lenguajes para programación orientada a objetos. La forma más fácil de reutilizar una clase es precisamente utilizar un objeto de esa clase directamente, pero también puede colocar un objeto de esta clase dentro de una clase nueva. Podemos llamarlo «crear un objeto miembro». Su nueva clase puede estar compuesta de varios objetos de cualquier tipo, en cualquier combinación que necesite para conseguir la funcionalidad deseada en su nueva clase. Como está componiendo una nueva clase a partir de clases existentes, este concepto se llama composición (o de forma más general, agregación). A menudo nos referimos a la composición como una relación «tiene-un», como en «un coche tiene-un motor». Coche Motor Figura 1.2: Un coche tiene un motor (El diagrama UML anterior indica composición con el rombo relleno, lo cual implica que hay un coche. Típicamente usaré una forma más simple: sólo una línea, sin el rombo, para indicar una asociación. 5 ) La composición es un mecanismo muy flexible. Los objetos miembro de su nueva clase normalmente son privados, haciéndolos inaccesibles para los programadores clientes que están usando la clase. Eso permite cambiar esos miembros sin perturbar al código cliente existente. También puede cambiar los miembros del objeto en tiem- 5 Normalmente esto es suficiente para la mayoría de los diagramas y no necesita especificar si está usando agregación o composición. 6 ✐ ✐ ✐ ✐
✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 7 — #45 ✐ 1.5. Herencia: reutilización de interfaces po de ejecución, para cambiar dinámicamente el comportamiento de su programa. La herencia, descrita más adelante, no tiene esta flexibilidad dado que el compilador debe imponer restricciones durante la compilación en clases creadas con herencia. Como la herencia es tan importante en la programación orientada a objetos, se suele enfatizar mucho su uso, y puede que el programador novel tenga la idea de que la herencia se debe usar en todas partes. Eso puede dar como resultado diseños torpes y demasiado complicados. En lugar de eso, debería considerar primero la composición cuando tenga que crear nuevas clases, ya que es más simple y flexible. Si acepta este enfoque, sus diseños serán más limpios. Una vez que tenga experiencia, los casos en los que necesite la herencia resultarán evidentes. 1.5. Herencia: reutilización de interfaces En sí misma, la idea de objeto es una herramienta útil. Permite empaquetar datos y funcionalidad junto al propio concepto, además puede representar una idea apropiada del espacio del problema en vez de estar forzado a usar el vocabulario de la máquina subyacente. Esos conceptos se expresan como unidades fundamentales en el lenguaje de programación mediante la palabra reservada class. Sin embargo, es una pena tomarse tantas molestias en crear una clase y verse obligado a crear una más para un nuevo tipo que tiene una funcionalidad similar. Es más sencillo si se puede usar la clase existente, clonarla, y hacerle añadidos y modificaciones a ese clon. Esto es justamente lo que hace la herencia, con la excepción de que si cambia la clase original (llamada clase base, super o padre), el «clon» modificado (llamado clase derivada, heredada, sub o hija) también refleja esos cambios. Base Figura 1.3: subclases (En el diagrama UML anterior, la flecha apunta desde la clase derivada hacia la clase base. Como puede ver, puede haber más de una clase derivada.) Un tipo hace algo más que describir las restricciones de un conjunto de objetos; también tiene una relación con otros tipos. Dos tipos pueden tener características y comportamientos en común, pero un tipo puede contener más características que otro y también puede manipular más mensajes (o hacerlo de forma diferente). La herencia lo expresa de forma similar entre tipos usando el concepto de tipos base y tipos derivados. Un tipo base contiene todas las características y comportamientos compartidos entre los tipos derivados de él. Cree un tipo base para representar lo esencial de sus ideas sobre algunos objetos en su sistema. A partir del tipo base, derive otros tipos para expresar caminos diferentes que puede realizar esa parte común. 7 ✐ ✐ ✐ ✐
- Page 1 and 2: ✐ ✐ ✐ “Volumen1” — 2012
- Page 3 and 4: ✐ ✐ ✐ “Volumen1” — 2012
- Page 5 and 6: ✐ ✐ ✐ “Volumen1” — 2012
- Page 7 and 8: ✐ ✐ ✐ “Volumen1” — 2012
- Page 9 and 10: ✐ ✐ ✐ “Volumen1” — 2012
- Page 11 and 12: ✐ ✐ ✐ “Volumen1” — 2012
- Page 13 and 14: ✐ ✐ ✐ “Volumen1” — 2012
- Page 15 and 16: ✐ ✐ ✐ “Volumen1” — 2012
- Page 17 and 18: ✐ ✐ ✐ “Volumen1” — 2012
- Page 19 and 20: ✐ ✐ ✐ “Volumen1” — 2012
- Page 21 and 22: ✐ ✐ ✐ “Volumen1” — 2012
- Page 23 and 24: ✐ ✐ ✐ “Volumen1” — 2012
- Page 25 and 26: ✐ ✐ ✐ “Volumen1” — 2012
- Page 27 and 28: ✐ ✐ ✐ “Volumen1” — 2012
- Page 29 and 30: ✐ ✐ ✐ “Volumen1” — 2012
- Page 31 and 32: ✐ ✐ ✐ “Volumen1” — 2012
- Page 33 and 34: ✐ ✐ ✐ “Volumen1” — 2012
- Page 35 and 36: ✐ ✐ ✐ “Volumen1” — 2012
- Page 37 and 38: ✐ ✐ ✐ “Volumen1” — 2012
- Page 39 and 40: ✐ ✐ ✐ “Volumen1” — 2012
- Page 41 and 42: ✐ ✐ ✐ “Volumen1” — 2012
- Page 43: ✐ ✐ ✐ “Volumen1” — 2012
- Page 47 and 48: ✐ ✐ ✐ “Volumen1” — 2012
- Page 49 and 50: ✐ ✐ ✐ “Volumen1” — 2012
- Page 51 and 52: ✐ ✐ ✐ “Volumen1” — 2012
- Page 53 and 54: ✐ ✐ ✐ “Volumen1” — 2012
- Page 55 and 56: ✐ ✐ ✐ “Volumen1” — 2012
- Page 57 and 58: ✐ ✐ ✐ “Volumen1” — 2012
- Page 59 and 60: ✐ ✐ ✐ “Volumen1” — 2012
- Page 61 and 62: ✐ ✐ ✐ “Volumen1” — 2012
- Page 63 and 64: ✐ ✐ ✐ “Volumen1” — 2012
- Page 65 and 66: ✐ ✐ ✐ “Volumen1” — 2012
- Page 67 and 68: ✐ ✐ ✐ “Volumen1” — 2012
- Page 69 and 70: ✐ ✐ ✐ “Volumen1” — 2012
- Page 71 and 72: ✐ ✐ ✐ “Volumen1” — 2012
- Page 73 and 74: ✐ ✐ ✐ “Volumen1” — 2012
- Page 75 and 76: ✐ ✐ ✐ “Volumen1” — 2012
- Page 77 and 78: ✐ ✐ ✐ “Volumen1” — 2012
- Page 79 and 80: ✐ ✐ ✐ “Volumen1” — 2012
- Page 81 and 82: ✐ ✐ ✐ “Volumen1” — 2012
- Page 83 and 84: ✐ ✐ ✐ “Volumen1” — 2012
- Page 85 and 86: ✐ ✐ ✐ “Volumen1” — 2012
- Page 87 and 88: ✐ ✐ ✐ “Volumen1” — 2012
- Page 89 and 90: ✐ ✐ ✐ “Volumen1” — 2012
- Page 91 and 92: ✐ ✐ ✐ “Volumen1” — 2012
- Page 93 and 94: ✐ ✐ ✐ “Volumen1” — 2012
✐<br />
✐<br />
✐<br />
“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 7 — #45<br />
✐<br />
1.5. Her<strong>en</strong>cia: reutilización de interfaces<br />
po de ejecución, para cambiar dinámicam<strong>en</strong>te el comportami<strong>en</strong>to de su programa.<br />
La her<strong>en</strong>cia, descrita más adelante, no ti<strong>en</strong>e esta flexibilidad dado que el compilador<br />
debe imponer restricciones durante la compilación <strong>en</strong> clases creadas con her<strong>en</strong>cia.<br />
Como la her<strong>en</strong>cia es tan importante <strong>en</strong> la programación ori<strong>en</strong>tada a objetos, se<br />
suele <strong>en</strong>fatizar mucho su uso, y puede que el programador novel t<strong>en</strong>ga la idea de<br />
que la her<strong>en</strong>cia se debe usar <strong>en</strong> todas partes. Eso puede dar como resultado diseños<br />
torpes y demasiado complicados. En lugar de eso, debería considerar primero la<br />
composición cuando t<strong>en</strong>ga que crear nuevas clases, ya que es más simple y flexible.<br />
Si acepta este <strong>en</strong>foque, sus diseños serán más limpios. Una vez que t<strong>en</strong>ga experi<strong>en</strong>cia,<br />
los casos <strong>en</strong> los que necesite la her<strong>en</strong>cia resultarán evid<strong>en</strong>tes.<br />
1.5. Her<strong>en</strong>cia: reutilización de interfaces<br />
En sí misma, la idea de objeto es una herrami<strong>en</strong>ta útil. Permite empaquetar datos<br />
y funcionalidad junto al propio concepto, además puede repres<strong>en</strong>tar una idea apropiada<br />
del espacio del problema <strong>en</strong> vez de estar forzado a usar el vocabulario de la<br />
máquina subyac<strong>en</strong>te. Esos conceptos se expresan como unidades fundam<strong>en</strong>tales <strong>en</strong><br />
el l<strong>en</strong>guaje de programación mediante la palabra reservada class.<br />
Sin embargo, es una p<strong>en</strong>a tomarse tantas molestias <strong>en</strong> crear una clase y verse<br />
obligado a crear una más para un nuevo tipo que ti<strong>en</strong>e una funcionalidad similar. Es<br />
más s<strong>en</strong>cillo si se puede usar la clase exist<strong>en</strong>te, clonarla, y hacerle añadidos y modificaciones<br />
a ese clon. Esto es justam<strong>en</strong>te lo que hace la her<strong>en</strong>cia, con la excepción de<br />
que si cambia la clase original (llamada clase base, super o padre), el «clon» modificado<br />
(llamado clase derivada, heredada, sub o hija) también refleja esos cambios.<br />
Base<br />
Figura 1.3: subclases<br />
(En el diagrama UML anterior, la flecha apunta desde la clase derivada hacia la<br />
clase base. Como puede ver, puede haber más de una clase derivada.)<br />
Un tipo hace algo más que describir las restricciones de un conjunto de objetos;<br />
también ti<strong>en</strong>e una relación con otros tipos. Dos tipos pued<strong>en</strong> t<strong>en</strong>er características y<br />
comportami<strong>en</strong>tos <strong>en</strong> común, pero un tipo puede cont<strong>en</strong>er más características que<br />
otro y también puede manipular más m<strong>en</strong>sajes (o hacerlo de forma difer<strong>en</strong>te). La<br />
her<strong>en</strong>cia lo expresa de forma similar <strong>en</strong>tre tipos usando el concepto de tipos base<br />
y tipos derivados. Un tipo base conti<strong>en</strong>e todas las características y comportami<strong>en</strong>tos<br />
compartidos <strong>en</strong>tre los tipos derivados de él. Cree un tipo base para repres<strong>en</strong>tar<br />
lo es<strong>en</strong>cial de sus ideas sobre algunos objetos <strong>en</strong> su sistema. A partir del tipo base,<br />
derive otros tipos para expresar caminos difer<strong>en</strong>tes que puede realizar esa parte<br />
común.<br />
7<br />
✐<br />
✐<br />
✐<br />
✐