Ad hoc polymorfism
Polymorfism |
---|
Ad hoc polymorfism |
Parametrisk polymorfism |
Undertypning |
I programmeringsspråk är ad hoc polymorfism en sorts polymorfism där polymorfa funktioner kan appliceras på argument av olika typer, eftersom en polymorf funktion kan beteckna ett antal distinkta och potentiellt heterogena implementeringar beroende på vilken typ av argument(er) som den tillämpas. När det tillämpas på objektorienterade eller procedurmässiga koncept kallas det också för funktionsöverbelastning eller operatörsöverbelastning . Termen ad hoc i detta sammanhang är inte avsedd att vara nedsättande; det hänvisar helt enkelt till det faktum att denna typ av polymorfism inte är en grundläggande egenskap hos typsystemet . Detta i motsats till parametrisk polymorfism , där polymorfa funktioner skrivs utan att nämna någon specifik typ, och kan således tillämpa en enda abstrakt implementering på ett valfritt antal typer på ett transparent sätt. Denna klassificering introducerades av Christopher Strachey 1967.
Tidig bindning
Ad hoc polymorfism är en sändningsmekanism : kontroll som rör sig genom en namngiven funktion skickas till olika andra funktioner utan att behöva specificera den exakta funktionen som anropas. Överbelastning tillåter att flera funktioner med olika typer definieras med samma namn; kompilatorn eller tolken ser automatiskt till att rätt funktion anropas . På detta sätt kan funktioner som lägger till listor med heltal , listor med strängar , listor med reella tal och så vidare skrivas, och alla kallas append - och den högra appendfunktionen skulle anropas baserat på vilken typ av listor som läggs till. Detta skiljer sig från parametrisk polymorfism, där funktionen skulle behöva skrivas generiskt , för att fungera med någon form av lista. Med hjälp av överbelastning är det möjligt att låta en funktion utföra två helt olika saker baserat på vilken typ av input som skickas till den; detta är inte möjligt med parametrisk polymorfism. Ett annat sätt att se på överbelastning är att en rutin identifieras unikt inte av sitt namn, utan genom kombinationen av dess namn och antalet, ordningen och typerna av dess parametrar.
Denna typ av polymorfism är vanlig i objektorienterade programmeringsspråk , av vilka många tillåter att operatörer överbelastas på ett sätt som liknar funktioner (se operatörsöverbelastning ) . Vissa språk som inte är dynamiskt typade och saknar ad hoc-polymorfism (inklusive typklasser) har längre funktionsnamn som print_int
, print_string
, etc. Detta kan ses som en fördel (mer beskrivande) eller en nackdel (alltför utförlig) beroende på ens poäng av synen.
En fördel som ibland uppnås av överbelastning är utseendet på specialisering, t.ex. kan en funktion med samma namn implementeras på flera olika sätt, var och en optimerad för de specifika datatyper som den arbetar på. Detta kan ge ett bekvämt gränssnitt för kod som måste specialiseras för flera situationer av prestandaskäl. Nackdelen är att typsystemet inte kan garantera konsekvensen i de olika implementeringarna.
Eftersom överbelastning görs vid kompileringstidpunkten, är det inte ett substitut för sen bindning som finns vid subtyping av polymorfism .
Sen bindning
Trots det föregående avsnittet finns det andra sätt på vilka ad hoc- polymorfism kan fungera. Tänk till exempel Smalltalk-språket. I Smalltalk görs överbelastningen vid körning, eftersom metoderna ("funktionsimplementering") för varje överbelastat meddelande ("överbelastad funktion") löses när de är på väg att exekveras. Detta händer vid körning, efter att programmet har kompilerats. Därför ges polymorfism genom att subtypa polymorfism som på andra språk, och den utökas också i funktionalitet av ad hoc polymorfism vid körning.
En närmare titt kommer också att avslöja att Smalltalk ger en något annorlunda variation av ad hoc- polymorfism. Eftersom Smalltalk har en sen bunden exekveringsmodell, och eftersom den ger objekt förmågan att hantera meddelanden som inte förstås, är det möjligt att implementera funktionalitet med hjälp av polymorfism utan att explicit överbelasta ett visst meddelande. Detta är kanske inte allmänt rekommenderad praxis för vardaglig programmering, men det kan vara ganska användbart när du implementerar proxyservrar.
Även om överbelastning av vanliga klassmetoder och konstruktorer generellt sett inte anses vara polymorfism, finns det mer enhetliga språk där klasser är vanliga objekt. I Smalltalk, till exempel, är klasser vanliga objekt. Detta innebär i sin tur att meddelanden som skickas till klasser kan överbelastas, och det är också möjligt att skapa objekt som beter sig som klasser utan att deras klasser ärver från klasshierarkin. Dessa är effektiva tekniker som kan användas för att dra fördel av Smalltalks kraftfulla reflektionsförmåga . Liknande arrangemang är också möjliga på språk som Self och Newspeak .
Exempel
Föreställ dig en operator +
som kan användas på följande sätt:
1 + 2 = 3
3,14 + 0,0015 = 3,1415
1 + 3,7 = 4,7
[1, 2, 3] + [4, 5, 6] = [1, 2, 3, 4, 5, 6]
[true, false] + [false, true] = [sant, falskt, falskt, sant]
"bab" + "oon" = "baboon"
För att hantera dessa sex funktionsanrop behövs fyra olika kodbitar (eller tre, om strängar anses vara teckenlistor):
- I det första fallet måste heltalsaddition anropas .
- I det andra och tredje fallet måste flyttalstillägg åberopas (med typbefordran , eller typtvång , i det tredje fallet).
- I det fjärde och femte fallet måste listkonkatenering åberopas .
- I det sista fallet måste strängkonkatenering anropas .
Namnet +
syftar alltså på tre eller fyra helt olika funktioner. Detta är ett exempel på överbelastning eller mer specifikt operatörsöverbelastning .
Notera tvetydigheten i strängtyperna som användes i det sista fallet. Tänk på "123" + "456"
där programmeraren naturligtvis kan anta addition snarare än sammanlänkning. De kan förvänta sig "579"
istället för "123456"
. Överbelastning kan därför ge olika betydelser, eller semantik, för en operation, såväl som olika implementeringar.
Se även
- Operatör överbelastning
- Typklass
- Polymorfism (datavetenskap) (andra typer av polymorfism)
- Parametrisk polymorfism