You are on page 1of 10

HERENCIA Dentro de la filosofa bsica de disear en trminos de responsabilidades y comportamiento, el siguiente paso programar de una manera orientada a objetos

implica adquirir conocimientos sobre cmo usar con efectividad clases organizadas bajo una estructura jerrquica basada en el concepto de herencia. Por herencia nos referimos a la propiedad de que los ejemplares de una clase hija (subclase) puedan tener acceso tanto a los datos como al comportamiento (mtodos) asociados con una clase paterna (superclase). La herencia es transitiva, por lo que una clase puede heredar caractersticas de superclases alejadas muchos niveles. Por ejemplo, si la clase Perro es una subclase de la clase Mamfero y sta a su vez es una subclase de la clase Animal, entonces el Perro heredar atributos tanto de la clase Mamfero como de la clase Animal. La herencia significa que el comportamiento y los datos asociados con las clases hijas son una extensin de las propiedades asociadas con las clases paternas. Una subclase rene todas las propiedades de la clase paterna y otras ms. Esta herencia de atributos se extiende tanto a los datos (variables de ejemplar y campos) como al comportamiento (mtodos) en los lenguajes orientados a objetos. DEFINICION El principio que dice que una subclase heredar los atributos (el conocimiento) de una superclase (categora ms general) que est ms arriba en el rbol jerrquico de las clases y objetos. BENEFICIOS DE LA HERENCIA Entre los beneficios del uso de la herencia en el diseo orientado a objetos estn: Reusabilidad del Software. Cuando el comportamiento (mtodos) se hereda de otra clase, no necesita ser reescrito el cdigo que proporciona ese comportamiento. Muchos programadores pasan gran parte de su tiempo reescribiendo cdigo que ya se ha escrito. Por ejemplo, para buscar un patrn en una celda o para insertar un nuevo elemento en una tabla, tales funciones pueden escribirse una sola vez y reutilizarse mediante tcnicas orientadas a objetos. Otros beneficios del cdigo reutilizable incluyen una mayor confiabilidad (cuanto ms se reutilice el cdigo, mayores sern las oportunidades de descubrir errores) y un menor costo de mantenimiento gracias a que el cdigo se comparte por todos los usuarios. Compartir Cdigo. El compartir cdigo puede tener lugar en diversos niveles cuando se usan tcnicas de orientadas a objetos. En un nivel, muchos usuarios o proyectos independientes pueden emplear las mismas clases. Otra forma de compartir ocurre cuando dos o ms clases diferentes,

desarrolladas por un solo programador como parte de un proyecto, hereda de una clase paterna nica. Por ejemplo, un Conjunto y un Arreglo pueden ser considerados como una forma de Coleccin; cuando esto sucede, significa que dos o ms tipos diferentes de objetos comparten el cdigo que heredan. Dicho cdigo se necesita escribir slo una vez y slo una vez contribuir al tamao del programa resultante. Consistencia de la Interfaz. Cuando mltiples clases heredan de la misma superclase asegura que el comportamiento que hereda ser el mismo en todos los casos. De esta forma es ms fcil garantizar que las interfaces para objetos similares sean similares y al usuario no se le presenta una coleccin confusa de objetos que son casi lo mismo pero que se comportan e interactan en forma diferente. Este beneficio supone que la herencia tienen lugar sin anulacin, es decir, que el programador cambie arbitrariamente el significado de cualquier mtodo. Componentes de Software. La herencia nos permitir construir componentes de software reutilizable. Ya existen comercialmente muchas bibliotecas y se espera que con el tiempo aparezcan muchos ms sistemas especializados. Modelado Rpido de Prototipos. Cuando un sistema de software puede construirse en su mayor parte con componentes reutilizables, el tiempo de desarrollo puede concentrarse en entender la parte del sistema que es nueva o no conocida. De esta forma, pueden generarse ms rpida y fcilmente los sistemas de software, llevando a un estilo de programacin conocido como modelo rpido de prototipos. En el cual se desarrolla un sistema prototipo, los usuarios experimentan con l, se produce un segundo sistema basado en la experiencia del primero, se efecta una exploracin adicional y as se repite varias veces. Este estilo de programacin es particularmente til en casos en los que los objetivos y los requisitos del sistema se entienden vagamente cuando se comienza el proyecto. Polimorfismo. El software producido de una forma convencional se escribe generalmente de manera ascendente, esto quiere decir, que se desarrollan las rutinas de bajo nivel y sobre stas se producen abstracciones de un nivel un poco ms alto, sobre estas se generan elementos an ms abstractos y as sucesivamente. Este proceso es como construir un muro, en el cual cada ladrillo descansa sobre los ladrillos subyacentes. Por lo regular, la transportabilidad decrece en la medida en que uno asciende en los niveles de abstraccin. Esto es, las rutinas de ms bajo nivel pueden usarse en diferentes proyectos y tal vez pueda reutilizarse incluso el siguiente nivel de abstraccin, pero las rutinas de ms alto nivel estn ligadas ntimamente a una aplicacin particular. El polimorfismo de los lenguajes de programacin permite al programador generar componentes reutilizables de alto nivel que pueden adaptarse para que se ajusten a diferentes aplicaciones mediante el cambio de sus partes de bajo nivel. Es como si las partes ms altas del muro pudieran llevarse y

