La POO n'est pas vraiment sur la façon dont une seule classe ressemble et fonctionne. C'est la manière dont les instances d'une ou de plusieurs classes à travailler ensemble.
C'est pourquoi vous voyez donc beaucoup d'exemples basés sur des "Voitures" et "les Gens" parce qu'ils font un travail vraiment bon d'illustrer ce principe.
À mon avis, leçons les plus importantes dans la programmation orientée objet sont l'encapsulation et le polymorphisme.
Encapsulation: Couplage de données et la logique qui utilise les données ensemble dans un concis, logique
Polymorphisme: La capacité d'un objet à regarder et/ou se comporter comme un autre.
Un bon exemple du monde réel de ce serait quelque chose comme un répertoire d'itérateur. Où est ce répertoire? C'est peut-être un dossier local, c'est peut-être à distance comme un serveur FTP. Qui sait!
C'est l'encapsulation:
abstract class DirectoryIterator
{
protected $root;
public function __construct( $root )
{
$this->root = $root;
}
abstract public function getAll();
}
class LocalDirectoryIterator extends DirectoryIterator
{
public function getAll()
{
// logic to get the current directory nodes and return them
}
}
class FtpDirectoryIterator extends DirectoryIterator
{
public function getAll()
{
// logic to get the current directory nodes and return them
}
}
Chaque classe/objet est responsable de sa propre méthode de récupération d'une liste de répertoire. Les données (variables) sont couplés à la logique (fonctions de classe i.e, méthodes) qui utilisent la dta.
Mais l'histoire n'est pas finie - rappelez-vous comment je l'ai dit, la programmation orientée objet est la façon dont les instances de classes à travailler ensemble, et pas toute seule classe ou d'un objet?
Ok, donc permet de faire quelque chose avec ces données d'impression à l'écran? Assurez-vous. Mais comment? Le HTML? Texte brut? RSS? Nous allons remédier à cela.
<?php
abstract class DirectoryRenderer
{
protected $iterator;
public function __construct( DirectoryIterator $iterator )
{
$this->iterator = $iterator;
}
public function render()
{
$dirs = $this->iterator->getAll();
foreach ( $dirs as $dir )
{
$this->renderDirectory( $dir );
}
}
abstract protected function renderDirectory( $directory );
}
class PlainTextDirectoryRenderer extends DirectoryRenderer
{
protected function renderDirectory( $directory )
{
echo $directory, "\n";
}
}
class HtmlDirectoryRenderer extends DirectoryRenderer
{
protected function renderDirectory( $directory )
{
echo $directory, "<br>";
}
}
Ok, maintenant nous avons un couple de la classe des arbres pour traverser et le rendu des listes de répertoire. Comment les utilisons-nous?
// Print a remote directory as HTML
$data = new HtmlDirectoryRenderer( new FtpDirectoryIterator( 'ftp://example.com/path' ) );
$data->render();
// Print a local directory a plain text
$data = new PlainTextDirectoryRenderer( new LocalDirectoryIterator( '/home/pbailey' ) );
$data->render();
Maintenant, je sais ce que vous pensez, "Mais Pierre, je n'ai pas besoin de ces grands de la classe des arbres pour cela!" mais si vous pensez que vous êtes à côté de la question, comme je soupçonne que vous avez été avec "Voiture" et "les Gens" exemples. Ne pas se concentrer sur les détails de l'exemple - au lieu d'essayer de comprendre ce qui se passe ici.
Nous avons créé deux classes d'arbres où l'on (DirectoryRenderer
) utilise l'autre (DirectoryIterator
) dans un de la manière prévue - c'est souvent désigné comme un contrat. Une instance de DirectoryRenderer
ne se soucie pas de quel type d'instance d' DirectoryIterator
il reçoit, ni les instances de DirectoryIterator se soucient de leur être rendus.
Pourquoi? Parce que nous avons conçu de cette façon. Ils suffit de la brancher dans l'autre et le travail. C'est de la POO en action.