Genericiteit: verschil tussen versies

Uit Wikipedia, de vrije encyclopedie
Verwijderde inhoud Toegevoegde inhoud
k allerlei object/en/; geparametriz->seerd
Robbot (overleg | bijdragen)
k Robot-geholpen doorverwijzing: Ada
Regel 3: Regel 3:
Generiek programmeren ligt dicht tegen [[meta-programmeren]] aan, een techniek waarbij aan de hand van bepaalde broncode weer nieuwe broncode wordt geprogrammeerd, die daarna wordt gecompileerd. Bij generiek programmeren gaat het echter om een [[syntaxis|syntactische]] en [[semantiek|semantische]] uitbreiding in de [[programmeertaal]] en wordt er niet direct 'nieuwe' broncode gegenereerd.
Generiek programmeren ligt dicht tegen [[meta-programmeren]] aan, een techniek waarbij aan de hand van bepaalde broncode weer nieuwe broncode wordt geprogrammeerd, die daarna wordt gecompileerd. Bij generiek programmeren gaat het echter om een [[syntaxis|syntactische]] en [[semantiek|semantische]] uitbreiding in de [[programmeertaal]] en wordt er niet direct 'nieuwe' broncode gegenereerd.


Generiek programmeren werd rond 1970 onderdeel van een aantal programmeertalen, zoals [[CLU]], [[Ada]]. Later werd de techniek ook onderdeel van veel andere object-geöriëntieerde talen, zoals [[C++]], [[Eiffel]] en [[Java (programmeertaal)|Java]].
Generiek programmeren werd rond 1970 onderdeel van een aantal programmeertalen, zoals [[CLU]], [[Ada (programmeertaal)|Ada]]. Later werd de techniek ook onderdeel van veel andere object-geöriëntieerde talen, zoals [[C++]], [[Eiffel]] en [[Java (programmeertaal)|Java]].


== Voorbeelden van generiek programmeren ==
== Voorbeelden van generiek programmeren ==

Versie van 20 apr 2007 01:11

Generiek programmeren is een vorm van programmeren waarbij algoritmes worden geschreven in een bepaalde syntaxis waardoor de algoritmes adaptief zijn en kunnen worden geïnstantieerd door de compiler. Zo kunnen algoritmes generiek worden geschreven: een sorteeralgoritme hoeft zich niet bezig te houden met wat voor datatype het precies sorteert, maar alleen hoe het dat doet.

Generiek programmeren ligt dicht tegen meta-programmeren aan, een techniek waarbij aan de hand van bepaalde broncode weer nieuwe broncode wordt geprogrammeerd, die daarna wordt gecompileerd. Bij generiek programmeren gaat het echter om een syntactische en semantische uitbreiding in de programmeertaal en wordt er niet direct 'nieuwe' broncode gegenereerd.

Generiek programmeren werd rond 1970 onderdeel van een aantal programmeertalen, zoals CLU, Ada. Later werd de techniek ook onderdeel van veel andere object-geöriëntieerde talen, zoals C++, Eiffel en Java.

Voorbeelden van generiek programmeren

Geparametriseerde klasse

Een veelgebruikte toepassing van generiek programmeren is het schrijven van 'container'-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++:

template<typename T> class List { 
  /* standaard lijst logica */
};
List<Animal> listOfAnimals;
List<Car> listOfCars;

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:

template<typename T> T void highest(const T& a, const T& b) {
    if(a>b) {
        return a;
    }
    else {
        return b;
    }
}

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:

int x = 10;
int y = 50;
int z = highest(x,y);

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 ints 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 Comparable, die een methode compare definieert:

interface Comparable {
    public int compare(Object b);
}
public class Integer implements Comparable {
    private int value;
    
    public int compare(Object b) {
         return value > (Integer)b;
   }
}

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):

public int compare(Object b) {
    if(!(b instanceof Integer)) throw
                      new IllegalArgumentException("Parameter b heeft een verkeerd type");
    return value > (Integer)b;
}

Met generiek programmeren kan dit probleem op een nette manier opgelost worden:

interface Comparable<T> {
    public int compare(T b);
}
public class Integer implements Comparable<Integer> {
    private int value;
    
    public int compare(Integer b) {
         return value > b;
   }
}

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.