Bonjour,
Je continue mon apprentissage du PHP et notamment de POO.
Il y a certaines choses que je ne comprends pas, et si je ne les comprends pas, je ne vais pas être en mesure de continuer à avancer correctement.
1 - Ma première question concerne les fonctions de classe (méthode) et notamment les SET et les GET.
Dans le programme ci-dessous, j'ai compris que:
A - Le SET me permet de récupérer une donnée extérieure à ma classe. Et de vérifier si elle correspond bien à un type de donnée attendu.
B - Le GET "récupererait" la valeur retravaillée pour en faire... ce qu'on a envie d'en faire.
Question:
. A quoi me sert-il de passer par les GET Largeur et Longueur?
Car ici:
setLongueur et setLargeur modifient la valeur de la propriété longueur et largeur en direct avec $this->longueur(ou largeur)=$longueur(ou$largeur);
du coup je peux directement récupérer cette valeur directement dans une fonction tiers sans passer par un GET non?
Dans l'exemple ci-dessous, si je supprime les get largeur/longueur, il n'y a aucune incidence sur le programme.
S'il a été décidé de mettre des SET et des GET (par convention) il doit donc y avoir une raison qui n'apparait pas dans ce genre de petit exercice pratique.
Pourriez vous me dire laquelle svp? (Si possible avec un exemple tout simple car j'ai trouvé des explications et je n'ai rien compris)
2 - Dans mon second point, je pars du postulat que si la convention passe par une initialisation dans le set et la récupération dans un get, il faut le faire (mais j'aimerai bien comprendre pourquoi cf. question 1
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 <?php class Pont { private float $longueur; private float $largeur; private string $unite = ' m²'; public function setLongueur(float $longueur):void { // Je transforme les données et retourne un résultat if($longueur<0) { trigger_error( 'La longueur doit être supérieure à 0.', E_USER_ERROR ); } $this->longueur=$longueur; } private function getLongueur():float { return $this->longueur; } public function setLargeur(float $largeur):void { // Je transforme les données et retourne un résultat if($largeur<0) { trigger_error( 'La largeur doit être supérieure à 0.', E_USER_ERROR ); } $this->largeur=$largeur; } private function getLargeur():float { return $this->largeur; } private function getSurface(): float { return $this->longueur * $this->largeur; } public function printSurface():void { echo 'la surface est de '. $this->getSurface().$this->unite; } } $towerBridge = new Pont; $towerBridge->setLongueur(286.0); $towerBridge->setLargeur(15.0); $towerBridge->printSurface();).
Autre exercice pour comprendre, je dois écrire un programme de comparaison de deux niveaux de joueurs (jeu), proba de perte/ gain suivant la différence de niveau puis suivant le résultat du "combat", afficher les nouveaux scores.
Le squelette est donné + formules, j'écris le programme à ma sauce et ça fonctionne.
En revanche, hors cadre car je dois inclure des SET, des GET et un __construct.
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
45
46
47
48
49
50
51
52 <?php // Réponse exercice const RESULT_WINNER = 1; const RESULT_LOSER = -1; const RESULT_DRAW = 0; const RESULT_POSSIBILITIES = [RESULT_WINNER, RESULT_LOSER, RESULT_DRAW]; class Encounter { public string $playerNameOne; public int $levelOne; public int $resultOne; public string $playerNameTwo; public int $levelTwo; public int $resultTwo; public function probabilityAgainst($levelOne,$levelTwo):float { return 1/(1+(10 ** (($levelTwo - $levelOne)/400))); } public function setNewLevel(&$levelOne, $levelTwo, $resultOne) { if (!in_array($resultOne, RESULT_POSSIBILITIES)) { trigger_error(sprintf('Invalid result. Expected %s',implode(' or ', RESULT_POSSIBILITIES))); } return $levelOne += (int) (32 * ($resultOne - $this->probabilityAgainst($levelOne, $levelTwo))); } } $players = new Encounter; $players->playerNameOne="Greg"; $players->levelOne=400; $players->resultOne=RESULT_WINNER; $players->playerNameTwo="Jade"; $players->levelTwo=800; $players->resultTwo=RESULT_LOSER; echo ($players->probabilityAgainst($players->levelOne,$players->levelTwo)*100).'%'; echo "</br>"; echo $players->setNewLevel($players->levelOne,$players->levelTwo,$players->resultOne); echo "</br>"; echo $players->setNewLevel($players->levelTwo,$players->levelOne,$players->resultTwo); exit(0);
Le programme corrigé est le suivant (pour le coup ce n'est pas le mien):
Il y a certaines parties que je n'arrive pas à comprendre:
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 <?php class Encounter { public const RESULT_WINNER = 1; public const RESULT_LOSER = -1; public const RESULT_DRAW = 0; public const RESULT_POSSIBILITIES = [self::RESULT_WINNER, self::RESULT_LOSER, self::RESULT_DRAW]; public static function probabilityAgainst(Player $playerOne, Player $playerTwo): float { return 1/(1+(10 ** (($playerTwo->getLevel() - $playerOne->getLevel())/400))); } public static function setNewLevel(Player $playerOne, Player $playerTwo, int $playerOneResult): void { if (!in_array($playerOneResult, self::RESULT_POSSIBILITIES)) { trigger_error(sprintf('Invalid result. Expected %s',implode(' or ', self::RESULT_POSSIBILITIES))); } $playerOne->setLevel( $playerOne->getLevel() + round(32 * ($playerOneResult - self::probabilityAgainst($playerOne, $playerTwo))) ); } } class Player { private int $level; public function __construct(int $level) { $this->level = $level; } public function getLevel(): int { return $this->level; } public function setLevel(int $level): void { $this->level = $level; } } $greg = new Player(400); $jade = new Player(800); echo sprintf( 'Greg à %.2f%% chance de gagner face a Jade', Encounter::probabilityAgainst($greg, $jade)*100 ).PHP_EOL; // Imaginons que greg l'emporte tout de même. Encounter::setNewLevel($greg, $jade, Encounter::RESULT_WINNER); Encounter::setNewLevel($jade, $greg, Encounter::RESULT_LOSER); echo sprintf( 'les niveaux des joueurs ont évolués vers %s pour Greg et %s pour Jade', $greg->getLevel(), $jade->getLevel() ); exit(0);
A - Ici on place dans Encounter tout ce qui "figé" ou structurel.
Les règles du jeu, les modèles mathématiques sous jacent ne sont pas sujets à modifs.
Encounter reçoit les infos depuis les instanciations de la classe Player (quel est le sens de lecture du programme en fait? c'est pas du tout de haut en bas).
La partie que je ne comprends pas est celle-ci:
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 class Encounter { public const RESULT_WINNER = 1; public const RESULT_LOSER = -1; public const RESULT_DRAW = 0; public const RESULT_POSSIBILITIES = [self::RESULT_WINNER, self::RESULT_LOSER, self::RESULT_DRAW]; public static function probabilityAgainst(Player $playerOne, Player $playerTwo): float { return 1/(1+(10 ** (($playerTwo->getLevel() - $playerOne->getLevel())/400))); } public static function setNewLevel(Player $playerOne, Player $playerTwo, int $playerOneResult): void { if (!in_array($playerOneResult, self::RESULT_POSSIBILITIES)) { trigger_error(sprintf('Invalid result. Expected %s',implode(' or ', self::RESULT_POSSIBILITIES))); } $playerOne->setLevel( $playerOne->getLevel() + round(32 * ($playerOneResult - self::probabilityAgainst($playerOne, $playerTwo))) ); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 $playerOne->setLevel( $playerOne->getLevel() + round(32 * ($playerOneResult - self::probabilityAgainst($playerOne, $playerTwo))) );
B - Ici, je ne comprends pas trop le lien entre SET/GET et __construct
. Quel est l'intérêt de passer par __construct? Est-ce seulement pour refiler les données à la fonction en écrivant moins de lignes ou il y a d'autres intérêts?
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 class Player { private int $level; public function __construct(int $level) { $this->level = $level; } public function getLevel(): int { return $this->level; } public function setLevel(int $level): void { $this->level = $level; } } $greg = new Player(400); $jade = new Player(800);
Car on a:
. $greg = new Player(400);
A la place de:
$greg = new Player;
$players->level=400; (si jamais on avait public int $level dans la classe Player - d'ailleurs je ne vois pas trop l'intérêt de le passer en private?)
. public function __construct(int $level) et public function setLevel(int $level): void, quel est l'intérêt de setLevel dans ce cas?
C - Dernière partie ou je ne comprends pas un passage
En première partie j'ai: Encounter::setNewLevel($greg, $jade, Encounter::RESULT_WINNER);
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 echo sprintf( 'Greg à %.2f%% chance de gagner face a Jade', Encounter::probabilityAgainst($greg, $jade)*100 ).PHP_EOL; // Imaginons que greg l'emporte tout de même. Encounter::setNewLevel($greg, $jade, Encounter::RESULT_WINNER); Encounter::setNewLevel($jade, $greg, Encounter::RESULT_LOSER); echo sprintf( 'les niveaux des joueurs ont évolués vers %s pour Greg et %s pour Jade', $greg->getLevel(), $jade->getLevel() );
avec $greg = new Player(400); et la classe Player qui ne contient qu'une seule propriété.
Du coup j'en ai conclu que lorsque je n'ai qu'une seule propriété, pas besoin de rentrer dans le détail, PHP nous renvoit d'office la valeur de la propriété
...
Sauf que plus bas je trouve:
$greg->getLevel(), et si je remplace par $greg, ca ne fonctionne pas.
Du coup, ma théorie précédente tombe à l'eau et je ne vois pas pourquoi dans un cas je peux simplement placer ma variable, et dans l'autre je dois appeler la fonction set.
C'est un peu long désolé, mais j'essaie de comprendre ca depuis un moment et si je n'arrive pas à clarifier cela, je serai coincé.
Et je tourne en rond depuis un très looooonnnnngggggg moment désormais.
J'ai besoin de votre aide.
D'avance merci pour vos retours![]()
Partager