Полиморфизам (рачунарство)
У програмским језицима, полиморфизам (грч. πολύς, што значи "много" и грч. μορφή, што значи „форма, облик“) представља обезбеђивање јединственог интерфејса према ентитетима различитих типова.[1] Полиморфни тип је онај тип чије се операције могу применити на вредности неког другог типа или више типова.[2] Постоји неколико фундаментално различитих типова полиморфизма:
- Ад-хок полиморфизам: почива на особини неких програмских језика да допуштају вишезначност имена функција и оператора (енгл. overloading).
- Параметарски полиморфизам: када је код написан без помињања било ког специфичног типа и стога га може користити већи број нових типова. Унутар заједнице објектно-оријентисаног програмирања, овај вид полиморфизма је познат као генеричко програмирање, док се у функционалном програмирању користи термин "полиморфизам".
- Хијерархијски полиморфизам (познат и као полиморфизам подтипова): када име означава инстанце различитих класа повезаних неком заједничком надкласом.[3] У објектно-оријентисаном програмирању, ово се често назива једноставан полиморфизам.
- Имплицитни полиморфизам: карактеристичан је за функционалне језичке парадигме. Представља уопштење параметарског полиморфизма. Дозвољава писање кода без навођења типова. Типови се одређују у фази извршавања.
Историја
[уреди | уреди извор]Ад-хок полиморфизам и параметарски полиморфизам су првобитно описани у низу предавања, Основни концепти програмских језика, које је 1967. године забележио британски програмер Кристофер Стрејчи.[4] Године 1985. Петер Вегнер и Лука Кардели су увели појам укључивања полиморфизма у модел подтипова и наслеђивања.[2] Међутим, имплементације полиморфизма подтипова и наслеђивања воде порекло од појма "инклузија полиморфизма", након што се појавио програмски језик Симула 1967. године.
Типови полиморфизма
[уреди | уреди извор]Ад-хок полиморфизам
[уреди | уреди извор](познат као преоптерећење функције). Термин "ад-хок" упућује на то да овај тип полиморфизма није основно обележје типа система. У програмском језику Паскал на пример, функција Add
наизглед ради генерички са више врста типова када се гледају само позиви, али у ствари представља потпуно различите функцијеКристофер Стрејчи[4] је изабрао термин ад-хок полиморфизам да означи полиморфне функције које се могу применити на аргументе различитих типова, али које се понашају другачије у зависности од типа аргумента на који се примењују (такође из перспективе компајлера у сваком смислу:
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.
У динамички типизираним језицима ситуација може бити доста сложенија, јер исправна функција коју треба позвати може бити одређена једино у току извршавања.
Имплицитна конверзија се такође дефинише као облик полиморфизма, и назива се принудан полиморфизам.[2][5]
Параметарски полиморфизам
[уреди | уреди извор]Параметарски полиморфизам почива на употреби тзв. типских променљивих. Типске променљиве се користе за симболичко означавање типова вредности, променљивих и израза. Сваки пут када се употреби код, који је написан уз употребу параметарског полиморфизма, симбилички типови (типске променљиве) се замењују конкретним типовима и програм се преводи у неполиморфном облику. Да би превођење било успешно, неопходно је да у свим деловима тог полиморфног кода замењивање симболичких типова конкретним типовима производи исправан програмски код. Ако то није случај, тј. ако је за конкретан тип изабран неки тип за који дати програмски код није исправан, онда ће преводилац пријавити грешку.
Одређивање конкретних типова се може изводити експлицитно, навођењем типа, или имплицитно, на основу правила превођења конкретног програмског језика.[6]
Параметарски полиморфизам је свеприсутан у функционалном програмирању, где се често једноставно назива "полиморфизам". Следећи пример у Хаскелу показује параметризован тип листе података и две параметарски полиморфне функције тих података:
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)
Подршка за параметарски полиморфизам постоји и у неколико објектно-оријентисаних језика. На пример, подршка за параметарски полиморфизам у програмском језику Ц++ и Д је имплементирана кроз концепт шаблона функција и класа. Шаблон функције представља функцију у којој се употребљава неки параметарски (симболички) тип. Слично, шаблон класе је дефиниција класе која почива на употреби једног или више симболичких типова:
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) {
...
}
Џон Ч. Рејнолдс (и касније Жан-Ив Жирар) је формално развио појам полиморфизма као проширење ламбда рачуна (који се зове полиморфни ламбда рачун или Систем Ф). Било која параметарски полиморфна функција је нужно ограничена, радећи на типовима података уместо на њиховим вредностима, што је довело до концепта параметризације.
Хијерархијски полиморфизам
[уреди | уреди извор]Хијерархијски полиморфизам користи успостављене хијерархијске односе надтип и подтип међу класама као средство остваривања полиморфизма. Он је последица особине објектно-оријентисаних програмских језика да програмски код, који је написан да ради са објектима једне класе, може да ради и са објектима свих њених поткласа. Нпр. функција написана тако да узима објекат одређеног типа Т, али да исправно ради и уколико јој се пошаље објекат који припада типу С који је подтип типа Т (по принципу супституције који је формулисала Лисков ). Овај тип односа се понекад означава као C<:Т. С друге стране, каже се да је Т супертип од С, означавамо Т:>С. Подтип полиморфизма се обично решава динамички (види доле).
У следећем примеру су авиони, бродови и аутомобили подтипови превозног средства. Процедура ispisiMesto() прихвата превозно средство, али ће исправно радити и ако се преноси подтип:
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());
}
На пример, ако су Number
, Rational
, и Integer
типови такви да Number
:> Rational
и Number
:> Integer
, функција која као аргумент прима Number
ће радити једнако добро када прима Integer
или Rational
. Стварни тип објекта може бити скривен од стране клијената у црну кутију, и приступа му се преко објекта идентитета. У ствари, ако је тип Number
апстрактан, можда неће ни бити могуће приступити објекту чија је већина пореклом од типа Number
. Ова врста хијерархије типа је позната - нарочито у контексту Шема програмског језика-као нумерички торањ, и обично садржи још много типова.
Објектно-оријентисани језици почивају на концептима класе и наслеђивања класа. Наслеђивање класа није ништа друго до декларисање да једна класа представља специјалан случај (или поткласу) друге класе, тј. да друга класа представља уопштење (тј. наткласу) прве класе. Релација поткласа је специјалан случај релације подтип, а релација наткласа специјалан случај релације надтип.[6]
Имплицитни полиморфизам
[уреди | уреди извор]Имплицитни полиморфизам подразумева да се при писању кода уопште не наводе типови вредности и израза. Претпоставља се да ће преводилац анализирати сваки конкретан сегмент програмског кода и сам закључити за које типове може да се преводе. Ако неки део кода може успешно да се преведе за више различитих типова, онда се преводи и користи као полиморфан део кода.
Имплицитни полиморфизам се користи у великом броју динамичких програмских језика, код којих се проверавање типова (а тиме и проверавање исправности кода) одлаже до фазе извршавања програма (на пример Лисп), али и код значајног броја програмских језика код којих се статичком провером типова у фази превођења тачно установљава (потенцијално полиморфан) тип сваког израза у коду.
Нпр. макрои програмског језика Ц представљају специфичан вид имплицитног полиморфизма. На пример, ако напишемо макро max
:
#define max(x,y) ((x)>(y) ? (x) : (y))
онда написани макро можемо да употребимо за израчунавање већег од два аргумента за било које типове података за које је дефинисан оператор поређења „>“.[6]
Аспекти имплементације
[уреди | уреди извор]Статички и динамички полиморфизам
[уреди | уреди извор]Полиморфизми се могу разликовати према томе која је имплементација изабрана - статично (у време компајлирања) или динамично (у време извршавања, обично преко виртуелне функције). Ово је познатије као статичко и динамичко спајање, а одговарајући облици полиморфизма се у складу са тим називају статички полиморфизам и динамички полиморфизам.
Статички полиморфизам се извршава брже, али захтева додатну подршку компајлера. Статички полиморфизам омогућава већу статичку анализу: приликом компајлирања (посебно за оптимизацију), анализу изворног кода и анализу коју врше програмери. Динамички полиморфизам је флексибилнији, али спорији - на пример, динамички полиморфизам омогућава кодирање без експлицитно декларисаних типова (енгл. duck typing), а динамички повезане библиотеке омогућавају њихово коришћење над објектима без познавања њиховог пуног садржаја.
Статички полиморфизам се обично јавља у ад-хоку и параметарском полиморфизму, док је динамички полиморфизам уобичајен за подтипизирани полиморфизам. Међутим, могуће је користити статички полиморфизам са подтипизираним полиморфизмом помоћу софистицираних употреба шаблона метапрограмирања.
Референце
[уреди | уреди извор]- ^ Stroustrup, Bjarne (19. 2. 2007). „Bjarne Stroustrup's C++ Glossary”.
- ^ а б в Cardelli, Luca; Wegner, Peter (децембар 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.
- ^ а б C. Strachey – Fundamental Concepts in Programming Languages http://www.itu.dk/courses/BPRD/E2009/fundamental-1967.pdf Архивирано на сајту Wayback Machine (12. август 2017)
- ^ Tucker, Allen B. (2004). Computer Science Handbook, Second Edition. Taylor & Francis. стр. 91. ISBN 978-1-58488-360-9.
- ^ а б в 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[мртва веза]