Er zijn hier twee problemen die veroorzaken dat een constructor altijd geimplementeerd moet worden:
1.
Beschouw een klasse hierarchie Object <- Voertuig <- Fiets <- Bakfiets en de volgende code (ok, C++, maar dat maakt het ff duidelijker omdat er dan niets engs onderwater gebeurd):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| Container
{
public:
Container(const Object *o) : object(o) {}
setItem(const Object *o) { object = o; }
private:
Object *object;
};
Fietsenstalling : public Container
{
public:
Fietsenstalling(const Fiets *f) : Container(f), fiets(f) { }
setItem(const Fiets *f) { Container::setItem(f); fiets = f; }
private:
Fiets *fiets;
};
int main(void)
{
Voertuig *v = getVoertuig();
Bakfiets *b = getBakfiets();
Container a1(v), a2(b);
Fietsenstalling b1(v), b2(b);
return 0;
} |
Container kan nu geinstantieerd worden met ieder object en zal dus alles accepteren, Fietsenstalling echter vereist een instantie van het type Fiets. Stel nu dat er een klasse Boekenkast is die erft van Object, kan ik dan nu ook een Fietsenstalling instantieren met een Boekenkast omdat ie dan gewoon de constructor van Container pakt? Nee natuurlijk niet, dan zou de pointer fiets niet geinitialiseerd worden en crashes veroorzaken (Want er is geen andere constructor in Fietsenstalling die aangeroepen kan worden). De code in de main functie laat ook al zien dat b1 eigenlijk fout is omdat je niet alle voertuigen in een Fietsenstalling kan zetten. Ik kan me ook niet voorstellen dat Delphi dit wel accepteerd, als dat wel zo is ben ik heel benieuwd hoe Delphi dit probleem oplost.
2.
Dit probleem gaat nog veel verder, het is namelijk ook toepasbaar op functies, in de bovenstaande code staan ook de functies setItem(). Hetzelfde is weer toepasbaar, kan ik nu de functie setItem() uit Fietsenstalling aanroepen met een Boekenkast en dat dan automatisch de functie setItem() uit Container aangeroepen wordt? Nee, doordat de setItem functie in Fietsenstalling opnieuw geimplementeerd wordt, worden alle overloads uit de base classes gemaskeerd.
Ok, dit zijn C++ voorbeelden, maar C# is eigenlijk een versimpelde variant van C++ (net als Java) en zal zich met dit soort problemen niet veel anders kunnen dan C++. Deze problemen zijn in de literatuur al stevig onderzocht en met imperatieve object georienteerde talen kun je niet veel andere zinnige oplossingen geven voor deze problemen. Natuurlijk kun je zeggen dat de programmeur maar beter op moet letten, maar als je met 100 programmeurs aan een project werkt met een grote klasse hierarchie zie je dit soort dingen wel heel makkelijk over het hoofd. Sterker nog, weinig programmeurs zijn op de hoogte van de situatie zoals ik in punt 2 omschreven heb.