*Tämä artikkeli käsittelee olio-ohjelmoinnin käsitettä. Materiaalitieteen käsitettä käsittelee polymorfia.*
**Polymorfismi** on olio-ohjelmoinnissa esiintyvä käsite, jonka mukaan aliluokat voivat määrittää oman yksilöllisen toimintansa ja silti jakaa saman toiminnallisuuden yläluokan kanssa.
Virtuaalimetodi on jäsenfunktio, joka voidaan määritellä uudelleen perityssä luokassa. Bjarne Stroustrupin mukaan polymorfismi tarjoaa yhden rajapinnan eri tyyppisiin entiteetteihin. Polymorfismin käsite pohjautuu biologian periaatteeseen, että yhdellä eliöllä voi olla monia eri muotoja tai vaiheita.

Perinteisesti tyypitetyt kielet, jotka perustuvat funktioille ja proseduureille, tukevat vain uniikkeja tyyppejä operandeilla.
Tämäntyyppiset kielet ovat *monomorfisia*: esimerkiksi Pascal on monomorfinen kieli. Pascal ja Ada sisältävät keinoja tiukan monomorfisuuden helpottamiseen erikoistapauksissa, josta johtuen niitä voidaan sanoa enimmäkseen monomorfisiksi.

Historia
--------

Kiinnostus polymorfisen tyyppisiä järjestelmiä kohtaan kasvoi 1990-luvulla merkittävästi, ja käytännön toteutukset alkoivat ilmaantua saman vuosikymmenen lopulla. Ad hoc -polymorfismi ja parametrinen polymorfismi kuvattiin alun perin Christopher Stracheyn julkaisussa *Fundamental Concepts in Programming Languages* , jossa ne on lueteltu polymorfismin "kahdeksi pääluokaksi". Ad hoc -polymorfismi oli Algol 68:n ominaisuus, kun taas parametrinen polymorfismi oli ML:n*selvennä* tyyppijärjestelmän ydinominaisuus.

Peter Wegner ja Luca Cardelli esittelivät vuoden 1985 artikkelissa inkluusiopolymorfismi-termin alatyyppien ja periytymisen mallintamiseen , ja katsoivat Simulan olevan ensimmäinen ohjelmointikieli, joka toteuttaa sen.

Luokittelu
----------

Luca Cardellin ja Peter Wegnerin luokittelussa polymorfiset kielet voidaan jakaa seuraavasti:

* universaali
	+ parametrinen
	+ liittävä
* ad-hoc
	+ ylikuormittava
	+ pakottava

Universaali polymorfismi toimii äärettömällä määrällä tyyppejä ja suorittaa samaa ohjelmakoodia kaikille tyypeille.
Ad-hoc polymorfismi toimii rajatulla määrällä tyyppejä ja voidaan toteuttaa joukolla monomorfisia funktioita, jolloin eri tyypeille käytetään eri ohjelmakoodia.

Christopher Strachey erotteli epämuodollisesti kaksi polymorfismin päätyyppiä luentomuistiossa vuonna 1967. Luennot pidettiin aluksi muistiinpanoista ja artikkeli *Fundamental Concepts in Programming Languages* kirjoitettiin kurssin lopuksi. Stracheyn luokittelun *parametrinen polymorfismi* saadaan kun funktio toimii joukolla tyyppejä, joissa normaalisti on jokin sama yhteinen rakenne. *Ad-hoc polymorfismi* saadaan kun funktio toimii tai näyttää toimivan usealla eri tyypillä (joissa ei välttämättä ole yhteistä rakennetta) ja voi toimia toisistaan riippumattomilla tavoilla eri tyypeillä.

Cardellin ja Wegnerin luokittelu lisää uuden tyypin *liittävä polymorfismi* alatyypeille ja perinnälle. Liittävä polymorfismi on parametrisen polymorfismin kanssa toinen merkittävä alakategoria *universaalille polymorfismille*. Varhaisin esimerkki liittävästä polymorfismista on Simula 67. Ad-hoc polymorfismille on myös kaksi kategoriaa. *Ylikuormittavassa polymorfismissa* samaa muuttujanimeä käytetään osoittamaan eri funktioita ja kontekstista päätellään mitä funktiota osoitetaan nimen *instanssilla*. *Pakottava polymorfismi* on semanttinen operaatio, jota tarvitaan muuttamaan argumentti funktion odottamalle tyypille. Algol 68 on tunnettu tyypin pakottamisesta.