colocarse en nuevos cimientos para crear un tipo de estructura totalmente diferente. Ocultamiento de Informacin. Cuando un programador reutiliza un componente de software slo necesita entender la naturaleza del componente y su interfaz. No es necesario que el programador tenga informacin detallada sobre aspectos como las tcnicas usadas para implantar el componente. As, se reduce la interconexin entre los sistemas de software.

COSTO DE LA HERENCIA Los beneficios de la herencia en la programacin orientada a objetos son grandes, pero tiene sus costos, los cuales se presentan a continuacin. Velocidad de Ejecucin. Las herramientas de software de propsito general rara vez pueden igualar la rapidez de los sistemas hechos cuidadosamente a mano. De esta forma, los mtodos heredados que deben prepararse para tratar con subclases arbitrarias, son con frecuencia ms lentos que el cdigo especializado. Tamao del Programa. El uso de cualquier biblioteca de software impone una sancin al tamao por el uso de sistemas construidos especialmente para un proyecto especfico. Aunque este gasto puede ser considerable en algunos casos, tambin es cierto que, en la medida en que decrecen los costos de memoria, el tamao de los programas se vuelve menos importante. Ahora es ms relevante contener los costos de desarrollo y producir con rapidez cdigo de alta calidad y sin errores, que limitar el tamao de los programas. Tiempo de Procesamiento Adicional del Paso de Mensajes. Se ha dicho que le paso de mensajes es una operacin ms costosa que la simple invocacin a un procedimiento. El tiempo de procesamiento de adicional del paso de mensajes ser mucho ms alto en lenguajes ligados dinmicamente como Smalltalk y ms abajo en lenguajes ligados estticamente como C++. El incremento en costo debe evaluarse junto con los muchos beneficios de la tcnica orientada a objetos. Algunos lenguajes como C++, ponen a disposicin del programador varias opciones que pueden reducir el tiempo de procesamiento adicional del paso de mensajes. Complejidad de los Programas. Aunque la programacin orientada a objetos se proclama con frecuencia como la solucin al problema de la complejidad de software, de hecho, a menudo el abuso de la herencia sustituye la forma de la complejidad por otra. Entender el flujo de control de un programa que usa herencia puede requerir diversas exploraciones mltiples hacia arriba y hacia abajo de la grfica de herencia.

EJEMPLO DE HERENCIA EN C++ La herencia es una las principales caractersticas de un lenguaje de programacin orientado a objetos. En C++, la herencia se lleva a cabo permitiendo a una clase incorporar otra clase dentro de su declaracin. Por ejemplo, una clase llamada vehiculo_ruedas, que define los vehculos con que van por carretera. Guarda el nmero de ruedas que tiene un vehculo y el nmero de pasajeros que puede transportar. class vehiculo_ruedas { int ruedas; int pasajeros; public: void establecer_ruedas(int numero); int obtener_ruedas(void); void establecer_pasajeros(int numero); int obtener_pasajeros(void); }; Se puede usar la definicin del vehculo de ruedas para definir objetos especficos, por ejemplo, declarar una clase camion como se muestra. class camion : public vehiculo_ruedas { int carga; public: void establecer_carga(int tamano); int obtener_carga(void); void mostrar(void); }; La sintaxis general para la herencia es: class nombre-nueva-clase : acceso clase-heredada { cuerpo de la nueva clase } Definir el acceso es opcional, pero si est presente debe ser public o pirvate. Como est en el ejemplo el acceso es public, lo que significa que todos los elementos public del antecesor son tambin public en la clase hereda , por lo tanto, los miembros de la clase camion tienen acceso a las funciones miembro de vehiculo_ruedas como si hubieran sido declaradas dentro de la clase camion. Sin embargo, las funciones miembro no tendrn acceso a la parte privada de vehiculo_ruedas.

