2010-11-13 5 views

Répondre

2

Like deceze already points out, ce n'est pas possible avec l'héritage.

Vous pouvez utiliser runkit_class_adopt-de PECL convertir une classe de base à une classe héritée, ajouter des méthodes ancestrales, le cas échéant mais runkit est quelque chose que vous ne voulez pas dans votre code de production.

L'approche OO propre à ce serait d'utiliser un Bridge pattern pour donner l'objet la mise en œuvre de la classe A à l'exécution et ainsi

découplage une abstraction de sa mise en œuvre afin que les deux peuvent varier indépendamment.

Comment ça marche

d'abord définir une interface tous les "parents" de B et B doit lui-même mettre en œuvre. L'interface doit contenir toutes les méthodes que vous voulez que B hérite. Je mets ces termes entre guillemets, car techniquement, ils ne sont ni parents, ni héritiers. Ensuite, définissez les classes A1 et A2 implémentant cette interface et ajoutez les méthodes demandées par l'interface

interface MyImplementation 
{ 
    public function doSomething(); 
    // more methods … 
} 
Ensuite, créez votre classe B et faites en sorte qu'elle nécessite l'une des classes d'implémentation à l'initialisation.

abstract class B implements MyImplementation 
{ 
    protected $_implementation; 
    // more properties ... 

    public function __construct(MyImplementation $implementationObj) 
    { 
     $this->_implementation = $implementationObj; 
    } 
    public function doSomething() 
    { 
     return $this->_implementation->doSomething(); 
    } 
    // more methods ... 
} 

Comme vous pouvez le voir, tous les appels vers les méthodes requises par notre interface sont déléguées à l'objet « parent » agrégé, donc en fonction de ce que vous avez passé dans B, vous obtiendrez des résultats différents. Maintenant, pour définir C, il suffit de lui faire accepter le nom de classe de la classe d'implémentation et de l'instancier dans C pour le passer au parent, par ex. B.

class C extends B { 
    public function __construct($bMethodImplementation) { 
     parent::__construct(new $bMethodImplementation); 
    } 
} 

et vous pouvez le faire

$c = new C('A1'); 
echo $c->doSomething(); // echoes A1 
$c = new C('A2'); 
echo $c->doSomething(); // echoes A2 
4

Étant donné que vous devez coder en dur la classe parent (class B extends A1), cela n'est pas possible (malgré les extensions/hacks d'exécution, que je ne recommanderais pas d'utiliser). Regardez dans composition au lieu de l'héritage si vous avez besoin de cette flexibilité.

+0

En effet, * toujours * favoriser la composition sur l'héritage! –

Questions connexes