[ PHP6 ] classes étendues et constructeurs

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : [ PHP6 ] classes étendues et constructeurs

par Hywan » 18 févr. 2008, 11:13

Oui, merci au temps pour moi.
Entre PHP 4 e 5, Java, C++ etc., j'en perds mon latin ... euh ... mon ASCII ;-).

par x@v » 16 févr. 2008, 16:42

en java on apelle le constructeur de la classe mère
super();

par zeus » 15 févr. 2008, 17:16

Effectivement, cette solution (si elle fonctionne en PHP) est pas mal, mais on interdit d'étendre le constructeur. ;)

par Hywan » 15 févr. 2008, 16:22

Les points de vues évoqués sont tous bons. Tout dépend de la façon dont on a structuré nos données et de leurs implémentations.

Sinon il y a encore un truc pour que les Filles n'aient pas de constructeurs, c'est de finaliser le constructeur de la Mere, i.e. interdire la surchage :
class C {

    final public function __construct ( ) {

        // premier constructeur à être interpellé
        // lors d'une instanciation de la famille
        // dans la famille d'objets (Filles etc.).
    }
}
Je n'ai pas testé. Peut être que PHP n'en veut pas, à voir (mais j'en doute, je ne vois pas en quoi cela poserait de problèmes).

C'est un cas bien particulier, mais ça peut toujours être utile ;-).

par zeus » 15 févr. 2008, 15:39

Pour préciser un peu mon intervention précédente :

Il m'est arrivé d'avoir des cas de figures où ma classe fille doit lancer une initialisation sur une méthode qui lui est propre, tout en devant initialiser la classe mère.
Actuellement, c'est tout a fait possible en appelant le constructeur de la classe mère dans le constructeur de la classe fille via parent::__construct(), mais je doutais de cette solution car il fallait que les développeurs pensent à l'ajouter dans leurs classes filles.

Je trouve donc que la solution d'imposer l'appel au constructeur mère, qu'il y ai constructeur fille ou pas, me séduit énormément.

Je sais que vous pourrez me dire que si les développeurs ne le font pas, il y aura des erreurs et que l'oubli sera corrigé pendant le développement, mais j'apprécie l'idée de forcer les filles à suivre une structure de base imposée par la classe mère.

par Cyrano » 15 févr. 2008, 15:30

Il m'est arrivé de devoir préciser un fonctionnement dans la classe fille...
C'est à ça que sert l'extension de classe non ? La classe mère est même éventuellement abstraite mais a un fonctionnement très générique : l'héritage permet justement cette précision pour un besoin de traitement spécifique.

Il me vient à l'esprit une illustration un peu sommaire mais ça devrait être très parlant :
mettons une classe "math" qui contiendra en méthode les quatre opérations arithmétiques : ensuite, je peux préciser certains traitement dans des extensions, dans des classes "trigo" où j'aurai les traitement sur les sinus, cosinus etc..., et une autre classe statistiques avec des méthodes de calculs de moyennes et autres du genre.

Mes deux classes filles ne seront pas utilisées dans le même contexte, mais requièrent les propriétés et méthodes de ma class "math".

Mais dans aucun cas je n'ai besoin de redéfinir le constructeur me semble-t-il :-k

par zeus » 15 févr. 2008, 14:45

Il m'est arrivé de devoir préciser un fonctionnement dans la classe fille alors que le fonctionnement général est défini dans la classe mère.

par Hywan » 15 févr. 2008, 14:21

Il est probable qu'on ai besoin depuis une fille d'appeler le constructeur de la mère. En Java, ça doit être la première instruction de la méthode :

Code : Tout sélectionner

public class Mere { public void Mere ( String message ) { System.out.println(message); } } public class Fille extends Mere { public void Fille ( ) { super("Hopla"); // le reste du code. } }
En PHP, on a la possibilité de lancer le constructeur de la mère n'importe quand, un avantage. Mais ça peut être le gros bazar.

Pourquoi utiliser un constructeur ? Il sert principalement à initialiser l'objet.
Pourquoi étendre un objet à un autre ? Principalement pour préciser l'objet parent. On a l'objet Mere qui propose des méthodes communes à tous ces enfants. Les enfants ayant la possibilité de surcharger les méthodes de la Mere.
Quand on surcharge le constructeur, cela signifie : on initialise pas la Mere, mais on laisse la Fille s'initialiser. Si la Fille a besoin d'utiliser les paramètres initiaux de la Mere, on propage la constructeur en faisant :
class Fille extends Mere {

    public function __construct ( ) {

        parent::__construct();
        // suite du code.
    }
}
Il est beaucoup plus logique de commencer par construire la Mere, puis la Fille.

Donc Cyrano a raison. La classe Mere permet à ces Filles d'utiliser des méthodes génériques ou communes. Les Filles ont la possibilité de les surcharger, ... de les redéfinir en quelques sortes (c'est faux, mais on schématise ...).
Les constructeurs des Filles sont donc -- en général -- très semblable à celui de la Mere, et appelle celui de la Mere si c'est bien construit.

Les classes étant des familles d'objets, si une Fille a un comportement différent de la Mere, c'est que l'architecture a été mal choisie à mon sens, et que les familles ont été mal construites/pensées.

par Cyrano » 15 févr. 2008, 07:33

Je suis très loin d'être un gourou en POO, néanmoins, sur un plan général : une classe étendue permet d'utiliser des méthodes générique de la classe mère en y ajoutant des méthodes plus spécifiques. Il y a donc lieu de se demander s'il y a un intérêt à avoir un constructeur dans la classe fille qui soit complètement différent de celui de la classe mère. Les questions à se poser lors de la conception architecturale des différentes classes concernent à mon sens essentiellement le type d'objet qu'on veut manipuler.

Exemple : je crée une classe "sql" et je l'étends avec des classes "sqlserver", "oracle", "db2" et "mysql" : l'objet que je crée est cohérant et me sert à accéder à un serveur de base de données. J'aurai dans ma classe "sql" les méthodes génériques valable sur n'importe quel SGBD et dans les classes étendues les méthodes qui me permettent d'adapter les appels selon les spécificités propres au SGBD utilisé. Je n'ai donc pas à me soucier vraiment de l'appel implicite à la classe mère, cet appel est du reste tout à fait indispensable.

Mais si ta classe étendue ne doit pas déclencher l'appel du constructeur parent, alors ta classe n'a pas de raison d'étendre cette classe mère et tu auras intérêt à utiliser une inclusion pour créer un objet indépendant pour utiliser les méthodes de cette classe.

Enfin bon, je dis ça, d'autres auront peut-être un avis autre ou des explications techniques pour contredire ce point de vue ? :-k

par tavman » 15 févr. 2008, 00:43

Quand on lit les conclusions, j'ai plus l'impression que cela sera une possibilité interne du moteur php destinée aux dev d'extensions plutôt qu'une fonctionnalité destinée à l'utilisateur final.
Oui effectivement... C'est bien dommage je trouve...
Une fois, j'ai étendu la fille et la mère ...
Bien joué...

par mcorgnet » 14 févr. 2008, 17:02

Effectivement, il m'est déjà arrivé de me demander comment forcer les filles d'une classes à passer par le constructeur de la classe mère.

C'est assez sympa comme fonctionnalité ;)
Une fois, j'ai étendu la fille et la mère ...

Mais je sais pas si y'a un rapport ici.

par titerm » 14 févr. 2008, 16:55

Conclusions:

1. We add a flag to the class structure to record this
2. We do not add new syntax for this to userland
Quand on lit les conclusions, j'ai plus l'impression que cela sera une possibilité interne du moteur php destinée aux dev d'extensions plutôt qu'une fonctionnalité destinée à l'utilisateur final.

par zeus » 14 févr. 2008, 16:35

Effectivement, il m'est déjà arrivé de me demander comment forcer les filles d'une classes à passer par le constructeur de la classe mère.

C'est assez sympa comme fonctionnalité ;)

par tavman » 14 févr. 2008, 16:32

Oui, ca je sais... Donc quand je lis dans les nouveautés de PHP6
appel du constructeur de la classee mère lorsque pas déclaré dans la classee fille
Mais bon je viens juste de tomber la dessus :
http://www.php.net/~derick/meeting-note ... onstructor
et en fait, c'est pas méchant... Vraisemblablement, ils vont rajouter un mot clé (ici ils disent require mais c'est déjà une fonction... donc je sais pas) pour obliger le constructeur de la classe fille a appeller le constructeur de la classe mère... Donc c'est pas automatique, c'est seulement si ca a été prévu dans la classe mère. Logique en fait...

par titerm » 14 févr. 2008, 09:09

Je pense que tu as besoin d'appeler explicitement le constructeur parent uniquement si tu as surcharger ce dernier.
class Mere {
   function __construct() { echo 'mere';}
}

class Fille extends mere {
   function __construct() { echo 'fille'; }
}

Si tu instancie Fille, le __construct() de mere ne sera pas appeler sauf si tu le fait toi même via parent::