Egenskab (computerprogrammering) - Trait (computer programming)

I computerprogrammering er et træk et begreb, der bruges i objektorienteret programmering , som repræsenterer et sæt metoder, der kan bruges til at udvide funktionaliteten af ​​en klasse .

Egenskaber

Egenskaber giver både et sæt metoder, der implementerer adfærd til en klasse, og kræver, at klassen implementerer et sæt metoder, der parametrerer den leverede adfærd.

For kommunikation mellem objekter er træk et sted mellem en objektorienteret protokol (interface) og et mixin . En grænseflade kan definere en eller flere adfærd via metodesignaturer , mens et træk definerer adfærd via fulde metodedefinitioner: det vil sige, at det omfatter metodenes krop . I modsætning hertil inkluderer mixins fulde metodedefinitioner og kan også bære tilstand gennem medlemsvariabel, mens træk normalt ikke gør det.

Derfor oprettes et objekt defineret som et træk som sammensætning af metoder, som kan bruges af andre klasser uden at kræve flere arv . I tilfælde af en navngivende kollision , når mere end et træk, der skal bruges af en klasse, har en metode med samme navn, skal programmereren eksplicit skelne, hvilken af ​​disse metoder der vil blive brugt i klassen; dermed manuelt løse diamantproblemet med multipel arv. Dette er forskelligt fra andre sammensætning metoder i objektorienteret programmering, hvor modstridende navne automatisk løses ved scoping regler .

Ud fra følgende betragtninger mixins kan sammensættes kun ved hjælp af arv drift, træk tilbyde et langt bredere udvalg af aktiviteter, herunder:

  • symmetrisk sum : en operation, der fusionerer to usammenhængende træk for at skabe et nyt træk
  • tilsidesættelse (eller asymmetrisk sum ): en operation, der danner et nyt træk ved at tilføje metoder til et eksisterende træk, muligvis tilsidesætte nogle af dets metoder
  • alias : en operation, der skaber et nyt træk ved at tilføje et nyt navn til en eksisterende metode
  • eksklusion : en operation, der danner et nyt træk ved at fjerne en metode fra et eksisterende træk. (Kombination af dette med alias -operationen giver en lav omdøbningsoperation ).

Træk er sammensat på følgende måder:

  • Egenskabssammensætning er kommutativ; rækkefølgen af ​​tilføjelse af træk er ligegyldig. For eksempel given karakteregenskab S = A + B , derefter karakteregenskab T = B + A er det samme som S .
  • Modstridende metoder er udelukket fra sammensætningen.
  • Indlejrede træk svarer til fladtrykte træk; sammensætningshierarkiet påvirker ikke egenskabernes adfærd. For eksempel given karakteregenskab S = A + X , hvor X = B + C , derefter karakteregenskab T = A + B + C er det samme som S .

Understøttede sprog

Træk stammer oprindeligt fra programmeringssproget Self og understøttes af følgende programmeringssprog:

  • AmbientTalk : Kombinerer egenskaberne for Self træk (objektbaseret multipel nedarvning) og Smalltalk 's Squeak træk (kræver eksplicit sammensætning af træk af programmøren). Det bygger på forskningen om stateful og frysbare træk for at muliggøre stat inden for træk, hvilket ikke var tilladt i de første definitioner.
  • C# : Siden version 8.0 har C# understøttelse af standardgrænseflademetoder , som har nogle egenskaber ved træk.
  • C ++ : Anvendes i Standard Template Library og C ++ standardbiblioteket til at understøtte generiske containerklasser og i Boost TypeTraits -biblioteket.
  • Curl : Abstrakte klasser som mixins tillader metodeimplementeringer og udgør således egenskaber ved et andet navn.
  • D : Siden version 2.003 har __traits sprogudvidelse og std.traits modulhjælperskabeloner skabt kompileringstidstræk. Sammen med andre sprogfunktioner (især skabeloner og mixins) tillader de fleksibel automatisk generering af metoder baseret på grænseflader og typer. D tillader også eksplicit aliasing af medlemsmetoder og variabler, herunder videresendelse til flere medlemsklasser.
  • Fæstning
  • Groovy : Siden version 2.3
  • Haskell : I Haskell er egenskaber kendt som typeklasser .
  • Haxe : Siden version 2.4.0. Kaldes Statisk udvidelse i manualen og bruger usingsøgeord
  • Java : Siden version 8 har Java understøttelse af standardmetoder , som har nogle egenskaber ved træk.
  • JavaScript : Egenskaber kan implementeres via funktioner og delegationer eller gennem biblioteker, der giver træk.
  • Julia : Flere pakker implementerer træk, f.eks.
  • Kotlin : Træk er blevet kaldt grænseflader siden M12.
  • Lasso
  • OCaml : Egenskaber kan implementeres ved hjælp af en række forskellige sprogfunktioner: inklusion af modul og modul, funktorer og funktortyper, klasse- og klassetypearv osv.
  • Perl : Kaldte roller , de er implementeret i Perl -biblioteker som Moose , Role :: Tiny og Role :: Basic. Roller er en del af søstersproget Raku .
  • PHP : Since version 5.4, PHP giver brugerne mulighed for at specificere skabeloner, der giver evnen til at "arve" fra mere end én (trait-) klasse, som en pseudo multipel nedarvning .
  • Python : Via et tredjepartsbibliotek eller via mixin-klasser i højere orden
  • Racket : Understøtter træk som et bibliotek og bruger makroer, strukturer og førsteklasses klasser til at implementere dem.
  • Ruby : Modulmixins kan bruges til at implementere træk.
  • Rust
  • Scala -egenskab er indbygget understøttet med nøgleordet trait.
  • Smalltalk : Træk implementeres i to dialekter af Smalltalk, Squeak og Pharo .
  • Swift : Egenskaber kan implementeres med protokoludvidelser .

Eksempler

C#

På C# 8.0 er det muligt at definere en implementering som medlem af en grænseflade.

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

Dette eksempel bruger en egenskab til at forbedre andre klasser:

// 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;
}

Dette gør det muligt at simulere aspekter ved flere arv:

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)
    {
        // …
    }
}

Rust

Et træk i Rust erklærer et sæt metoder, som en type skal implementere. Rustkompilatorer kræver, at træk forklares, hvilket sikrer sikkerheden ved generika i 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)
}

For at forenkle kedelig og gentagen implementering af træk som Debugog Ordkan derivemakroen bruges til at anmode kompilatorer om at generere bestemte implementeringer automatisk. Derivable træk kan nævnes: Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ordog Hash.

Se også

Referencer

eksterne links