stringtranslate.com

herencia múltiple

La herencia múltiple es una característica de algunos lenguajes de programación de computadoras orientados a objetos en los que un objeto o clase puede heredar características de más de un objeto o clase principal . Es distinta de la herencia única, donde un objeto o clase sólo puede heredar de un objeto o clase en particular.

La herencia múltiple ha sido un tema controvertido durante muchos años, [1] [2] y sus oponentes señalan su mayor complejidad y ambigüedad en situaciones como el "problema del diamante", donde puede ser ambiguo en cuanto a qué clase de padre es una característica particular. heredado de si más de una clase principal implementa dicha característica. Esto se puede abordar de varias maneras, incluido el uso de herencia virtual . [3] También se han propuesto métodos alternativos de composición de objetos que no se basan en la herencia, como mixins y rasgos, para abordar la ambigüedad.

Detalles

En programación orientada a objetos (POO), la herencia describe una relación entre dos clases en la que una clase (la clase secundaria ) es una subclase de la clase principal . El hijo hereda los métodos y atributos del padre, lo que permite una funcionalidad compartida. Por ejemplo, se podría crear una clase variable Mamífero con características como comer, reproducirse, etc.; luego defina una clase secundaria Cat que herede esas características sin tener que programarlas explícitamente, mientras agrega nuevas características como perseguir ratones .

La herencia múltiple permite a los programadores usar más de una jerarquía totalmente ortogonal simultáneamente, como permitir que Cat herede de un personaje de dibujos animados y de una mascota y un mamífero y acceda a funciones desde todas esas clases.

Implementaciones

Los lenguajes que admiten herencia múltiple incluyen: C++ , Common Lisp (a través de Common Lisp Object System (CLOS)), EuLisp (a través de The EuLisp Object System TELOS), Curl , Dylan , Eiffel , Logtalk , Object REXX , Scala (mediante el uso de clases mixin ), OCaml , Perl , POP-11 , Python , R , Raku y Tcl (integrados desde 8.6 o mediante Incremental Tcl ( Incr Tcl ) en versiones anteriores [4] [5] ).

El tiempo de ejecución de IBM System Object Model (SOM) admite herencia múltiple y cualquier lenguaje de programación dirigido a SOM puede implementar nuevas clases SOM heredadas de múltiples bases.

Algunos lenguajes orientados a objetos, como Swift , Java , Fortran desde su revisión de 2003 , C# y Ruby implementan herencia única , aunque los protocolos o interfaces proporcionan algunas de las funcionalidades de la verdadera herencia múltiple.

PHP usa clases de rasgos para heredar implementaciones de métodos específicos. Ruby usa módulos para heredar múltiples métodos.

El problema del diamante

Un diagrama de herencia de clases de diamantes.

El " problema del diamante " (a veces denominado el "Diamante Mortal de la Muerte" [6] ) es una ambigüedad que surge cuando dos clases B y C heredan de A, y la clase D hereda tanto de B como de C. Si hay un método en A que B y C han anulado , y D no lo anula, entonces, ¿qué versión del método hereda D: la de B o la de C?

Por ejemplo, en el contexto del desarrollo de software GUI , una clase puede heredar tanto de clases (para apariencia) como (para funcionalidad/manejo de entradas) y clases y ambas heredan de la clase. Ahora bien, si se llama al método para un objeto y no existe tal método en la clase pero hay un método anulado en o (o ambos), ¿qué método debería llamarse finalmente?ButtonRectangleClickableRectangleClickableObjectequalsButtonButtonequalsRectangleClickable

Se le llama "problema del diamante" debido a la forma del diagrama de herencia de clases en esta situación. En este caso, la clase A está en la parte superior, tanto B como C por separado debajo de ella, y D une los dos en la parte inferior para formar una forma de diamante.

Mitigación

Las lenguas tienen diferentes maneras de abordar estos problemas de herencia repetida.

