ClubEnsayos.com - Ensayos de Calidad, Tareas y Monografias
Buscar

El concepto básico de la herencia múltiple (HM)

xavix99Trabajo1 de Junio de 2012

3.676 Palabras (15 Páginas)588 Visitas

Página 1 de 15

INTRODUCCIÓN

El concepto básico de la herencia múltiple (HM) suena bastante simple: puede crear un nuevo tipo heredando de más una una clase base. La sintaxis es exactamente la que espera, y en la medida en que los diagramas de herencia sean simples, la HM puede ser simple también.

Herencia múltiple hace referencia a una característica de los lenguajes de programación orientada a objetos en la que una clase puede heredar comportamientos y características de más de una superclase. Esto contrasta con la herencia simple, donde una clase sólo puede heredar de una superclase.

Lenguajes que soportan herencia múltiple en su mayor parte son: C++, Centura SQL Windows, CLOS, Eiffel, Object REXX, Perl y Python.

La herencia múltiple permite a una clase tomar funcionalidades de otras clases, como permitir a una clase llamada MusicoEstudiante heredar de una clase llamada Persona, una clase llamada Músico, y una clase llamada Trabajador. Esto puede ser abreviado como MusicoEstudiante : Persona, Músico, Trabajador.

Ambigüedades

En la herencia múltiple aparecen ambigüedades, como en el ejemplo de encima: si la clase Músico heredaba de Persona y Trabajador, y la clase Trabajador heredaba de Persona. Existirían las siguientes reglas::

MusicoEstudiante : Persona, Músico, Trabajador

Músico : Persona, Trabajador

Trabajador: Persona

Si un compilador está mirando la clase MusicoEstudiante necesita saber si debe juntar las características iguales o si deben estar separadas. Por ejemplo, tendría sentido unir las características "Edad" de Persona para MusicoEstudiante. La edad de una persona no cambia si le consideras una Persona, un Trabajador o un Músico. Sin embargo, tendría sentido separar la característica "Nombre" de Persona y Músico si los músicos usan un nombre artístico diferente de su nombre real. Las opciones de juntar y separar son válidas según el contexto, y sólo el programador sabe qué opción es correcta para la clase que está diseñando.

Cada lenguaje de programación trata estos problemas de herencia repetida de diferente forma:

C++ requiere que el programador establezca de qué clase padre vendrá la característica a usar. Por ejemplo con "Trabajador::Persona.Edad". C++ no soporta herencia repetida explícita porque no habría forma de indicar qué superclase usar.

CLOS permite al programador control total del método de combinación, y si no es suficiente, el protocolo de metaobjetos ofrece al programador formas de modificar la herencia, envío de métodos, instanciación de clases, y otros mecanismos internos sin afectar a la estabilidad del sistema.

Eiffel permite al programador explicitar si junta o separa características que son heredadas de superclases. Eiffel juntará características automáticamente si tienen el mismo nombre e implementación. El programador tiene la opción de renombrar las características para separarlas. Eiffel también permite explicitar herencia repetida como A: B, B.

Logtalk soporta tanto interfaces como multi-herencia de implementación, permitiendo declarar alias de métodos que ofrecen renombrar y acceder a métodos que quedarían ocultados por el mecanismo de resolución de conflictos convencional.

Perl usa la lista de clases para heredar de una lista ordenada. El compilador usa el primer método que encuentra mediante búsqueda en profundidad por la lista de superclases.

Java, Nemerle, Delphi, C# y Objective-C no permiten herencia múltiple; esto hace que no haya ambigüedad. Sin embargo, permiten a las clases implementar múltiples interfaces.

Debate

Hay debate sobre si la herencia múltiple puede ser implementada de forma simple y sin ambigüedad. Con frecuencia es criticada por su aumentada complejidad y su ambigüedad, así como los problemas de versiones y mantenimiento que puede causar (a menudo resumido como el problema del diamante).1

Los detractores también señalan que hay problemas de implementación de la herencia múltiple como no ser capaces de explicitar herencia de múltiple clases y el orden de las semánticas de clase que cambian con la herencia. Hay lenguajes que solucionan todos los problemas técnicos de la herencia múltiple, pero el debate principal sigue sobre si implementar y usar herencia múltiple es más fácil que usar herencia simple y patrones de diseño de software.

Antes de C++, el lenguaje orientado a objetos más popular era Smaltalk. Smaltalk fue creado desde cero como un lenguaje orientado a objetos. A menudo se dice que es puro, mientras que a C++ se le llama lenguaje híbrido porque soporta múltiples paradigmas de programación, no sólo el paradigma orientado a objeto. Uno de las decisiones de diseño de Smalltalk fue que todas las clases tendrían solo herencia simple, empezando en una clase base (llamada Object - ese es el modelo para la jerarquía basada en objetos) [17] En Smalltalk no puede crear una nueva clase sin derivar de un clase existente, que es la razón por la que lleva cierto tiempo ser productivo con Smalltalk: debe aprender la librería de clases antes de empezar a hacer clases nuevas. La jerarquía de clases de Smalltalk es por tanto un único árbol monolítico.

