IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[POO] Utilisation de l'héritage


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 117
    Par défaut [POO] Utilisation de l'héritage
    Bonsoir,

    J'ai un petit problème assez simple d'héritage, tellement simple que je n'arrive pas à le résoudre ...

    Mettons deux classes A et B
    La classe A doit posseder plusieurs objets B.
    Toutefois un objet B contenu par A, doit pouvoir utiliser des méthodes et des attributs de l'objet A qui le contient.
    La classe A ne fera jamais appel aux méthodes de B par elle même.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    class A
    {
      protected $A_id;
      public $B_list;
      public __construct (...)
      {
       $B_list = array();
        for (..)
         $B_list = new B (...);
      }
      protected A_funct(...)
      {
        ...
      }
    }
    class B extends A
    {
     public $B_data;
     public __construct (...)
     {
       utilisation de $A_id et de A_funct(..) de l\'objet A qui aura appelé ce construct.
     }
     public __foo (...)
     {
    utilisation de $A_id et de A_funct(..) de l\'objet A qui aura appelé cette méthode foo
    }
     
    }
    Donc bon ça me paraît évident que B doit hériter de A, mais comment récupérer l'objet A qui a appelé une méthode de B ?

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    obj_A = new A(...);
    obj_A->B_list[0]->foo()
    Comment faire pour que foo utilisent les attributs/méthode d'une copie de obj_A ?

    Je sais bien que les passer en paramètres résoudrait le problème mais ça fait pas très POO ...

    N'existe t'il pas une méthode plus "propre" que de passer au constructeur B une copie de l'élément A actuel ($this) ?


    Merci d'avance pour vos réponses !

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    625
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 625
    Par défaut
    Hello,

    Qu'une classe B doive faire appel à des méthodes et membres d'une classe A n'induit pas obligatoirement une relation d'héritage.

    L'héritage c'est "B = A + options" et pas "B utilise A".

    En ce qui te concerne, passer une référence à l'instance de A à tes éléments B est ce qu'il y a de plus logique.

  3. #3
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Salut

    Créer une classe A qui créé des objets d'une classe B, dont B hérite de A, ça risque d'être ingérable, voir provoquer des erreurs.
    A vu de nez, ça ressemble à une sorte de boucle sans fin.

    Pourquoi ta classe A aurait besoin de créer des instances de B ? (vu que B en hérite)
    Ou alors, pourquoi B hériterait de A ?

    Comme ça, au feeling, je dirais qu'il faudrait éliminer un des 2 cas.


    Attention : Dans ton cas (B hérite de A), si dans B tu crée un constructeur (__construct__) alors que A a aussi un constructeur, le constructeur de B "écrase" en quelque sorte celui de A. En faite, B redéfini un nouveau.
    Si tu veux que les 2 constructeurs soient exécutés, faut que B l'appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class B {
    	public function __construct() {
    		parent::__construct();
    		// Traitements du constructeur de B à la suite
    		... etc ...
    	}
    }

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 117
    Par défaut
    Bonsoir,

    Merci pour vos réponses aussi rapide !

    Il est vrai qu'au final l'héritage n'a pas lieu d'être dans mon cas de figure, néanmoins passer systématiquement aux méthode de l'objet B contenu dans A une copie de l'objet A me paraît .. pas optimisé.

    Car au final :
    A contiendra donc plusieurs objets B
    Tout les objets de B auront besoin de méthodes de l'objet A qui le contient.
    (Éventuellement des listes d'objets C et D seront contenu dans B qui auront besoin des méthodes des objets B et A qui les contiennent... )

    Dois-je revoir mon modèle (A contient plusieurs B) ou existe t'il un moyen en PHP de récupérer l'objet parent A de B ?

  5. #5
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    A contiendra donc plusieurs objets B
    Tout les objets de B auront besoin de méthodes de l'objet A qui le contient.

    C'est une histoire sans fin, ça ... ne crois tu pas ?


    C'est comme si on voulait mettre une petite boite dans la grande boite, mais aussi la grande boite dans la petite. Pour cette dernière ça va être difficile.


    Je ne sais pas ce que tu veux faire, mais il y a un truc qui va pas.

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    625
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 625
    Par défaut
    Citation Envoyé par RunCodePhp Voir le message
    C'est comme si on voulait mettre une petite boite dans la grande boite, mais aussi la grande boite dans la petite. Pour cette dernière ça va être difficile.
    Non, il faut juste y voir une relation bidirectionnelle entre deux objets, rien d'incorrect dans tout ça. C'est même souvent incontournable comme relation.

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    625
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 625
    Par défaut
    Que des objets aient besoin d'une visibilité sur un autre objet est naturel, même si cet autre objet contient les premiers.
    Ce que tu veux faire et la méthode utilisée sont tout à fait corrects.

    Par contre il faut bien comprendre un truc. Tu ne passes pas une copie d'un objet, mais une référence. Toute modification effectuée sur cette référence affecte ton objet conteneur.

  8. #8
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    @Petibidon +1

    Et puis, si B hérite de A, A ne peut pas avoir de relation avec B.
    L'objet en tout cas, même si c'est très abstrait, on peut dire quand même que :
    une classe Parente qui donne naissance à une classe Entant, et bien l'Enfant ne peu pas être le Parent de son Parent.
    C'est un peu ce que tu tente de faire on dirait.

    Il y a des trucs qui, selon moi, ne seront pas possibles parce que ça n'aura pas de sens.
    Enfin, théoriquement.

    Citation Envoyé par Petibidon
    Non, il faut juste y voir une relation bidirectionnelle entre deux objets, rien d'incorrect dans tout ça. C'est même souvent incontournable comme relation.
    Je ne vois pas de bidirectionnel dans son principe.
    Par rapport à mon exemple, il tenterait de mettre la grande boite dans la petite alors que la grande contient déjà la petite.
    Ca me fait penser au serpent qui se mord la queue.


    Ceci dit, je n'ai pas de solution.
    Faudrait peut être un exemple concret, et non des A et des B.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 117
    Par défaut
    Merci beaucoup pour vos contributions !

    Voilà donc un exemple concret :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    class A
    {
    	private $attr_a_1;
    	public $b_list;
     
    	public function __construct($id, $b_id)
    	{		
    		$this->attr_a_1 = $id;
    		$this->b_list = array();
    		foreach ($b_id as $k => $v)
    			$this->b_list[$k] = new B($v, $this);
    	}
     
    	public function random_func($id)
    	{
    		return $this->attr_a_1 - $id;
    	}
     
    	/* .. */
    }
     
    class B
    {
    	protected $attr_b_1, $attr_b_2;
     
    	public function __construct($id_b, $a_obj)
    	{
    		$this->attr_b_1 = $id_b;
    		$this->attr_b_2 = $a_obj->random_func($id_b);
    	}		
     
    	public function change($param, $a_obj)
    	{
    		echo "changement de l'objet B : " , $this->attr_b_2 , ' en : "';	
    		$this->attr_b_2 = $a_obj->random_func($param);
    		echo $this->attr_b_2 , '"', "\n";	
    	}
    }
     
    $a = new A(5, array(1, 2, 3));
    foreach ($a->b_list as $k => $v)
    {
    	$a->b_list[$k]->change(10, clone $a);
    }
    Évidemment ce qui est fait la dedans est triviale et stupide mais ça résume bien l'idée.

    Toutes les méthodes de B ont besoin des méthodes de A.
    Toutefois A est sujet à d'autre modification externe à B

    Comment donc faire en php pour ne pas avoir à passer l'objet A (qui contient donc B) en paramètre de toutes les méthode de B ?

    écrire "$a->b_list[$k]->change(10, clone $a);" me paraît pas "viable" pour un utilisateur ..

    Peut être dois-je revoir la construction des deux classes ?

Discussions similaires

  1. [POO] Recherche cas d'utilisation de l'héritage multiple
    Par sleroux dans le forum Langages de programmation
    Réponses: 0
    Dernier message: 27/07/2010, 18h01
  2. [PHP 5.2] [POO] Utiliser des fonction statique ou un héritage
    Par pierrot10 dans le forum Langage
    Réponses: 16
    Dernier message: 28/03/2010, 21h03
  3. Réponses: 21
    Dernier message: 04/05/2006, 20h00
  4. [POO] utilisation d'objets
    Par jexl dans le forum Langage
    Réponses: 2
    Dernier message: 07/03/2006, 10h32
  5. [POO] Utilisation d'une classe dans une classe !
    Par Okinou dans le forum Langage
    Réponses: 3
    Dernier message: 16/02/2006, 14h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo