Skip to content

Generic

In OOP kennen we de volgende principes:

  • Er zijn verschillende “standaard” types zoals nummers, strings, booleans etc.
  • Classes beschrijven welke attributen en methodes objecten hebben.
  • Objecten zijn instanties van classes.
  • De meeste object georiënteerde talen eisen dat je overal aangeeft van wat voor type (of class) iets is.
  • Denk daarbij aan de return value van een methode, de parameters van een methode en de attributen in de class.

Dit aangeven van wat voor type iets is levert soms een hoop overhead op. Dit is zeker het geval als je twee methodes hebt die hetzelfde doen en eigenlijk alleen verschillende zijn in het type objecten die ze teruggeven. Om dit overhead probleem op te lossen zijn generics geïntroduceerd.

Het doel van een generic

Generics zorgen ervoor dat je stukjes code (componenten) op verschillende plaatsen kan gebruiken omdat ze onafhankelijk zijn van de gebruikte types. Hierdoor wordt je code flexibelere en efficiënter (minder dubbele code en beter herbruikbare stukken).

Types van de parameters en return values in je generic classes zijn afhankelijk van hoe je het object hebt gedeclareerd. Dus in je class geef je aan dat je het type van bepaalde attributen nog niet weet. Op het moment dat je een object van de class declareert geef je aan wat het type van dit attribuut zal zijn.

Bekende voorbeelden

Als je met TS hebt gewerkt heb je waarschijnlijk al gebruik gemaakt van generics. Zie bijvoorbeeld de onderstaande code

async function authenticateAtBackend(username: string, password: string): Promise<boolean> {
    //more code

De bovenstaande functie geeft een Promise terug waar in het resultaat van de functie zit. Van wat voor type dat resultaat is staat tussen <>. In dit geval is dat een boolean.

Als je met Java hebt gewerkt heb je waarschijnlijk al gebruik gemaakt van generics. Zie bijvoorbeeld de onderstaande code

private ArrayList<String> myStrings = new ArrayList<>;
private ArrayList<Integer> myIntegers = new ArrayList<>;

De bovenstaande code mag je alleen Strings toevoegen aan myStrings en alleen Integers aan myIntegers. Dit terwijl myStrings en myIntegers van dezelfde classe zijn.

Voorbeeld: Een generic class maken in TypeScript

In dit voorbeeld maken we een asiel voor dieren. We willen dat het asiel voor verschillende type dieren. De volgende classes zijn beschikbaar:

class Kat {
    public toString():void{
        console.log("Ik ben een kat");
    }
}

class Hond {
    public toString():void{
        console.log("Ik ben een hond");
    }
}

Nu is het mogelijk om een class Asiel te maken waarbij je aangeeft dat het asiel voor verschillende type dieren is.

// Door <T> te gebruiken geven we aan dat we niet weten wat voor type dieren dit asiel kan zijn
class Asiel<T>{

    //Hier weten we niet welke type dieren het zijn (hond of kat?)
    //Het type van de attribuut is T[] (een array van T). Dit staat voor het nog onbekende type dieren
    private dieren:T[] = [];

    //Hier weten de type van de parameters niet
    public plaatsDierInAsiel(dier: T ) : void{
        this.dieren.push(dier);
    }

    //Hier weten de return type niet
    public haalDierUitAsiel(): T | undefined { 
        return this.dieren.pop();
    }
}

Als je nu een instantie van de Asiel class maakt kan je aangeven voor welk type dieren het asiel is:

const hondenAsiel:Asiel<Hond> = new Asiel();
const kattenAsiel:Asiel<Kat> = new Asiel();

Nu kan je dieren in het asiel plaatsen en er weer uithalen:

const hond: Hond = new Hond();
hondenAsiel.plaatsDierInAsiel(hond);
console.log(hondenAsiel.haalDierUitAsiel()?.toString());

const kat: Kat = new Kat();
hondenAsiel.plaatsDierInAsiel(kat);
console.log(hondenAsiel.haalDierUitAsiel()?.toString());

Het voordeel van het bovenstaande voorbeeld is dat je maar één Asiel class hebt. Je hoeft dus niet voor elke type dier een nieuwe class te maken. Verder kan je de Asiel class gebruiken voor verschillende type dieren terwijl je toch de type veiligheid behoudt: honden kan je alleen in een honden asiel plaatsen en katten alleen in een katten asiel.