Las clases de Smalltalk normalmente tienen ciertas cosas en común, y siempre tienen algunas cosas en común (las características y el comportamiento de Object), de modo que no suelen aparecer situaciones en las que se necesite heredad de más de una clase base. Sin embargo, con C++ puede crear tantos árboles de herencia distintos como quiera. Por completitud lógica el lenguaje debe ser capaz de combinar más de una clase a la vez - por eso la necesidad de herencia múltiple.

No fue obvio, sin embargo, que los programadores requiriesen herencia múltiple, y había (y sigue habiendo) mucha discrepancia sobre si es algo esencial en C++. La HM fue añadida en cfrontrelease 2.0 de AT&T en 1989 y fue el primer cambio significativo en el lenguaje desde la versión 1.0.[18] Desde entonces, se han añadido muchas características al Estándar C++ (las plantillas son dignas de mención) que cambian la manera de pensar al programar y le dan a la HM un papel mucho menos importante. Puede pensar en la HM como una prestación menor del lenguaje que raramente está involucrada en las decisiones de diseño diarias.

Uno de los argumentos más convincentes para la HM involucra a los contenedores. Suponga que quiere crear un contenedor que todo el mundo pueda usar fácilmente. Una propuesta es usar void*como tipo para el contenido. La propuesta de Smalltalk, sin embargo, es hacer un contenedor que aloja Object, dado que Object es el tipo base de la jerarquía de Smalltalk. Como todo en Smalltalk está derivado de Object, un contenedor que aloja Objects puede contener cualquier cosa.

Ahora considere la situación en C++. Suponga que el fabricante A crea una jerarquía basada-en-objetos que incluye un conjunto de contenedores incluye uno que desea usar llamado Holder. Después, se da cuenta de que la jerarquía de clases del fabricante B contiene alguna clase que también es importante para usted, una clase BitImage, por ejemplo, que contiene imágenes. La única forma de hacer que un Holder de BitImage es derivar de una nueva clase que derive también deObject, y así poder almacenarlos en el Holder, y BitImage.

HERENCIA MÚLTIPLE

Dentro de los lenguajes O.O. (orientados a objetos) existen algunos que soportan herencia múltiple, como C++ (Stroustrup, 2000) y Eiffel (Meyer, 2001); en cambio otros no, como en el caso de Smalltalk y Java. Si bien, la mayoría de las situaciones pueden resolverse sin recurrir a herencia múltiple, en algunos casos es conveniente contar con esta característica, a fin de lograr una mejor implementación de la aplicación.

Desde el punto de vista del diseño de un lenguaje, soportar herencia múltiple complica la tarea de implementación, ya que hay que prever cómo resolver situaciones como la que se muestra en la Figura 1, mediante el diagrama UML de relaciones de herencia múltiple entre las clases A, B y C (Fowler y Scott 2000). Cuando un objeto de clase C tiene que acceder al atributo p, el lenguaje debe tener algún medio de discriminar a cuál atributo p se quiere referir, si al de la clase A o la B.

Figura 1: Herencia múltiple

12

Proyecto Leonardo Año 4 – Volumen 3 – Número 1 – Octubre de 2008 ISSN 1668-7523

Una situación más complicada es la que se muestra en la Figura 2, que presenta un caso de herencia múltiple con un ancestro común. El atributo p se hereda a través de dos ramas diferentes, entonces un objeto D podría tener dos copias del mismo atributo, una la que hereda por la rama de B y otra por la de C. Lenguajes como C++ y Eiffel, tienen diferentes abordajes para resolver situaciones como estas.

Figura 2: Herencia múltiple con ancestro común

Los problemas antes mencionados, son una consecuencia del modo de construir un objeto de una clase que hereda de otra. Una relación de herencia, como por ejemplo entre las clases C y D, implica que un objeto de la clase D es una forma particular de C. Este tipo de vínculos entre clases, se describen con expresiones como “extiende” o “es un”, que dan la idea de que un objeto D es una forma de objeto C. Así, un objeto D va a tener una parte que va a ser C, pero también una parte que será B, lo cual plantea algunos problemas de ambigüedad que se deben resolver (Stroustrup 2000).

Los problemas comentados pueden aumentar, cuando se fuerza el concepto de herencia (Seidewitz,

...

Descargar como (para miembros actualizados) txt (24 Kb)
Leer 14 páginas más »
Disponible sólo en Clubensayos.com