POO... composition et héritage

Lost In Paradise
Invité n'ayant pas de compte PHPfrance

09 mai 2006, 20:31

Bonjour à tous,

Je suis entrain d'apprendre la POO sur le PHP, j'ai jamais fais de POO alors c'est pas évident de comprendre tout d'un coup :roll: ...

J'ai fais ce petit script pour essayer de comprendre avec un exemple concret, il s'agit de la création d'un objet personnage avec son inventaire et les objets qu'il contient.
<?php

/*
 * Personnage
 */

class personnage {
	
	public $force;
	public $vitesse;
	
	function __construct($force, $vitesse) {
		
		echo 'Construction du personnage... Force : ' . $force . ', Vitesse : ' . $vitesse . '<br/>';
		
		$this->force = $force;
		$this->vitesse = $vitesse;
		
		$this->inventaire = new inventaire($force); 
	}
	
	public function add_force ($force) {
		$this->force = $this->force + $force;
	}
	
}


/*
 * Inventaire
 */

class inventaire extends personnage {
	
	protected $inventaire_taille;
	protected $inventaire_objets;
	
	function __construct($force) {

		$this->inventaire_objets = array();
		$this->inventaire_taille = $force * 5;
		$this->inventaire_objets[0] = new pomme(2);
		$this->inventaire_objets[1] = new couteau(1);
						
		echo 'Construction de l\'inventaire... Taille de l\'inventaire : ' . $this->inventaire_taille . '<br/>';
		
	}
	
	public function inventaire_libre() {
		$this->inventaire_taille = $this->force * 5;
		$inventaire_oqp = 0;
		foreach($this->inventaire_objets as $k => $v) {
			$inventaire_oqp = ($this->inventaire_objets[$k]->poids*$this->inventaire_objets[$k]->quantite) + $v;	 
		}
		
		return $this->inventaire_taille - $inventaire_oqp;		
	}

	
	public function inventaire_liste() {
		$inventaire = '';
		foreach($this->inventaire_objets as $k => $v) {
			$inventaire .= $this->inventaire_objets[$k]->nom . ' (' . $this->inventaire_objets[$k]->quantite . ')<br/>';
		}	
		return $inventaire;
	}
	
}


/*
 *  Objets
 */

abstract class objets {
	
	public $poids;
	public $type;
	public $quantite;
	public $nom;
	
	function __construct($quantite) {
		$this->quantite = $quantite;
	}
	
}


/*
 *  Objets de type Nourriture
 */

abstract class nourritures extends objets {
	
	public $hp;
	
	function __construct ($quantite) {
		parent::__construct($quantite);
		$this->type = "Nourriture";
	}	
}

class pomme extends nourritures {
		
	function __construct ($quantite) {
		parent::__construct($quantite);
		$this->poids = 2;
		$this->nom = "Pomme";
	}	
}


/*
 *  Objets de type Armes
 */

abstract class armes extends objets {
	
	public $degats;
	
	function __construct ($quantite) {
		parent::__construct($quantite);
		$this->type = "Arme";
	}	
}

class couteau extends armes {
	
	function __construct ($quantite) {
		parent::__construct($quantite);
		$this->poids = 5;
		$this->nom = "Couteau";
	}	
}



$personnage = new personnage(15,15);
echo '<br/>Taille disponible dans l\'inventaire : ';
echo $personnage->inventaire->inventaire_libre();
echo '<br/><br/>Liste de l\'inventaire<br/>';
echo $personnage->inventaire->inventaire_liste();

echo '<br/><br/>Ajoute de 5 de force<br/>';
echo $personnage->add_force(5);

echo '<br/>Taille disponible dans l\'inventaire : ';
echo $personnage->inventaire->inventaire_libre();
?>
Ce que je n'arrive pas à faire c'est récuperer la propriété force de la class personnage pour l'utiliser dans la classe inventaire (voir la méthode inventaire_libre).
Si je met cette méthode dans la classe personnage j'arrive à avoir le résultat que je veux... mais pour la lisibilité du code je ne trouve ça pas terrible de mettre une méthode en rapport avec l'inventaire dans la classe personnage...

Si vous pouviez m'éclaircir sur ce sujet ? Je pense que j'ai compris l'héritage mais la composition je rame :?

Merci à tous et à bientôt :wink:

Eléphanteau du PHP | 11 Messages

09 mai 2006, 20:52

Je n'ai pas pris le temps de tout lire mais je crois qu'une simple méthode (Fonction) dans ta classe personnage sufirais. Comme celle-ci :

Code : Tout sélectionner

Public Function getForce() {Return self::$force;}
ou bien :

Code : Tout sélectionner

Public Function getForce() {Return $this->force;}
Ton code m'intéresse alors si tu as des question sur comment arrivé a quelque chose ou, si tu as des problème, ou encore dans l'intention de partagé. Tu n'as qu'a me le dire ici :)


-------------------------------------------------------------------------------------
Un petit patch de message....

