Polimorfizam (računarstvo)
U programskim jezicima, polimorfizam (grč. πολύς, što znači "mnogo" i grč. μορφή, što znači „forma, oblik“) predstavlja obezbeđivanje jedinstvenog interfejsa prema entitetima različitih tipova.[1] Polimorfni tip je onaj tip čije se operacije mogu primeniti na vrednosti nekog drugog tipa ili više tipova.[2] Postoji nekoliko fundamentalno različitih tipova polimorfizma:
- Ad-hok polimorfizam: počiva na osobini nekih programskih jezika da dopuštaju višeznačnost imena funkcija i operatora (engl. overloading).
- Parametarski polimorfizam: kada je kod napisan bez pominjanja bilo kog specifičnog tipa i stoga ga može koristiti veći broj novih tipova. Unutar zajednice objektno-orijentisanog programiranja, ovaj vid polimorfizma je poznat kao generičko programiranje, dok se u funkcionalnom programiranju koristi termin "polimorfizam".
- Hijerarhijski polimorfizam (poznat i kao polimorfizam podtipova): kada ime označava instance različitih klasa povezanih nekom zajedničkom nadklasom.[3] U objektno-orijentisanom programiranju, ovo se često naziva jednostavan polimorfizam.
- Implicitni polimorfizam: karakterističan je za funkcionalne jezičke paradigme. Predstavlja uopštenje parametarskog polimorfizma. Dozvoljava pisanje koda bez navođenja tipova. Tipovi se određuju u fazi izvršavanja.
Istorija
urediAd-hok polimorfizam i parametarski polimorfizam su prvobitno opisani u nizu predavanja, Osnovni koncepti programskih jezika, koje je 1967. godine zabeležio britanski programer Kristofer Strejči.[4] Godine 1985. Peter Vegner i Luka Kardeli su uveli pojam uključivanja polimorfizma u model podtipova i nasleđivanja.[2] Međutim, implementacije polimorfizma podtipova i nasleđivanja vode poreklo od pojma "inkluzija polimorfizma", nakon što se pojavio programski jezik Simula 1967. godine.
Tipovi polimorfizma
urediAd-hok polimorfizam
uredi(poznat kao preopterećenje funkcije). Termin "ad-hok" upućuje na to da ovaj tip polimorfizma nije osnovno obeležje tipa sistema. U programskom jeziku Paskal na primer, funkcija Add
naizgled radi generički sa više vrsta tipova kada se gledaju samo pozivi, ali u stvari predstavlja potpuno različite funkcijeKristofer Strejči[4] je izabrao termin ad-hok polimorfizam da označi polimorfne funkcije koje se mogu primeniti na argumente različitih tipova, ali koje se ponašaju drugačije u zavisnosti od tipa argumenta na koji se primenjuju (takođe iz perspektive kompajlera u svakom smislu:
program Adhoc;
function Add( x, y : Integer ) : Integer;
begin
Add := x + y
end;
function Add( s, t : String ) : String;
begin
Add := Concat( s, t )
end;
begin
Writeln(Add(1, 2)); (* Ispisuje "3" *)
Writeln(Add('ZDRAVO, ', 'SVETE!')); (* Ispisuje "ZDRAVO, SVETE!" *)
end.
U dinamički tipiziranim jezicima situacija može biti dosta složenija, jer ispravna funkcija koju treba pozvati može biti određena jedino u toku izvršavanja.
Implicitna konverzija se takođe definiše kao oblik polimorfizma, i naziva se prinudan polimorfizam.[2][5]
Parametarski polimorfizam
urediParametarski polimorfizam počiva na upotrebi tzv. tipskih promenljivih. Tipske promenljive se koriste za simboličko označavanje tipova vrednosti, promenljivih i izraza. Svaki put kada se upotrebi kod, koji je napisan uz upotrebu parametarskog polimorfizma, simbilički tipovi (tipske promenljive) se zamenjuju konkretnim tipovima i program se prevodi u nepolimorfnom obliku. Da bi prevođenje bilo uspešno, neophodno je da u svim delovima tog polimorfnog koda zamenjivanje simboličkih tipova konkretnim tipovima proizvodi ispravan programski kod. Ako to nije slučaj, tj. ako je za konkretan tip izabran neki tip za koji dati programski kod nije ispravan, onda će prevodilac prijaviti grešku.
Određivanje konkretnih tipova se može izvoditi eksplicitno, navođenjem tipa, ili implicitno, na osnovu pravila prevođenja konkretnog programskog jezika.[6]
Parametarski polimorfizam je sveprisutan u funkcionalnom programiranju, gde se često jednostavno naziva "polimorfizam". Sledeći primer u Haskelu pokazuje parametrizovan tip liste podataka i dve parametarski polimorfne funkcije tih podataka:
data List a = Nil | Cons a (List a)
length :: List a -> Integer
length Nil = 0
length (Cons x xs) = 1 + length xs
map :: (a -> b) -> List a -> List b
map f Nil = Nil
map f (Cons x xs) = Cons (f x) (map f xs)
Podrška za parametarski polimorfizam postoji i u nekoliko objektno-orijentisanih jezika. Na primer, podrška za parametarski polimorfizam u programskom jeziku C++ i D je implementirana kroz koncept šablona funkcija i klasa. Šablon funkcije predstavlja funkciju u kojoj se upotrebljava neki parametarski (simbolički) tip. Slično, šablon klase je definicija klase koja počiva na upotrebi jednog ili više simboličkih tipova:
class List<T> {
class Node<T> {
T elem;
Node<T> next;
}
Node<T> head;
int length() { ... }
}
List<B> map(Func<A,B> f, List<A> xs) {
...
}
Džon Č. Rejnolds (i kasnije Žan-Iv Žirar) je formalno razvio pojam polimorfizma kao proširenje lambda računa (koji se zove polimorfni lambda račun ili Sistem F). Bilo koja parametarski polimorfna funkcija je nužno ograničena, radeći na tipovima podataka umesto na njihovim vrednostima, što je dovelo do koncepta parametrizacije.
Hijerarhijski polimorfizam
urediHijerarhijski polimorfizam koristi uspostavljene hijerarhijske odnose nadtip i podtip među klasama kao sredstvo ostvarivanja polimorfizma. On je posledica osobine objektno-orijentisanih programskih jezika da programski kod, koji je napisan da radi sa objektima jedne klase, može da radi i sa objektima svih njenih potklasa. Npr. funkcija napisana tako da uzima objekat određenog tipa T, ali da ispravno radi i ukoliko joj se pošalje objekat koji pripada tipu S koji je podtip tipa T (po principu supstitucije koji je formulisala Liskov ). Ovaj tip odnosa se ponekad označava kao C<:T. S druge strane, kaže se da je T supertip od S, označavamo T:>S. Podtip polimorfizma se obično rešava dinamički (vidi dole).
U sledećem primeru su avioni, brodovi i automobili podtipovi prevoznog sredstva. Procedura ispisiMesto() prihvata prevozno sredstvo, ali će ispravno raditi i ako se prenosi podtip:
abstract class PrevoznoSredstvo {
abstract String mestoOdvijanjaSaobracaja();
}
class Avion extends PrevoznoSredstvo {
String mestoOdvijanjaSaobracaja() {
return "Vazduh!";
}
}
class Brod extends PrevoznoSredstvo {
String mestoOdvijanjaSaobracaja() {
return "Voda!";
}
}
class Automobil extends PrevoznoSredstvo {
String mestoOdvijanjaSaobracaja() {
return "Kopno!";
}
}
void ispisiMesto(PrevoznoSredstvo a) {
println(a.mestoOdvijanjaSaobracaja());
}
int main() {
ispisiMesto(new Avion());
ispisiMesto(new Brod());
ispisiMesto(new Automobil());
}
Na primer, ako su Number
, Rational
, i Integer
tipovi takvi da Number
:> Rational
i Number
:> Integer
, funkcija koja kao argument prima Number
će raditi jednako dobro kada prima Integer
ili Rational
. Stvarni tip objekta može biti skriven od strane klijenata u crnu kutiju, i pristupa mu se preko objekta identiteta. U stvari, ako je tip Number
apstraktan, možda neće ni biti moguće pristupiti objektu čija je većina poreklom od tipa Number
. Ova vrsta hijerarhije tipa je poznata - naročito u kontekstu Šema programskog jezika-kao numerički toranj, i obično sadrži još mnogo tipova.
Objektno-orijentisani jezici počivaju na konceptima klase i nasleđivanja klasa. Nasleđivanje klasa nije ništa drugo do deklarisanje da jedna klasa predstavlja specijalan slučaj (ili potklasu) druge klase, tj. da druga klasa predstavlja uopštenje (tj. natklasu) prve klase. Relacija potklasa je specijalan slučaj relacije podtip, a relacija natklasa specijalan slučaj relacije nadtip.[6]
Implicitni polimorfizam
urediImplicitni polimorfizam podrazumeva da se pri pisanju koda uopšte ne navode tipovi vrednosti i izraza. Pretpostavlja se da će prevodilac analizirati svaki konkretan segment programskog koda i sam zaključiti za koje tipove može da se prevode. Ako neki deo koda može uspešno da se prevede za više različitih tipova, onda se prevodi i koristi kao polimorfan deo koda.
Implicitni polimorfizam se koristi u velikom broju dinamičkih programskih jezika, kod kojih se proveravanje tipova (a time i proveravanje ispravnosti koda) odlaže do faze izvršavanja programa (na primer Lisp), ali i kod značajnog broja programskih jezika kod kojih se statičkom proverom tipova u fazi prevođenja tačno ustanovljava (potencijalno polimorfan) tip svakog izraza u kodu.
Npr. makroi programskog jezika C predstavljaju specifičan vid implicitnog polimorfizma. Na primer, ako napišemo makro max
:
#define max(x,y) ((x)>(y) ? (x) : (y))
onda napisani makro možemo da upotrebimo za izračunavanje većeg od dva argumenta za bilo koje tipove podataka za koje je definisan operator poređenja „>“.[6]
Aspekti implementacije
urediStatički i dinamički polimorfizam
urediPolimorfizmi se mogu razlikovati prema tome koja je implementacija izabrana - statično (u vreme kompajliranja) ili dinamično (u vreme izvršavanja, obično preko virtuelne funkcije). Ovo je poznatije kao statičko i dinamičko spajanje, a odgovarajući oblici polimorfizma se u skladu sa tim nazivaju statički polimorfizam i dinamički polimorfizam.
Statički polimorfizam se izvršava brže, ali zahteva dodatnu podršku kompajlera. Statički polimorfizam omogućava veću statičku analizu: prilikom kompajliranja (posebno za optimizaciju), analizu izvornog koda i analizu koju vrše programeri. Dinamički polimorfizam je fleksibilniji, ali sporiji - na primer, dinamički polimorfizam omogućava kodiranje bez eksplicitno deklarisanih tipova (engl. duck typing), a dinamički povezane biblioteke omogućavaju njihovo korišćenje nad objektima bez poznavanja njihovog punog sadržaja.
Statički polimorfizam se obično javlja u ad-hoku i parametarskom polimorfizmu, dok je dinamički polimorfizam uobičajen za podtipizirani polimorfizam. Međutim, moguće je koristiti statički polimorfizam sa podtipiziranim polimorfizmom pomoću sofisticiranih upotreba šablona metaprogramiranja.
Reference
uredi- ^ Stroustrup, Bjarne (19. 2. 2007). „Bjarne Stroustrup's C++ Glossary”.
- ^ a b v Cardelli, Luca; Wegner, Peter (decembar 1985). „On understanding types, data abstraction, and polymorphism” (PDF). New York, NY, USA.
- ^ Booch, et al 2007 Object-Oriented Analysis and Design with Applications. Addison-Wesley.
- ^ a b C. Strachey – Fundamental Concepts in Programming Languages http://www.itu.dk/courses/BPRD/E2009/fundamental-1967.pdf Arhivirano na sajtu Wayback Machine (12. avgust 2017)
- ^ Tucker, Allen B. (2004). Computer Science Handbook, Second Edition. Taylor & Francis. str. 91. ISBN 978-1-58488-360-9.
- ^ a b v S.Malkov-Odlomak iz knjige Razvoj softvera http://poincare.matf.bg.ac.rs/~smalkov/files/rs.r290.2015/public/Predavanja/Razvoj%20softvera.2014.06%20-%20Parametarski%20polimorfizam.pdf[mrtva veza]