En la programación de computadoras , un rasgo es un concepto utilizado en la programación orientada a objetos , que representa un conjunto de métodos que se pueden utilizar para ampliar la funcionalidad de una clase . [1] [2]
Caracteristicas
Los rasgos proporcionan un conjunto de métodos que implementan el comportamiento de una clase y requieren que la clase implemente un conjunto de métodos que parametrizan el comportamiento proporcionado.
Para la comunicación entre objetos, los rasgos se encuentran en algún lugar entre un protocolo orientado a objetos (interfaz) y un mixin . Una interfaz puede definir uno o más comportamientos a través de firmas de métodos , mientras que un rasgo define comportamientos a través de definiciones de métodos completos: es decir, incluye el cuerpo de los métodos . Por el contrario, los mixins incluyen definiciones de métodos completos y también pueden llevar el estado a través de la variable miembro, mientras que los rasgos generalmente no lo hacen.
Por lo tanto, un objeto definido como rasgo se crea como la composición de métodos, que pueden ser utilizados por otras clases sin requerir herencia múltiple . En caso de una colisión de nombres , cuando más de un rasgo para ser utilizado por una clase tiene un método con el mismo nombre, el programador debe eliminar la ambigüedad explícitamente cuál de esos métodos se utilizará en la clase; resolviendo así manualmente el problema del diamante de la herencia múltiple. Esto es diferente de otros métodos de composición en la programación orientada a objetos, donde los nombres en conflicto se resuelven automáticamente mediante reglas de alcance .
Mientras que los mixins solo pueden componerse utilizando la operación de herencia , los rasgos ofrecen una selección mucho más amplia de operaciones, que incluyen: [3] [4]
- suma simétrica : una operación que fusiona dos rasgos disjuntos para crear un nuevo rasgo
- anular (o suma asimétrica ): una operación que forma un nuevo rasgo agregando métodos a un rasgo existente, posiblemente anulando algunos de sus métodos
- alias : una operación que crea un nuevo rasgo agregando un nuevo nombre para un método existente
- exclusión : operación que forma un rasgo nuevo al eliminar un método de un rasgo existente. (La combinación de esto con la operación de alias produce una operación de cambio de nombre superficial ).
Los rasgos se componen de las siguientes formas:
- La composición de los rasgos es conmutativa; el orden de agregar rasgos no importa. Por ejemplo, dada rasgo S = A + B , a continuación, trait T = B + A es el mismo que S .
- Los métodos conflictivos están excluidos de la composición.
- Los rasgos anidados son equivalentes a los rasgos aplanados; la jerarquía de composición no afecta el comportamiento de los rasgos. Por ejemplo, dada rasgo S = A + X , donde X = B + C , a continuación, rasgo T = A + B + C es el mismo que S . [1]
Idiomas admitidos
Los rasgos provienen originalmente del lenguaje de programación Self [5] y son compatibles con los siguientes lenguajes de programación:
- AmbientTalk : combina las propiedades de los rasgos Self (herencia múltiple basada en objetos) y los rasgos Squeak de Smalltalk (que requieren una composición explícita de rasgos por parte del programador). Se basa en la investigación sobre rasgos con estado y congelables para habilitar el estado dentro de los rasgos, lo que no estaba permitido en las primeras definiciones. [6]
- C # : desde la versión 8.0, C # tiene soporte para métodos de interfaz predeterminados , [7] que tienen algunas propiedades de rasgos. [8]
- C ++ : Se utiliza en la biblioteca de plantillas estándar y la biblioteca estándar de C ++ para admitir clases de contenedor genéricas [9] [10] y en la biblioteca Boost TypeTraits. [11]
- Curl : Las clases abstractas como mixins permiten implementaciones de métodos y, por lo tanto, constituyen rasgos con otro nombre. [ cita requerida ]
- D : Desde la versión 2.003, la extensión de lenguaje __traits [12] y las plantillas auxiliares del módulo std.traits [13] proporcionan características en tiempo de compilación. Junto con otras características del lenguaje (especialmente plantillas y mixins), permiten la generación automática flexible de métodos basados en interfaces y tipos. D también permite el alias explícito de métodos y variables de miembros, incluido el reenvío a varias clases de miembros. [14]
- Fortaleza [15]
- Groovy : desde la versión 2.3 [16]
- Haskell : en Haskell, los rasgos se conocen como clases de tipo .
- Haxe : desde la versión 2.4.0. [17] Llamada extensión estática [18] en el manual, utiliza
using
palabras clave - Java : desde la versión 8, Java tiene soporte para métodos predeterminados , [19] que tienen algunas propiedades de rasgos. [20] [21]
- JavaScript : los rasgos se pueden implementar mediante funciones y delegaciones [22] o mediante bibliotecas que proporcionan rasgos. [23] [24] [25]
- Julia : Varios paquetes implementan rasgos, p. Ej., [26]
- Kotlin : Los rasgos se han denominado interfaces [27] desde M12. [28]
- Lazo [29]
- OCaml : Los rasgos se pueden implementar utilizando una variedad de características del lenguaje: módulo y inclusión de tipo de módulo, functores y tipos de functor, clase y herencia de tipo de clase, etcétera.
- Perl : llamados roles , se implementan en bibliotecas de Perl como Moose , Role :: Tiny y Role :: Basic. Los roles son parte del idioma hermano Raku . [30]
- PHP : Desde la versión 5.4, [31] [32] PHP permite a los usuarios especificar plantillas que brindan la capacidad de "heredar" de más de una clase (trait-), como una herencia pseudo múltiple .
- Python : a través de una biblioteca de terceros, [33] [34] o mediante clases mixin de orden superior [35]
- Raqueta : admite rasgos como biblioteca y utiliza macros, estructuras y clases de primera clase para implementarlos. [36]
- Ruby : los mixins de módulo se pueden usar para implementar rasgos. [37]
- Óxido [38]
- El rasgo Scala [39] [40] está integrado con la palabra clave
trait
. - Smalltalk : los rasgos se implementan en dos dialectos de Smalltalk, Squeak [1] y Pharo . [41]
- Rápido : los rasgos se pueden implementar con extensiones de protocolo . [42]
Ejemplos de
C#
En C # 8.0, es posible definir una implementación como miembro de una interfaz.
usando el sistema ;espacio de nombres CSharp8NewFeatures { interfaz ILogger { // Métodos de interfaz tradicionales void Log ( mensaje de cadena ); void LogError ( excepción de excepción ); // Método de interfaz predeterminado void LogWarning ( mensaje de cadena ) { Console . WriteLine ( mensaje ); } } clase Logger : ILogger { público vacío Log ( cadena de mensaje ) { consola . WriteLine ( mensaje ); } public void LogError ( excepción de excepción ) { Console . WriteLine ( excepción . ToString ()); } } class Program { static void Main ( string [] args ) { ILogger logger = new Logger (); registrador . LogWarning ( "Algún mensaje de advertencia" ); } } }
PHP
Este ejemplo usa un rasgo para mejorar otras clases:
// El rasgo de la plantilla TSingleton { private static $ _instance = null ; función privada __construct () {} // Debe tener un constructor predeterminado privado y tenga en cuenta que no debe abrirlo en la clase función estática pública getInstance () { if ( nulo === self :: $ _instance ) { self :: $ _instance = new self (); } return self :: $ _instance ; } }class FrontController { use TSingleton ; }// También se puede usar en clases ya extendidas class WebSite extiende SomeClass { use TSingleton ; }
Esto permite simular aspectos de herencia múltiple:
rasgo TBounding { public $ x , $ y , $ ancho , $ alto ; }rasgo TMoveable { función pública moveTo ( $ x , $ y ) { //… } } trait TResizeable {cambio de tamaño de función pública ( $ newWidth , $ newHeight ) { //… } } class Rectangle { use TBounding , TMoveable , TResizeable ; función pública fillColor ( $ color ) { //… } }
Oxido
Un rasgo en Rust declara un conjunto de métodos que un tipo debe implementar. [43] Los compiladores de Rust requieren que se expliquen los rasgos, lo que garantiza la seguridad de los genéricos en Rust.
// el tipo T debe tener el rasgo "Ord" // para que se puedan realizar las operaciones ">" y "<" fn get_max < T : Ord > ( a : & [ T ]) -> Option <& T > { deje mut resultado = a . obtener ( 0 ) ? ; para n en un { si * n > * resultado { resultado = & n ; } } Algunos ( resultado )}
Para simplificar la implementación tediosa y repetida de rasgos como Debug
y Ord
, la derive
macro se puede usar para solicitar a los compiladores que generen ciertas implementaciones automáticamente. [44] rasgos Derivable incluyen: Clone
, Copy
, Debug
, Default
, PartialEq
, Eq
, PartialOrd
, Ord
y Hash
.
Ver también
- Método de extensión
- interfaz (programación orientada a objetos)
- UFCS
Referencias
- ^ a b c Schärli, Natanael; Ducasse, Stéphane; Nierstrasz, Oscar ; Negro, Andrew P. (2003). "Rasgos: unidades componibles de comportamiento" (PDF) . Actas de la Conferencia Europea de Programación Orientada a Objetos (ECOOP) . Apuntes de conferencias en Ciencias de la Computación. 2743 : 248–274.
- ^ Ducasse, Stéphane; Nierstrasz, Oscar; Schärli, Nathanael; Wuyts, Roel; Black, Andrew P. (marzo de 2006). "Rasgos: un mecanismo para la reutilización de grano fino". Transacciones ACM sobre lenguajes y sistemas de programación . 28 (2): 331–388. doi : 10.1145 / 1119479.1119483 .
- ^ Fisher, Kathleen ; Reppy, John (2003). "Rasgos escritos estáticamente" (PDF) . Universidad de Chicago . Archivado (PDF) desde el original el 17 de mayo de 2004. Cite journal requiere
|journal=
( ayuda ) - ^ Fisher, Kathleen; Reppy, John (2004). Un cálculo de rasgos mecanografiado (PDF) . XI Taller de Fundamentos de la Programación Orientada a Objetos . Universidad de Chicago .
- ^ Curry, Gael; Baer, Larry; Lipkie, Daniel; Lee, Bruce (1982). Rasgos: un enfoque para las subclases de herencia múltiple . Jornada SIGOA sobre Sistemas de Información de Oficina. Filadelfia, Pensilvania, EE.UU .: ACM Press. págs. 1–9. doi : 10.1145 / 966873.806468 .
- ^ Van Cutsem, Tom; Bergel, Alexandre; Ducasse, Stéphane; De Meuter, Wolfgang (2009). Agregar control de estado y visibilidad a los rasgos mediante el anidamiento léxico (PDF) . Congreso Europeo de Programación Orientada a Objetos (ECOOP 2009). Apuntes de conferencias en Ciencias de la Computación. 5653 . Springer-Verlag. págs. 220–243. doi : 10.1007 / 978-3-642-03013-0_11 . ISBN 978-3-642-03012-3.
- ^ "Métodos de interfaz predeterminados" . Novedades de C # 8.0 . Microsoft . Consultado el 29 de noviembre de 2019 .
- ^ "Las interfaces en C # 8.0 se renuevan" . Implementación predeterminada en interfaces en C # 8.0 . Hablando de Dotnet . Consultado el 29 de noviembre de 2019 .
- ^ "iterator_traits " . Biblioteca de plantillas estándar . SGI.
- ^ Myers, Nathan C. (junio de 1995). "Rasgos: una nueva y útil técnica de plantilla" . Informe C ++ . Consultado el 23 de enero de 2016 .
- ^ Abrahams, David. "Técnicas genéricas de programación: rasgos" . Impulsar las bibliotecas de C ++ . Consultado el 23 de enero de 2016 .
- ^ "Rasgos" . La referencia del lenguaje D . Marte digital . Consultado el 23 de enero de 2016 .
- ^ "rasgos estándar" . The D Language - Referencia de biblioteca . Marte digital . Consultado el 23 de enero de 2016 .
- ^ "Clases" . La referencia del lenguaje D . Marte digital . Consultado el 23 de enero de 2016 .
- ^ Steele, Guy; Maessen, Jan-Willem (11 de junio de 2006). "Tutorial del lenguaje de programación Fortress" (PDF) . Sun Microsystems . Consultado el 23 de enero de 2016 .
- ^ "Orientación a objetos: rasgos" . El lenguaje de programación Groovy . Consultado el 23 de enero de 2016 .
- ^ "Haxe 2.4.0 - Haxe - El kit de herramientas multiplataforma" . Haxe: el kit de herramientas multiplataforma . Consultado el 12 de septiembre de 2017 .
- ^ "Manual - Haxe - El conjunto de herramientas multiplataforma" . Haxe: el kit de herramientas multiplataforma . Consultado el 12 de septiembre de 2017 .
- ^ "Métodos predeterminados" . Los tutoriales de Java . Oracle . Consultado el 23 de enero de 2016 .
- ^ Bono, Viviana; Mensa, Enrico; Naddeo, Marco (septiembre de 2014). Programación orientada a rasgos en Java 8 . Congreso Internacional sobre Principios y Prácticas de Programación en la Plataforma Java: máquinas virtuales, lenguajes y herramientas (PPPJ '14) . Cracovia, Polonia.
- ^ Forslund, Emil (3 de febrero de 2016). "Definición del patrón de rasgos en Java" . Era de Java . Archivado desde el original el 4 de agosto de 2016 . Consultado el 3 de febrero de 2016 .
- ^ Seliger, Peter (11 de abril de 2014). "Los muchos talentos de JavaScript" . Consultado el 23 de enero de 2015 .
- ^ "Traits.js: rasgos para JavaScript" . Consultado el 23 de enero de 2016 .
- ^ Van Cutsem, Tom; Miller, Mark S. (2012). "Composición robusta de rasgos para Javascript" (PDF) . Ciencia de la Programación de Computadores . Consultado el 23 de enero de 2016 .
- ^ "CocktailJS" . Consultado el 23 de enero de 2016 .
- ^ mauro3. "SimpleTraits.jl" . Consultado el 23 de marzo de 2017 .
- ^ "Interfaces" . Referencia de Kotlin . JetBrains . Consultado el 23 de enero de 2016 .
- ^ Breslav, Andrey (29 de mayo de 2015). "¡Kotlin M12 está fuera!" . Blog de Kotlin . JetBrains . Consultado el 23 de enero de 2016 .
- ^ "Rasgos" . Guía de idiomas de lazo . LassoSoft. 6 de enero de 2014 . Consultado el 23 de enero de 2016 .
- ^ cromático (30 de abril de 2009). "El por qué de los roles de Perl" . Consultado el 23 de enero de 2016 .
- ^ "Rasgos" . Documentación PHP . El Grupo PHP . Consultado el 23 de enero de 2016 .
- ^ Marr, Stefan (9 de enero de 2011). "Solicitud de comentarios: reutilización horizontal para PHP" . Wiki de PHP.net . El Grupo PHP . Consultado el 31 de enero de 2011 .
- ^ Perä, Teppo. "Documentación de py3traits" . Consultado el 23 de enero de 2016 .
- ^ Perä, Teppo (25 de marzo de 2015). "py2traits" . Consultado el 23 de enero de 2016 .
- ^ "Clases mixtas de orden superior" . Archivado desde el original el 9 de octubre de 2016.
- ^ "Rasgos" . La referencia de la raqueta . Consultado el 23 de enero de 2016 .
- ^ David Naseby (14 de febrero de 2004). "Rasgos en Ruby" . Ruby Naseby . Consultado el 23 de enero de 2016 .
- ^ "Rasgos" . El lenguaje de programación Rust . Consultado el 30 de septiembre de 2019 .
- ^ "Rasgos" . Un recorrido por Scala . École polytechnique fédérale de Lausanne . Consultado el 23 de enero de 2016 .
- ^ Neward, Ted (29 de abril de 2008). "La guía del desarrollador Java ocupado de Scala: de rasgos y comportamientos" . IBM developerWorks . IBM . Consultado el 23 de enero de 2016 .
- ^ "Rasgos en 10 minutos" . Pharo: The CollaborActive Book . Consultado el 23 de enero de 2016 .
- ^ Hollemans, Matthijs (22 de julio de 2015). "Mixins y rasgos en Swift 2.0" . Consultado el 23 de enero de 2016 .
- ^ "Rasgos - Introducción a la programación con Rust" .
- ^ "Rasgos - el lenguaje de programación Rust" .
enlaces externos
- "Rasgos: unidades componibles de comportamiento" . Grupo de Composición de Software . Universidad de Berna.