# Polymorfisme in de praktijk

Beeld je in dat je een klasse `EersteMinister` hebt met een methode `Regeer` en je wilt een eenvoudig land simuleren.

De `EersteMinister` heeft toegang tot de ministers die hem kunnen helpen (inzake milieu, binnenlandse zaken (BZ) en economie). Zonder de voordelen van polymorfisme zou de klasse `EersteMinister` er zo kunnen uitzien (**slechte manier**!):

```csharp
internal class EersteMinister
{
    public MinisterVanMilieu Jansens {get;set;} = new MinisterVanMilieu();
    public MinisterBZ Ganzeweel {get;set;} = new MinisterBZ();
    public MinisterVanEconomie VanCent {get;set;} = new MinisterVanEconomie();

    public void Regeer()
    {
        // ministers stappen binnen en zeggen wat er moet gebeuren

        // Jansens: Problematiek aangaande bos dat gekapt wordt
        Jansens.VerhoogBosSubsidies();
        Jansens.OpenOnderzoek();
        Jansens.ContacteerGreenpeace();

        // Ganzeweel advies omtrent rel aan grens met Nederland
        Ganzeweel.VervangAmbassadeur();
        Ganzeweel.RoepTroepenmachtTerug();
        Ganzeweel.VerhoogRisicoZoneAanGrens();

        // Van Cent geeft advies omtrent nakende beurscrash
        VanCent.InjecteerGeldInMarkt();
        VanCent.VerlaagWerkloosheidsPremie();
    }
}
```

Dit voorbeeld is gebaseerd op een briljante StackOverflow post waarin de vraag *"What is polymorphism, what is it for, and how is it used?"* wordt behandeld[^1].

De `MinisterVanMilieu` zou er zo kunnen uitzien (de methodenimplementatie mag je zelf verzinnen):

```csharp
internal class MinisterVanMilieu
{
  public void VerhoogBosSubsidies(){}
  public void OpenOnderzoek(){}
}
```

De `MinisterVanEconomie`-klasse heeft dan weer heel andere publieke methoden. En de `MinisterBZ` ook weer totaal andere.

Je merkt dat de `EersteMinister`-klasse aardig wat specifieke kennis moet hebben van de vele verschillende departementen van het land. Bovenstaande code is dus zeer slecht en vloekt tegen het abstractie-principe van OOP: onze klasse moeten veel te veel weten van andere klassen, wat vermeden moet worden. Telkens er zaken binnen een specifieke ministerklasse wijzigen moet dit ook in de `EersteMinister` aangepast worden. **Dankzij polymorfisme en overerving kunnen we dit alles veel mooier oplossen!**

**Ten eerste:** We verplichten alle ministers dat ze overerven van de abstracte klasse `Minister` die maar 1 abstracte methode heeft `Adviseer`:

```csharp
internal abstract class Minister
{
  abstract public void Adviseer();
}

internal class MinisterVanMilieu:Minister
{
  public override void Adviseer()
  {
       VerhoogBosSubsidies();
       OpenOnderzoek();
       ContacteerGreenpeace();
  }
  private void VerhoogBosSubsidies(){ ... }
  private void OpenOnderzoek(){ ... }
  private void ContacteerGreenpeace(){ ... }
  }
}

internal class MinisterBZ:Minister {}
internal class MinisterVanEconomie:Minister {}
```

**Ten tweede:** Het leven van de EersteMinister wordt plots véél makkelijker. Hij kan gewoon de `Adviseer` methode aanroepen van iedere minister:

```csharp
internal class EersteMinister
{
  public MinisterVanMilieu Jansens {get;set;} = new MinisterVanMilieu();
  public MinisterBZ Ganzeweel {get;set;} = new MinisterBZ();
  public MinisterVanEconomie VanCent {get;set;} = new MinisterVanEconomie();
    
  public void Regeer()
  {
      Jansens.Adviseer(); 
      Ganzeweel.Adviseer(); 
      VanCent.Adviseer();
  }
}
```

**En ten derde:** En we kunnen hem nog helpen door met een array of `List<Minister>` te werken zodat hij ook niet steeds de "namen" van z'n ministers moet kennen. Dankzij polymorfisme mag dit:

```csharp
internal class EersteMinister
{
  public List<Minister> AlleMinisters {get;set;}= new List<Minister>();
  public EersteMinister()
  {
      AlleMinisters.Add(new MinisterVanMilieu());
      AlleMinisters.Add(new MinisterBZ());
      AlleMinisters.Add(new MinisterVanEconomie());
  }
  public void Regeer()
  {  
      foreach (Minister minister in AlleMinisters)
      {
          minister.Adviseer();
      }
  }
}
```

En wie zei dat het regeren moeilijk was?!

{% hint style="info" %}
Merk op dat dit voorbeeld ook goed gebruik maakt van **compositie**.
{% endhint %}

[^1]: [stackoverflow.com/questions/1031273/what-is-polymorphism-what-is-it-for-and-how-is-it-used](https://stackoverflow.com/questions/1031273/what-is-polymorphism-what-is-it-for-and-how-is-it-used)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://apwt.gitbook.io/zie-scherp-scherper/h16-polymorfisme/polypraktijd.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
