Hallo, ik heb het volgende probleem.
Ik heb een klasse die een array bevat met daarin andere klassen.
De opbouw is ongeveer zo:

Component
----Button
----Select
----TextField
----Checkbox

ComponentCollection
----methode: add(Component c)


Hiermee bedoel ik dat de klassen Button, Select, TextField en Checkbox de klasse Component extenden.
De klasse ComponentCollection bevat een methode die alleen als parameter objecten accepteert die van het type Component zijn.
Je zorgt zo ervoor dat er alleen maar klassen in kunnen worden gedaan met add() als ze een Component zijn.
Als ik nu in de klasse ComponentCollection iets wil doen met de toegevoegde Component, dan kan ik dus alleen de methodes gebruiken die in de Component klasse worden gedefinieerd. Ik kan dus wel een Button meegeven aan ComponentCollection, maar ComponentCollection kan niets doen met de Button klasse, hij kan alleen iets doen met de Component klasse die Button overerft.
Toch wil ik de methodes van Button kunnen bereiken. Is hier een manier voor?
Ik heb het hier niet over een interface, ookal zou je Button bijvoorbeeld een interface geven, de methode van Button die je wil bereiken heb je er al in staan. Een interface zou je kunnen maken, maar daar los je nu niks mee op. Dit is een overervings kwestie.
Als jullie niet begrijpen wat ik bedoel, dan moet ik het misschien nog wat beter uitleggen.
Natuurlijk kun je wel de methods van Button gebruiken. Vanuit een OO perspectief is het alleen niet veilig om te doen, aangezien je niet weet of die methods wel bestaan. Je kan er alleen zeker van zijn dat de add method bestaat, omdat je daar (zo verwacht ik) op type hint.

De oplossing is dus het maken van een ButtonInterface met die specifieke methods en die dan type hinten/controleren voordat je een method aanroept.

En overigens, een Interface is stap 1 van overerven, dus dat een overervings kwestie niks met interfaces te maken heeft is een vreemde conclusie...
De type hint die in de add() functie bepaalt welk type objecten kunnen worden toegevoegd bepaalt niet welke methodes je kunt aanroepen. Als je dus een button meegeeft, dan kan je in die add() methode (of ergens anders) ook gewoon de button specifieke methodes aanroepen. Zolang ze maar public zijn.

Waar je alleen wel aan moet denken is dat je de button specifieke methode niet moet aanroepen op een niet button. Dat kan je checken via een instance of check:

<?php
class ComponentCollection{
  public function add( Component $obj ){
    if ( $obj instanceof Button ){
      $obj->buttonClick();
    }
  }
}
?>


Overigens noem jezelf de interface al. Dat is wel een betere methode, omdat je dan ook door niet overerving toch nog de juiste types kunt afdwingen. Ook voor bovenstaande button kan je een interface definieren zodat je niet alleen op button kunt checken, maar via die interface op alle types die de juiste methodes hebben. Probeer type hints en dit soort instance checks altijd op interfaces te doen, nooit op classes.

Reageren