J'ai lu tes deux classe, je vois pas pourquoi cela ne fonctionne pas. La seul raison que je vois valide est la variable dans construct, car je n'ai jamais fait sa. Mais sinon tu n'as qu'as divisé l'espace d'inventaire par 5 non...
Comme ceci :

Code : Tout sélectionner

Public Function getForce() {Return $this->inventaire_taille/5;}
Et a partir de ta classe personnage, quand tu crée l'objet Inventaire tu n'as qu'as ajouté une variable a Inventaire et faire ceci :

Code : Tout sélectionner

Public $InvForce; //--------------------------- $this->inventaire = new inventaire; $this->inventaire->InvForce=$this->$force;
Mais ce qui est drole c'est que la classe Inventaire étend la classe personnage, donc tu as accès à la classe Personnage a partir de l'inventaire en faisant comme ça :

Code : Tout sélectionner

$Inventaire=new inventaire; $fr=$Inventaire->getForce(); // Ou.... $Inventaire=new inventaire; $fr=$Inventaire->force;

Ou tu peut te servir de php5 ;)

Code : Tout sélectionner

$info=personnage::$inventaire->inventaire_libre(); $force=personnage::$force; personnage::$inventaire->newForce($force); // ou personnage::$inventaire->newForce(personnage::$force);
Il y as tellement de possibilité

Lost In Paradise
Invité n'ayant pas de compte PHPfrance

09 mai 2006, 21:28

Oui mais la classe inventaire étant un enfant de la classe personnage je pensais que la propriété de la force serait héritée ? sans avoir besoin de faire autre chose en plus ? La méthode get ne sert que si on veut autoriser un objet non enfant d'accéder aux propriétés de l'objet instanciée (enfin c'est ce que j'ai compris) car je voulais mettre les propriétés en protected pour protéger des modifications extérieures à l'objet.

Lost In Paradise
Invité n'ayant pas de compte PHPfrance

09 mai 2006, 21:50

J'ai fais un var_dumps sur $personnage :

Code : Tout sélectionner

object(personnage)#1 (3) { ["force:protected"]=> int(20) ["vitesse:protected"]=> int(15) ["inventaire"]=> object(inventaire)#2 (4) { ["inventaire_taille:protected"]=> int(0) ["inventaire_objets:protected"]=> array(2) { [0]=> object(pomme)#3 (5) { ["hp"]=> NULL ["poids"]=> int(2) ["type"]=> string(10) "Nourriture" ["quantite"]=> int(2) ["nom"]=> string(5) "Pomme" } [1]=> object(couteau)#4 (5) { ["degats"]=> NULL ["poids"]=> int(5) ["type"]=> string(4) "Arme" ["quantite"]=> int(1) ["nom"]=> string(7) "Couteau" } } ["force:protected"]=> NULL ["vitesse:protected"]=> NULL } }
Ce qui m'intrigue c'est les 2 NULL à la fin ???

Eléphanteau du PHP | 11 Messages

10 mai 2006, 00:04

Humm, ouai.. Je ne connaispas var-dump mais je peut quand-même voir la structure ici. C'est étrange, je vient de lire sur le site de php le sous-chapitre Visibilité dans les classe php5. il dit
L'accès aux éléments protégés (protected) est limité aux classes et parents hérités (et à la classe qui a défini l'élément)
. Donc selon moi ce que tu as devrais fonctionné. Pour le constructeur de classe, dans la définition de l'équipe Php je ne vois aucun paramètre, seulement ceux qui laisse des commentaire en bas ont écris la fonction __construct() avec des paramètres et je ne comprend pas tellement ce qu'ils raconte. Tu devrais essaillé de revoir la visibilité de tes variables et de les metre en Public, mais seulement après t'être assuré que la construction se fait sans erreur et que tes variable se définisse bien. Car avec ton var_dump on vois bien qu'elles sont null.

Je vient de revoir le var dump et, elle sont null uniquement dans inventaire...
Est-ce parceque php fait un lien directe avec celles qui ne le sont pas dans personnage ou c'est a cause de la visibilité. Sa je ne peut pas le savoir, j'ai jamais utilisé un var_dump.

Si ceci ne fonctionne pas je te conseille de revoir la structure au complet de toutes tes classes sur papier ou dans un logiciel graphique pour pouvoir faire un shéma ou il n'y aura aucune erreur. Avant de le faire ou même pendant fait des test pour t'assuré que tes méthode aille bien ensemble et qu'il n'y est aps d'erreur. Après tu poura te lancé dans le projet. Selon moi sa ne sert a rien de construire quelquechose d'aussi gros pour apprendre comment fonctionne l'OO en Php.

Tout ceci me semble assez bien par contre, la structure veut de l'avenir. Fait bien attention à ce que tu fait et tu aura moin d'erreur :wink:

Ohh, mais c'est qu'elles sont maintenant public ces variables :P
AAAAAA!!!!!!!! Ce que je déteste les cookie ! Voila 2 message identique !