Genericiteit: verschil tussen versies

54 bytes toegevoegd ,  12 jaar geleden
Broncodes opgeschoond en opgevrolijkt
(Broncodes opgeschoond en opgevrolijkt)
=== 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) hoeft het ''type'' object dat wordt opgeslagen niet bekend te zijn. Een voorbeeld in C++:
<source lang=cpp>
 
template<typename T> class List {
{
/*/ standaard lijst logica */
};
List<Animal> listOfAnimals;
List<CarAnimal> listOfCarslistOfAnimals;
List<Car> listOfCars;
</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:
<source lang=cpp>
 
template<typename T> T void highest(const T& a, const T& b) {
T& highest(const T& a, const T& b)
if(a>b) {
{
return a;
if(a > }b)
return else {a;
else
return b;
return }b;
}
</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:
<source lang=cpp>
 
int x = 10;
int y = 50;
int z = highest(x,y);
</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:
<source lang=java>
interface Comparable<T> {
public int compare(TObject b);
}
 
interfacepublic class Integer implements Comparable {
publicprivate int compare(Object b)value;
}
 
public class Integer implements Comparable {
private int value;
public int compare(Object b) {
{
return value > (Integer) b;
}
}
}
 
</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):
<source lang=java>
 
public int compare(Object b) {
{
if(!(b instanceof Integer)) throw
new IllegalArgumentException("Parameter b heeft een verkeerd type");
return value > (Integer) b;
else
}
throw new IllegalArgumentException("Parameter b heeft een verkeerd type");
}
</source>
 
Met generiek programmeren kan dit probleem op een nette manier opgelost worden:
 
<source lang=java>
interface Comparable<T> {
interface Comparable<T> {
public int compare(T b);
public int compare(T b);
}
}
 
public class Integer implements Comparable<Integer> {
{
private int value;
private int value;
public int compare(Integer b) {
{
return value > b;
}
}
}
 
</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''.
 
2.096

bewerkingen