Полиморфизам (рачунарство)У програмским језицима, полиморфизам (грч. πολύς, што значи "много" и грч. μορφή, што значи „форма, облик“) представља обезбеђивање јединственог интерфејса према ентитетима различитих типова.[1] Полиморфни тип је онај тип чије се операције могу применити на вредности неког другог типа или више типова.[2] Постоји неколико фундаментално различитих типова полиморфизма:
ИсторијаАд-хок полиморфизам и параметарски полиморфизам су првобитно описани у низу предавања, Основни концепти програмских језика, које је 1967. године забележио британски програмер Кристофер Стрејчи.[4] Године 1985. Петер Вегнер и Лука Кардели су увели појам укључивања полиморфизма у модел подтипова и наслеђивања.[2] Међутим, имплементације полиморфизма подтипова и наслеђивања воде порекло од појма "инклузија полиморфизма", након што се појавио програмски језик Симула 1967. године. Типови полиморфизмаАд-хок полиморфизам(познат као преоптерећење функције). Термин "ад-хок" упућује на то да овај тип полиморфизма није основно обележје типа система. У програмском језику Паскал на пример, функција 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());
}
На пример, ако су Објектно-оријентисани језици почивају на концептима класе и наслеђивања класа. Наслеђивање класа није ништа друго до декларисање да једна класа представља специјалан случај (или поткласу) друге класе, тј. да друга класа представља уопштење (тј. наткласу) прве класе. Релација поткласа је специјалан случај релације подтип, а релација наткласа специјалан случај релације надтип.[6] Имплицитни полиморфизамИмплицитни полиморфизам подразумева да се при писању кода уопште не наводе типови вредности и израза. Претпоставља се да ће преводилац анализирати сваки конкретан сегмент програмског кода и сам закључити за које типове може да се преводе. Ако неки део кода може успешно да се преведе за више различитих типова, онда се преводи и користи као полиморфан део кода.
Нпр. макрои програмског језика Ц представљају специфичан вид имплицитног полиморфизма. На пример, ако напишемо макро
онда написани макро можемо да употребимо за израчунавање већег од два аргумента за било које типове података за које је дефинисан оператор поређења „>“.[6] Аспекти имплементацијеСтатички и динамички полиморфизамПолиморфизми се могу разликовати према томе која је имплементација изабрана - статично (у време компајлирања) или динамично (у време извршавања, обично преко виртуелне функције). Ово је познатије као статичко и динамичко спајање, а одговарајући облици полиморфизма се у складу са тим називају статички полиморфизам и динамички полиморфизам. Статички полиморфизам се извршава брже, али захтева додатну подршку компајлера. Статички полиморфизам омогућава већу статичку анализу: приликом компајлирања (посебно за оптимизацију), анализу изворног кода и анализу коју врше програмери. Динамички полиморфизам је флексибилнији, али спорији - на пример, динамички полиморфизам омогућава кодирање без експлицитно декларисаних типова (енгл. duck typing), а динамички повезане библиотеке омогућавају њихово коришћење над објектима без познавања њиховог пуног садржаја. Статички полиморфизам се обично јавља у ад-хоку и параметарском полиморфизму, док је динамички полиморфизам уобичајен за подтипизирани полиморфизам. Међутим, могуће је користити статички полиморфизам са подтипизираним полиморфизмом помоћу софистицираних употреба шаблона метапрограмирања. Референце
|
Portal di Ensiklopedia Dunia