En el siguiente programa se ilustra la herencia creando dos subclases de vehiculo_ruedas que son camion y automovil. #include <iostream.h> enum tipo {coche, camioneta, furgon}; class vehiculo_ruedas { int ruedas; int pasajeros; public: void establecer_ruedas(int numero); int obtener_ruedas(void); void establecer_pasajeros(int numero); int obtener_pasajeros(void); }; class camion : public vehiculo_ruedas { int carga; public: void establecer_carga(int tamano); int obtener_carga(void); void mostrar(void); }; class automovil : public vehiculo_ruedas { enum tipo tipo_coche; public: void establecer_tipo(enum tipo t); enum tipo obtener_tipo(void); void mostrar(void); }; void vehiculo_ruedas::establecer_ruedas(int numero) { ruedas=numero; } int vehiculo_ruedas::obtener_ruedas(void) { return ruedas; }

void vehiculo_ruedas::establecer_pasajeros(int numero){pasajeros=numero; } int vehiculo_ruedas::obtener_pasajeros(void) { return pasajeros; } }

void camion::establecer_carga(int numero) { carga =numero; int camion::obtener_carga(void) { return carga; }

void camion::mostrar(void) { cout << Ruedas: << obtener_ruedas( ) << \n; cout << Pasajeros: << obtener_pasajeros( ) << \n; cout << Capacidad de carga en pies cbicos: << obtener_pasajeros( ); << \n; }

void automovil::establecer_tipo(enum tipo t) { tipo_coche = t; } enum tipo_automovil::establecer_tipo(enum tipo t) { tipo_coche = t; } void automovil::mostrar(void) { cout << Ruedas: << obtener_ruedas( ) << \n; cout << Pasajeros: << obtener_pasajeros( ) << \n; cout << Tipo: ; switch (obtener_tipo( )) { case camioneta: cout << Camioneta \n; break; case coche: cout << Coche \n; break; case furgon: cout << Furgn \n; break; } } main(void) { camion camion1, camion2; automovil automovil1; // Crea dos objetos tipo camion y un objeto // automovil

camion1.establecer_ruedas(18); camion1.establecer_pasajeros(3); camion1.establecer_carga(3200); camion2.establecer_ruedas(6); camion2.establecer_pasajeros(2); camion2.establecer_carga(1200); camion1.mostrar( ); camion2.mostrar( ); automovil1.establecer_ruedas(4); automovil1.establecer_pasajeros(5); automovil1.establecer_carga(camioneta); automovil1.mostrar( ); } return 0;

La mayor ventaja de la herencia se encuentra en que se puede crear una clasificacin bsica en la que pueden incorporarse clases ms especficas. De esta forna, cada objeto puede representar su propia clasificacin de modo

preciso. En el ejemplo se observa, que las clases camion y automovil incluyen funciones miembro denominadas mostrar( ) que muestran la informacin del objeto. Este es otro aspecto del polimorfismo, como cada funcin mostrar( ) est vinculada a su propia clase, el compilador sabe fcilmente a cul llamar en cualquier circunstancia. DESCUBRIMIENTO DE LA HERENCIA Una vez que se ha realizado el diseo inicial, el reconocimiento de partes comunes puede facilitar el desarrollo posterior. Hay dos relaciones de importancia en la segunda etapa del diseo orientado a objetos; ests son conocidas como la relacin es-un y la relacin tiene-un (o es parte-de). La relacin es-un se da entre dos conceptos cuando el primero es un ejemplar especializado del segundo. Es decir, para todo propsito prctico el comportamiento y los datos asociados con la idea ms especfica forman un subconjunto del comportamiento y los datos asociados con la idea ms abstracta. (aunque en un momento dado se debe tener forma de manejar las excepciones). Por ejemplo, un Florista es-un Comerciante, puesto que los hechos generales de los comerciantes son aplicables a los floristas. Para probar la relacin es-un, consideremos la afirmacin de que X es un Y, en donde X y Y son conceptos que se estn examinando. Si la afirmacin es correcta, esto es, concuerda con nuestro conocimiento, entonces se concluye que X y Y guardan una relacin es-un. La relacin tiene-un se da cuando el segundo concepto es un componente del primero, pero los dos no son en sentido alguno la misma cosa, sin importar cun abstracta sea la generalidad. Por ejemplo, un Automvil tiene-un motor, un Automvil no es un Motor, ni un Motor es un Automvil. Sin embargo, un Automvil es-un Vehculo. (Ver ). La mayora de las veces la distincin es muy clara. Algunas veces la diferencia puede ser muy sutil o puede depender de las circunstancias. La relacin es-un define la jerarqua de clase-subclase, mientras que la relacin tiene-un describe datos que se deben mantener dentro de una clase. HEURISTICAS PARA CREAR SUBCLASES Los programadores novatos en orientacin a objetos se sienten inseguros en cuanto a como reconocer las clases en la descripcin de un problema, tambin dudan en cundo una clase debe convertirse en subclase de otra o cundo es ms apropiado otro mecanismo. La regla ms importante es que, para que una clase se relacione con otra por medio de la herencia , debe hacer una relacin de funcionalidad entre ambas. Como se describi la regla es-un para captar esta relacin. Al decir que una

subclase es-una superclase, se esta diciendo que la funcionalidad y los datos asociados con la clase hija (subclase) forman un superconjunto de la funcionalidad y los datos asociados con la clase padre (superclase). Sin embargo, dentro de este marco general hay lugar para muchas variaciones, dentro de las cuales estn las siguientes: Especializacin. El uso ms comn de la herencia y la subclasificacin es en la especializacin. La subclasificacin para la especializacin es el uso ms obvio y directo de la regla es-un. Si se consideran dos conceptos C1 y C2, y tiene sentido el enunciado C1 es un C2, entonces, probablemente ser cierto que decir que C1 es una subclasificacin de C2. Por ejemplo, un Perro es un Mamfero significa que tal vez tenga sentido que la clase Perro sea una subclase de Mamfero. Si el enunciado es C2 tiene un C2, entonces, probablemente sea una mejor decisin de diseo hacer que los objetos de la clase C2 sean atributos (campos o variables de ejemplar) de la clase C1. Otra pregunta til es determinar si se desea contar con subclases o ejemplares de su clase, para tener acceso a datos o comportamiento de una posible superclase. A veces, la regla no est claramente definida y de hecho puede ser un asunto de perspectiva. Por ejemplo, considere un sistema de software que permite al usuario editar el contenido de las ventanas de texto. Si se piensa en este sistema como un Editor de ventanas, tiene ms sentido decir que un editor de ventanas opera sobre una ventana y que el editor tiene-una ventana. Pero si se piensa en el sistema como una Venta editable, tiene ms sentido decir que una ventana editable es-un tipo de ventana.. Existen ventajas y desventajas para ambos puntos de vista y no se puede decir que uno sea ms correcto que el otro. Especificacin. Otro uso frecuente de la herencia es garantizar que las clases mantengan cierta interface comn; es decir, que implanten los mimos mtodos. La clase padre puede ser una combinacin de operaciones implantadas que se delegan a las clases hijas. A menudo no hay cambio de interface entre el supertipo y el subtipo, la hija implanta simplemente el comportamiento descrito, aunque no implantado en la clase padre. Se trata en realidad de un caso especial de subclasificacin por especializacin, excepto que las subclases no son refinamientos de un tipo existente, sino ms bien realizaciones de una especificacin abstracta incompleta. Tal clase es conocida a veces como una clase de especificacin. La subclasificacin por especificacin puede reconocerse cuando la superclase no implanta ningn comportamiento real, sino que nada ms describe el comportamiento que ser implanta en las subclases. Esta forma de subclasificacin es comn en lenguajes que hacen uso extensivo de funciones virtuales. Construccin. Muchas veces una clase puede heredar casi toda la funcionalidad de una superclase, tal vez con slo cambiar los nombres de los mtodos usados para relacionar la clase o al modificar los argumentos de cierta manera.

Generalizacin. Usar la herencia para crear subtipos para generalizacin es lo opuesto a la creacin de subtipos para la especializacin. Aqu, un subtipo extiende el comportamiento del supertipo para crear una especie de objeto. La creacin de subtipos por generalizacin se aplica a menudo cuando se est construyendo sobre la base de clases que no se desea o no puede modificar. Por ejemplo, considere un sistema de visualizacin de grficas en el cual se ha definido una clase Ventana para mostrarse en un simple fondo blanco y negro. Se podra crear un subtipo VentanaAColor que permitiera que el color del fondo fuera a color, aadiendo un campo adicional para guardar el color y anulando el cdigo de visualizacin de ventana heredado para que el fondo fuera dibujado en ese color. (Ver figura). Como regla, se debe evitar la creacin de subtipos por generalizacin y mejor se debe invertir la jerarqua del tipo y usar creacin de subtipos por especializacin (Ver figura), sin embargo, no siempre es posible hacerlo. Extensin. Mientras la subclasificacin por generalizacin modifica o expande la funcionalidad existente de un objeto, la subclasificacin por extensin agrega capacidades totalmente nuevas. La subclasificacin por extensin puede distinguirse de la subclasificacin por generalizacin en que la ltima debe anular al menos un mtodo del padre y la funcionalidad unida a ste, mientras que la extensin tan slo aade nuevos mtodos a los del padre y la funcionalidad queda menos fuertemente unida a los mtodos existentes de ste. Limitacin. Subclasificacin por limitacin es una forma especializada de la subclasificacin por especificacin, en la que el comportamiento de la subclase es ms reducido o est ms restringido que el comportamiento de la superclase. Como la creacin de subtipos por generalizacin, la subclasificacin por limitacin tiene lugar con ms frecuencia cuando un programador est construyendo sobre una base de clases existentes que no deben o pueden ser modificadas. La presencia de los mtodos que anulan los mtodos existentes y que producen mensajes de error si se invocan los mtodos es lo que caracteriza a la subclasificacin por limitacin. La subclasificacin por limitacin es una violacin explcita del enfoque es-un de la herencia. Por eso, esta tcnica debe evitarse siempre que sea posible. Variacin. La creacin de subtipos por variacin es til cuando dos o ms clases tiene implantaciones similares, pero no parece haber ninguna relacin jerrquica entre los conceptos representados por las clases. Por ejemplo, el cdigo necesario para controlar un ratn puede ser casi idntico al cdigo que se necesita para controlar una tarjeta grfica. Sin embargo, conceptualmente no hay razn particular por la que cualquier clase Raton deba ser una subclase de la clase Tarjeta o por la cual la clase Tarjeta deba ser una subclase de la clase Ratn. Se puede seleccionar arbitrariamente una de las dos clases como padre, haciendo que el cdigo comn sea

heredado por el otro y el cdigo especfico del dispositivo sea proporcionado como mtodos anulados. Sin embargo, con frecuencia una mejor alternativa es descomponer en factores el cdigo comn de una clase abstracta, digamos DispositivoApuntador, y hacer que ambas clases hereden de este ancestro comn (Ver Figura). Como con la creacin de subtipos por generalizacin, la anterior seleccin puede no estar disponible si se est construyendo sobre una base de clases existentes. Combinacin. Una situacin comn ocurre cuando una subclase representa una combinacin de caractersticas de dos o ms clases padres. Por ejemplo, un AyudanteDeProfesor es tanto un Profesor como un estudiante y lgicamente se debera comportar como ambos (Ver Figura). La capacidad de una clase para heredar de dos o ms clases padres se conoce como herencia mltiple y por desgracia no se proporciona en todos los lenguajes.

CUANDO CREAR SUBCLASES Generalmente un programador de la orientacin a objetos se encuentra con el siguiente problema. Una clase existente provee 80% de la funcionalidad necesaria para una nueva aplicacin. La funcionalidad restante la puede proporcionar con unos cuntos mtodos nuevos. Debe el programador cambiar simplemente la clase base para ofrecer a la estructura la nueva funcionalidad o crear una nueva clase y usar herencia para lograr acceso a la estructura existente?. No existen reglas rigurosas y rpidas que den una respuesta, slo hay directrices generales que se deben tomar en consideracin en casos individuales. Por ejemplo, si la clase existente se est usando mucho en otras aplicaciones y los cambios propuestos implican agregar campos de datos a los ejemplares de la clase, sancionando a los usuarios al tener que proporcionar caractersticas que no necesitan; sera mejor dejarla quieta. De igual manera, los cambios a los mtodos existentes dejan al programador expuesto al riesgo de que las modificaciones puedan introducir errores en otras aplicaciones. Pero si el cambio es transparente, entonces un solo cambio puede acarrear beneficios amplios. No siempre es una buena decisin derivar clases para hacer cambios menores a las clases existentes. En una situacin de grupo, con facilidad puede suceder que cada programador ample una clase de una forma diferente, teniendo como resultado docenas de clases derivadas de una nica clase base. Una superabundancia de clases complica en extremo la comprensin de un programa, en lugar de ofrecer la simplificacin que dara un rbol de herencia bien hecho. El grupo debe decidirse por unas pocas clases comunes que proporcionen la unin de la funcionalidad que desee cada programador.

You might also like