Traço (programação de computador) - Trait (computer programming)
Na programação de computadores , um traço é um conceito usado na programação orientada a objetos , que representa um conjunto de métodos que podem ser usados para estender a funcionalidade de uma classe .
Características
As características fornecem um conjunto de métodos que implementam o comportamento para uma classe e exigem que a classe implemente um conjunto de métodos que parametrizam o comportamento fornecido.
Para a comunicação entre objetos, as características estão em algum lugar entre um protocolo orientado a objetos (interface) e um mixin . Uma interface pode definir um ou mais comportamentos por meio de assinaturas de método , enquanto uma característica define comportamentos por meio de definições de método completas: ou seja, inclui o corpo dos métodos . Em contraste, os mixins incluem definições de método completas e também podem transportar o estado por meio da variável membro, enquanto as características geralmente não.
Portanto, um objeto definido como uma característica é criado como a composição de métodos, que podem ser usados por outras classes sem exigir herança múltipla . No caso de uma colisão de nomenclatura , quando mais de um traço a ser usado por uma classe tem um método com o mesmo nome, o programador deve esclarecer explicitamente qual desses métodos será usado na classe; resolvendo assim manualmente o problema do diamante de herança múltipla. Isso é diferente de outros métodos de composição na programação orientada a objetos, onde nomes conflitantes são resolvidos automaticamente por regras de escopo .
Considerando que os mixins podem ser compostos apenas usando a operação de herança , os traits oferecem uma seleção muito mais ampla de operações, incluindo:
- soma simétrica : uma operação que mescla duas características disjuntas para criar uma nova característica
- override (ou soma assimétrica ): uma operação que forma uma nova característica adicionando métodos a uma característica existente, possivelmente substituindo alguns de seus métodos
- alias : uma operação que cria uma nova característica adicionando um novo nome para um método existente
- exclusão : uma operação que forma um novo traço ao remover um método de um traço existente. (Combinar isso com a operação de alias resulta em uma operação de renomeação superficial ).
As características são compostas das seguintes maneiras:
- A composição do traço é comutativa; a ordem de adição de características não importa. Por exemplo, dada característica S = A + B , em seguida, traço T = B + A é o mesmo que S .
- Métodos conflitantes são excluídos da composição.
- Os traços aninhados são equivalentes aos traços achatados; a hierarquia de composição não afeta o comportamento das características. Por exemplo, dada característica S = A + X , onde X = B + C , em seguida característica T = A + B + C é o mesmo que S .
Idiomas suportados
As características vêm originalmente da linguagem de programação Self e são suportadas pelas seguintes linguagens de programação:
- AmbientTalk : combina as propriedades de auto traços (com base em objectos de herança múltipla) e Smalltalk 's rangido traços (exigindo composição explícito de traços pelo programador). Ele se baseia na pesquisa sobre características stateful e freezable para habilitar o estado dentro das características, o que não era permitido nas primeiras definições.
- C # : desde a versão 8.0, C # tem suporte para métodos de interface padrão , que têm algumas propriedades de características.
- C ++ : Usado na Biblioteca de Modelos Padrão e na biblioteca padrão C ++ para oferecer suporte a classes de contêiner genéricas e na biblioteca Boost TypeTraits.
- Curl : Classes abstratas como mixins permitem implementações de métodos e, portanto, constituem características com outro nome.
- D : Desde a versão 2.003, a extensão de linguagem __traits e os modelos auxiliares do módulo std.traits fornecem características de tempo de compilação. Junto com outros recursos de linguagem (notadamente modelos e mixins), eles permitem a geração automática e flexível de métodos baseados em interfaces e tipos. D também permite o aliasing explícito de métodos e variáveis de membro, incluindo o encaminhamento para várias classes de membro.
- Fortaleza
- Groovy : desde a versão 2.3
- Haskell : Em Haskell, os traços são conhecidos como classes de tipo .
-
Haxe : desde a versão 2.4.0. Chamada de extensão estática no manual, ela usa a
using
palavra - chave - Java : desde a versão 8, o Java tem suporte para métodos padrão , que possuem algumas propriedades de características.
- JavaScript : as características podem ser implementadas por meio de funções e delegações ou por meio de bibliotecas que fornecem características.
- Julia : Vários pacotes implementam características, por exemplo,
- Kotlin : Os traços são chamados de interfaces desde M12.
- Laço
- OCaml : Traits podem ser implementados usando uma variedade de recursos de linguagem: módulo e inclusão de tipo de módulo, functores e tipos de functor, classe e herança de tipo de classe, etc.
- Perl : funções chamadas , são implementadas em bibliotecas Perl como Moose , Role :: Tiny e Role :: Basic. Os papéis fazem parte da linguagem irmã Raku .
- PHP : Desde a versão 5.4, o PHP permite aos usuários especificar modelos que fornecem a habilidade de "herdar" de mais de uma classe (característica), como uma herança pseudo múltipla .
- Python : por meio de uma biblioteca de terceiros ou de classes mixin de ordem superior
- Racket : oferece suporte a traits como uma biblioteca e usa macros, estruturas e classes de primeira classe para implementá-los.
- Ruby : Os mixins de módulo podem ser usados para implementar características.
- Ferrugem
-
O traço Scala é embutido com suporte na palavra-chave
trait
. - Smalltalk : Traits são implementados em dois dialetos de Smalltalk, Squeak e Pharo .
- Swift : os traços podem ser implementados com extensões de protocolo .
Exemplos
C #
No C # 8.0, é possível definir uma implementação como membro de uma interface.
using System;
namespace CSharp8NewFeatures
{
interface ILogger
{
// Traditional interface methods
void Log(string message);
void LogError(Exception exception);
// Default interface method
void LogWarning(string message)
{
Console.WriteLine(message);
}
}
class Logger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
public void LogError(Exception exception)
{
Console.WriteLine(exception.ToString());
}
}
class Program
{
static void Main(string[] args)
{
ILogger logger = new Logger();
logger.LogWarning("Some warning message");
}
}
}
PHP
Este exemplo usa uma característica para aprimorar outras classes:
// The template
trait TSingleton
{
private static $_instance = null;
private function __construct() {} // Must have private default constructor and be aware not to open it in the class
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
}
class FrontController
{
use TSingleton;
}
// Can also be used in already extended classes
class WebSite extends SomeClass
{
use TSingleton;
}
Isso permite simular aspectos de herança múltipla:
trait TBounding
{
public $x, $y, $width, $height;
}
trait TMoveable
{
public function moveTo($x, $y)
{
// …
}
}
trait TResizeable
{
public function resize($newWidth, $newHeight)
{
// …
}
}
class Rectangle
{
use TBounding, TMoveable, TResizeable;
public function fillColor($color)
{
// …
}
}
Ferrugem
Uma característica em Rust declara um conjunto de métodos que um tipo deve implementar. Os compiladores Rust exigem que os traços sejam explicados, o que garante a segurança dos genéricos no Rust.
// type T must have the "Ord" trait
// so that ">" and "<" operations can be done
fn get_max<T: Ord>(a: &[T]) -> Option<&T> {
let mut result = a.get(0)?;
for n in a {
if *n > *result {
result = &n;
}
}
Some(result)
}
Para simplificar a implementação entediante e repetida de características como Debug
e Ord
, a derive
macro pode ser usada para solicitar que os compiladores gerem certas implementações automaticamente. Traços deriváveis incluem: Clone
, Copy
, Debug
, Default
, PartialEq
, Eq
, PartialOrd
, Ord
e Hash
.
Veja também
Referências
links externos
- "Traços: unidades composíveis de comportamento" . Grupo de composição de software . Universidade de Berna.