Los lenguajes que solo permiten herencia única , donde una clase solo puede derivar de una clase base, no tienen el problema del diamante. La razón de esto es que dichos lenguajes tienen como máximo una implementación de cualquier método en cualquier nivel de la cadena de herencia, independientemente de la repetición o ubicación de los métodos. Normalmente, estos lenguajes permiten que las clases implementen múltiples protocolos , llamados interfaces en Java. Estos protocolos definen métodos pero no proporcionan implementaciones concretas. Esta estrategia ha sido utilizada por ActionScript , C# , D , Java , Nemerle , Object Pascal , Objective-C , Smalltalk , Swift y PHP . [13] Todos estos lenguajes permiten que las clases implementen múltiples protocolos.

Además, Ada , C#, Java, Object Pascal, Objective-C, Swift y PHP permiten la herencia múltiple de interfaces (llamadas protocolos en Objective-C y Swift). Las interfaces son como clases base abstractas que especifican firmas de métodos sin implementar ningún comportamiento. (Las interfaces "puras", como las de Java hasta la versión 7, no permiten ninguna implementación o datos de instancia en la interfaz). Sin embargo, incluso cuando varias interfaces declaran la misma firma de método, tan pronto como ese método se implementa (define) en cualquier parte de la cadena de herencia, anula cualquier implementación de ese método en la cadena superior (en sus superclases). Por lo tanto, en cualquier nivel dado de la cadena de herencia, puede haber como máximo una implementación de cualquier método. Por lo tanto, la implementación del método de herencia única no presenta el problema del diamante incluso con herencia múltiple de interfaces. Con la introducción de la implementación predeterminada para las interfaces en Java 8 y C# 8, todavía es posible generar un problema Diamond, aunque esto sólo aparecerá como un error en tiempo de compilación.

Ver también

Referencias

  1. ^ Cargill, TA (invierno de 1991). "Controversia: el caso contra la herencia múltiple en C++". Sistemas Computacionales . 4 (1): 69–82.
  2. ^ Waldo, Jim (primavera de 1991). "Controversia: el caso de la herencia múltiple en C++". Sistemas Computacionales . 4 (2): 157–171.
  3. ^ Schärli, Natanael; Ducasse, Stéphane; Nierstrasz, Óscar; Negro, Andrés. "Rasgos: unidades de comportamiento componibles" (PDF) . Web.cecs.pdx.edu . Consultado el 21 de octubre de 2016 .
  4. ^ "incr Tcl". blog.tcl.tk. ​Consultado el 14 de abril de 2020 .
  5. ^ "Introducción al lenguaje de programación Tcl". www2.lib.uchicago.edu . Consultado el 14 de abril de 2020 .
  6. ^ Martín, Robert C. (9 de marzo de 1997). "Java y C++: una comparación crítica" (PDF) . Objectmentor.com . Archivado desde el original (PDF) el 24 de octubre de 2005 . Consultado el 21 de octubre de 2016 .
  7. ^ "Estándar ECMA-367". Ecma-international.org . Consultado el 21 de octubre de 2016 .
  8. ^ "Estado de la Lambda". Cr.openjdk.java.net . Consultado el 21 de octubre de 2016 .
  9. ^ "perlobj". perldoc.perl.org . Consultado el 21 de octubre de 2016 .
  10. ^ Resumen. "El orden de resolución del método Python 2.3". Python.org . Consultado el 21 de octubre de 2016 .
  11. ^ "Unificando tipos y clases en Python 2.2". Python.org . Consultado el 21 de octubre de 2016 .
  12. ^ "Página de manual de la clase". Tcl.tk. ​16 de noviembre de 1999 . Consultado el 21 de octubre de 2016 .
  13. ^ "Interfaces de objetos: manual". PHP.net . 2007-07-04 . Consultado el 21 de octubre de 2016 .

Otras lecturas

enlaces externos