Arv (programmering)

Från Wikipedia
(Omdirigerad från Multipelt arv)
Hoppa till: navigering, sök

Arv (eng. inheritance) är ett av grundkoncepten inom objektorienterad programmering. Arv går ut på att det går att relatera olika klasser av objekt enligt en arvsprincip. Med arv så ärver subklassen (även kallad härledd klass, eng. derived class) alla egenskaper och färdigheter som definierats för superklassen (även kallad basklass). Genom arv så bygger man upp en slags logisk hierarki mellan klasserna.

Ett konkret exempel är följande. Föreställ er en klass som beskriver ett Fordon (ett fordon som har x antal hjul, som det går att använda till att färdas med och så vidare). Exempel på fordon är bilar, cyklar, motorcyklar. Då kan vi göra skilda klasser Bil, Cykel, Motorcykel som alla ärver de gemensamma egenskaper från Fordon-klassen.

Man pratar om superklass och subklass, där superklassen i vårt exempel är Fordon och subklasser är Bil, Cykel, Motorcykel. Genom arv så får Bilen alla egenskaper som gäller för Fordon överlag, det vill säga bilen får automatiskt egenskapen x antal hjul (vilket sedan kan specificeras till 4, 6 eller hur många som helst) samt att det ska gå att färdas med en bil.

En tumregel för hur man kan föreställa sig arv inom programmering är att uttala relationen som:

(subklassen) är en/ett (superklass), exempelvis att Cykeln är ett Fordon.

Multipelt arv[redigera | redigera wikitext]

Begreppet multipelt arv har sin grund i objektorienterad programmering och syftar till att en klass kan ärva egenskaper från flera andra klasser samtidigt.

Det mest kända och populära språket som tillåter multipelt arv är C++. Här kan man kombinera olika klasser för att skapa en ny. Ett klassiskt exempel är varelsen Kentaur från den grekiska mytologin, som representerar både en häst och en människa. För att uppnå den önskade effekten är det lägligt att använda sig av multipelt arv och låta Kentaur dra nytta av egenskaperna från både klassen Häst och klassen Människa samtidigt.

Den praktiska användningen av multipelt arv visade på svårigheterna, främst för programmeraren att överblicka effekterna av koden. Ett exempel är ovan, om både Häst och Människa ärver klassen Däggdjur. Då kommer Kentaur att innehålla två instanser av däggdjur, modifierade på lite olika sätt av Häst resp Människa, så vissa operationer kan bli oklart definierade, eller framför allt svåra att överblicka. Och det blir inte alltid lätt för kompilatorn att lägga ut effektiv kod för det som i C++ kallas virtuella metoder.

Därför tillämpar man i till exempel Java, enkelt arv, med tillägg av så kallade interface. Interface kan formellt ses som en klass ovan, men får inte innehålla egen kod. All sådan kod måste ligga i klasser som definierar koden. I exemplet ovan kan man då definiera interfacen

  • IDäggdjur - beskriver vilka metoder ett däggdjur har (men har igen kod)
  • IHäst - ärver IDäggdjur och beskriver vilka metoder en häst har

samt klasserna

  • CDäggdjur implementerar IDäggdjur
  • CHäst ärver CDäggdjur och implementerar IHäst
  • CMänniska ärver CDäggdjur
  • CKentaur ärver CMänniska och implementerar IHäst

CKentaur och CHäst kommer på detta vis innehålla en del kod i duplikat. Fördelen är att det är tydligt att så är fallet. Användningen av denna struktur är sedan lika enkel som den är vid implementering med multipelt arv.

Begreppet Interface beskriver också en annan princip. I större projekt är det viktigt att skilja på gränssnitt (interface) och implementering; gränssnitt för en modul bör vara mindre förändringssutsatt, och väl beskriven. Implementeringar av dessa däremot är ofta utsatta för förändringar. Det är då en fördel med ett språk som tydligare än C++ anger vad som är gränssnitt (interface) och implementering (klass). Interface kan (nästan alltid) implementeras med hjälp av abstrakta klasser i C++.