Genericiteit: verschil tussen versies

Naar navigatie springen Naar zoeken springen
108 bytes toegevoegd ,  7 maanden geleden
k
Bot: Replace deprecated <source> tag
k (Bot: Replace deprecated <source> tag)
=== Geparametriseerde klasse ===
Een veelgebruikte toepassing van generiek programmeren is het schrijven van 'container'-[[klasse (informatica)|klassen]], waarin allerlei objecten kunnen worden opgeslagen. Tijdens het schrijven van de container (bijvoorbeeld een lijst, een [[hashtable]] of een [[associatieve array]]) hoeft het ''type'' object dat wordt opgeslagen niet bekend te zijn. Een voorbeeld in C++:
<sourcesyntaxhighlight lang=cpp>
template<typename T>
class List
List<Animal> listOfAnimals;
List<Car> listOfCars;
</syntaxhighlight>
</source>
In de hierboven geschetste 'List'-klasse wordt het te gebruiken type ''T'' genoemd tijdens de definitie van de lijst-klasse, en wordt deze door de compiler als het ware gesubstitueerd door ''Animal'' of ''Car'' op het moment dat deze de typenaam ''List<Animal>'' tegenkomt.
 
=== Geparametriseerde functie ===
Een voorbeeld van een generiek algoritme in C++ is het volgende:
<sourcesyntaxhighlight lang=cpp>
template<typename T>
T& highest(const T& a, const T& b)
return b;
}
</syntaxhighlight>
</source>
Hierbij is nog niet bekend wat het ''type'' is van de parameters ''a'' en ''b'', maar wordt wel het algoritme beschreven. Als we bovenstaande functie willen gebruiken voor getallen, dan kan dat simpelweg zo:
<sourcesyntaxhighlight lang=cpp>
int x = 10;
int y = 50;
int z = highest(x,y);
</syntaxhighlight>
</source>
Waarbij ''z'' de waarde 50 zal krijgen. Uit de gegeven parameters (''x'' en ''y'', allebei ''int'', geheel getal) leidt de compiler het type voor de ''generieke parameter'' ''T'' af. Als in plaats van twee ''int''s bijvoorbeeld een ''string'' en een ''float'' als parameter worden gegeven kan de compiler geen type T bepalen: het type van de eerste en tweede parameter moet namelijk gelijk zijn (of converteerbaar naar een gemeenschappelijke T).
 
=== Geparametriseerde superklasse ===
Een derde manier van generiek programmeren die vaak wordt toegepast (in Java en C++) is het parametrizeren van de superklasse. Stel, we hebben een [[Interface (Java)|interface]] ''Comparable'', die een [[Methodes en technieken in de informatica|methode]] ''compare'' definieert:
<sourcesyntaxhighlight lang=java>
interface Comparable {
public int compare(Object b);
}
}
</syntaxhighlight>
</source>
De ''compare''-methode kan nu alle objecten vergelijken die subklassen zijn van ''Object'' (In Java zijn alle klassen dat). Als de parameter ''b'' van type ''Integer'' is, gaat de vergelijking goed. Het probleem is alleen dat het mogelijk is voor ''b'' een instantie van een compleet ander type dan Integer te geven. De methode zal dus moeten controleren of ''b'' van het juiste type is (namelijk Integer):
<sourcesyntaxhighlight lang=java>
public int compare(Object b)
{
throw new IllegalArgumentException("Parameter b heeft een verkeerd type");
}
</syntaxhighlight>
</source>
 
Met generiek programmeren kan dit probleem op een nette manier opgelost worden:
 
<sourcesyntaxhighlight lang=java>
interface Comparable<T> {
public int compare(T b);
}
}
</syntaxhighlight>
</source>
Nu is de interface, ''Comparable'', generiek gemaakt. Integer implementeert niet zomaar ''Comparable'', maar implementeert ''Comparable<Integer>''. Alle ''T'''s in de definitie van Comparable worden gesubstitueerd door ''Integer''. Het type van parameter ''b'' kan nu tijdens het compileren worden gecontroleerd, en er kan ''at-runtime'' geen fout meer optreden door het gebruik van een verkeerd type. Omdat de superklasse van ''Integer'' geparametriseerd is met Integer zelf, spreken we van een ''geparametriseerde superklasse''.
 
325.758

bewerkingen

Navigatiemenu