<?php
class Toto {
private $x = false;
protected $y = "";
public $z = null;
function methode() { }
}
echo "---- var_export ----\n";
var_export(new Toto());
echo "\n";
echo "---- print_r ----\n";
print_r(new Toto());
echo "\n";
echo "---- var_dump ----\n";
var_dump(new Toto());
echo "\n";
---- var_export ---- Toto::__set_state(array( 'x' => false, 'y' => '', 'z' => NULL, )) ---- print_r ---- Toto Object ( [x:Toto:private] => [y:protected] => [z] => ) ---- var_dump ---- /users/ensweb/www-prod/pres/oophp/demo/exPrintDebug.php:19: class Toto#3 (3) { private $x => bool(false) protected $y => string(0) "" public $z => NULL }
final
pour une méthode : la méthode ne peut pas être redéfinie dans une classe dérivéefinal
pour une classe : la classe ne peut pas être dérivée
<?php
class finalEx {
private $donnee = "exemple";
final function maj() {
return strtoupper($this->donnee);
}
}
final class finalExtend extends finalEx {
/* Fatal error : impossible de redéfinir maj()
public function maj() {
return $this->donnee;
} */
}
/* Fatal error : impossible de dériver finalExtend
class erreur extends finalExtend {
// impossible
}
*/
$class = new finalEx();
echo $class->maj();
echo "\n";
$classExtend = new finalExtend();
echo $classExtend->maj();
?>
EXEMPLE EXEMPLE
abstract
<?php
abstract class AbstractClass
{
// Force la classe étendue à définir cette méthode
abstract protected function getValue();
// méthode commune
public function printOut() {
print $this->getValue();
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass2";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();
$class2 = new ConcreteClass2;
$class2->printOut();
?>
ConcreteClass1ConcreteClass2
interface
class maClasse implements monInterface
array
et callable
)
function MaFonction(MaClasse $param)
: $param doit être une instance de la classe MaClasseint
ou string
:
voir la liste
TypeError
est envoyée si le type n'est pas respecté, sauf
si la conversion est possible !
declare(strict_types=1);
pour bénéficier du « typage strict »,
qui renverra bien une TypeError
dans tous les cas où le paramètre donné ne respecte pas
la déclaration. Sauf pour les int
, qui pourront toujours être convertis en float
.
function toto(): float { return 3.14; }
void
en plus
null
pour certains cas particuliers (par exemple des erreurs)
function titi(?int $x)
Un principe important en POO est de favoriser la composition plutôt que l'héritage pour mutualiser du code
En effet l'héritage a des conséquences pénibles, notamment le fait qu'à partir du moment où on a sous-classé une classe, il devient difficile de la faire évoluer (tout changement a des conséquences sur les classes filles)
cela contrevient à la modularisation du code — les classes sont trop dépendantes les unes des autres, alors que le but de la POO est plutôt d'essayer de créer des « boîtes noires » dont le comportement interne n'a pas d'influence à l'extérieur
En utilisant la composition, on garde l'indépendance entre les classes
le prix à payer est une syntaxe un peu plus lourde dans la classe, et l'obligation parfois d'écrire des méthodes de « délégation »
ex autom cell: comportement en fonction de la règle, en fonction de l'affichage voulu
Les traits de PHP sont (principalement) un moyen de faire de la composition, sans les inconvénients
trait MonTrait { function uneMethodeUtile() { } class Toto { use MonTrait; }
Toto
contient la méthode uneMethodeUtile
, comme si elle avait hérité de MonTrait
, sauf qu'il n'y a pas eu d'héritage :
Toto
__sleep
et __wakeup
: code à exécuter lors de la sérialisation et désérialisation d'un objet__get __set __call
pour gérer la surcharge objet (voir le manuel)