Ralf Lämmel ja Joost Visser esittävät artikkelissa *Type Combinators for Generic Traversal* polytyyppisen ohjelmoinnin käsitteen.

Myös rivipolymorfismia on kuvattu.

Lisäksi on myös Rank-polymorfismi, jota käytetään taulukko-ohjelmointikielissä ja se on jopa niiden määrittävä piirre.

Toteutustavat
-------------

### Staattinen ja dynaaminen polymorfismi

Polymorfismi voidaan erottaa siitä, milloin toteutus valitaan: staattisesti (käännösaikana) vai dynaamisesti (ajon aikana, tyypillisesti virtuaalisen funktion kautta). Tämä tunnetaan vastaavasti staattisena lähetyksenä ja dynaamisena lähetyksenä, ja vastaavia polymorfismin muotoja kutsutaan vastaavasti staattiseksi polymorfismiksi ja dynaamiseksi polymorfismiksi.

Staattinen polymorfismi suoritetaan nopeammin, koska dynaamista lähetystä ei ole, mutta se vaatii lisäkääntäjätukea. Lisäksi staattinen polymorfismi mahdollistaa suuremman staattisen analyysin kääntäjien (erityisesti optimointia varten), lähdekoodin analysointityökalujen ja ihmislukijoiden (ohjelmoijien) toimesta. Dynaaminen polymorfismi on joustavampaa, mutta hitaampaa – esimerkiksi dynaaminen polymorfismi mahdollistaa ankkakirjoituksen, ja dynaamisesti linkitetty kirjasto voi toimia objekteissa tietämättä niiden täyttä tyyppiä.

Staattista polymorfismia esiintyy tyypillisesti ad hoc -polymorfismissa ja parametrisissa polymorfismissa, kun taas dynaaminen polymorfismi on tavallista alatyyppipolymorfismissa. On kuitenkin mahdollista saavuttaa staattista polymorfismia alatyypeillä käyttämällä metaohjelmointia.

Katso myös
----------

* Tyyppijärjestelmä
* Myöhäinen ja varhainen sidonta

Lähteet
-------

1. ↑  Polymorphism *docs.oracle.com*. Viitattu 19.2.2020. (englanniksi)
2. ↑  Polymorphism *cplusplus.com*. Viitattu 19.2.2020. (englanniksi)
3. ↑  Bjarne Stroustrup's C++ Glossary *stroustrup.com*. Viitattu 22.2.2020. (englanniksi)
4. ↑  Glenn G. Chappell: CS 331 Spring 2018 A Primer on Type Systems *cs.uaf.edu*. Viitattu 22.2.2020. (englanniksi)
5. ↑  David Parsons: *Inheritance, Polymorphism, and Interfaces*, s. 159–195. London: Springer London, 2012. ISBN 978-1-4471-2478-8.
6. 1 2 3 4 5 6 7 8 9 10  Luca Cardelli & Peter Wegner: On Understanding Types, Data Abstraction, and Polymorphism (PDF) *lucacardelli.name*. doi:10.1145/6041.6042.  Viitattu 22.2.2020. (englanniksi)}
7. 1 2  Christopher Strachey: Fundamental Concepts in Programming Languages.  *Higher-Order and Symbolic Computation*, 2000, 13. vsk, nro 1/2, s. 11–49. doi:10.1023/a:1010000313106. ISSN 1388-3690.
8. ↑  Luca Cardelli, Peter Wegner: On understanding types, data abstraction, and polymorphism.  *ACM Computing Surveys*, 10.12.1985, 17. vsk, nro 4, s. 471–523. doi:10.1145/6041.6042. ISSN 0360-0300. Artikkelin verkkoversio.
9. ↑  Ralf Lämmel & Joost Visser: Type Combinators for Generic Traversal (PDF) *citeseerx.ist.psu.edu*.  elokuu 2001. Viitattu 4.2.2023. (englanniksi)
10. ↑  Row polymorphism (PDF) *cl.cam.ac.uk*. Viitattu 4.2.2023. (englanniksi)
11. ↑  Neel Krishnaswami: Objects and Aspects: Row Polymorphism (PDF) *cs.cmu.edu*. Viitattu 4.2.2023. (englanniksi)

Aiheesta muualla
----------------

* Polymorphic variants (englanniksi)