Classes abstraites et finales

Publié dans PHP objet | Marqué avec , , , , , , , , ,
Share

Les notions de classes abstraites et classes finales permettent de sécuriser notre programmation PHP, dans le sens qu’elles permettent d’éviter qu’un programmeur, reprenant notre code, n’en contourne la logique et s’égare ainsi sur une fausse piste.
En effet :

  • Class abstraite : class qui ne peut être instanciée, il est donc OBLIGATOIRE de créer une class héritante de cette class pour s’en servir. Utile lorsque l’on créé une class générique qui ne servira qu’à créer des sous class et non à être instanciée. Une telle class ne contient donc pas de __construct() puisqu’elle n’est pas instanciée. Mot clef : abstract.
  • Class finale : class qui NE PEUT PLUS avoir de sous-class, c’est-à-dire de class héritante. Les méthodes de cette class ne pourront être surchargées (réécrites, redéfinies). Mot clef : final. De la même manière, on peut aussi déclarer des méthodes abstraites et finales.
  • Méthode abstraite : méthode qui doit OBLIGATOIREMENT être surchargée (réécrite, ou redéfinie). Une class contenant une méthode abstraite doit aussi être abstraite. Mot clef : abstract.
  • Méthode finale : méthode qui NE PEUT ÊTRE surchargée (réécrite, redéfinie). Une class finale s’applique sur toutes les méthodes ou attributs de la classe, alors qu’ici on ne touche qu’à une seule méthode. Mot clef : final. Pour bien comprendre ces 2 notions et en saisir mieux l’intérêt voici plusieurs exemples, un pour chaque cas.

Class et méthodes abstraites

 abstract class Site {
	protected $type;
	protected $name;
	public function getType()
	{
		return $this->type;
	}
	public function getName()
	{
		return $this->name;
	}
}
$monSite = new Site();
echo $monSite->getType(); // Erreur : on tente d'instancier une classe abstraite


Ici, on a créé une classe abstraite « Site », qui est donc censé représentée un site Internet en général. Cela n’est pas dépourvue de logique puisque cette class telle quelle ne suffit pas à définir un site, il est nécessaire de lui ajouter des attributs, des méthodes et de surcharger les éléments déjà existants. Et donc si on tente d’instancier cette class abstraite : jolie erreur…

Fatal error: Cannot instantiate abstract class Site in /var/www/test.php on line 5

Par contre, si on créé une sous-classe, aucun problème. Et maintenant si on ajoutait une méthode abstraite…

abstract class Site
{
	protected $type;
	protected $name;
	abstract function afficherArticle();
	public function getType()
	{
		return $this->type;
	}
	public function getName()
	{
		return $this->name;
	}
}

class Blog extends Site
{
	public function </strong>construct($name)
	{
		$this->name = $name;
		$this->type = 'blog';
	}
}

$monBlog = new Blog('30 minutes par jour');
echo $monSite->getType(); // Erreur : une méthode abstraite n'a pas été surchargée

Et encore une erreur :

Fatal error: Class Blog contains 1 abstract method and must therefore be declared abstract or implement the remaining method (Site::afficherArticle) in /var/www/test.php on line 7

Mais si on surcharge la méthode abstraite en question : tout va bien !

 class Blog extends Site {
	public function <strong>construct($name)
	{
		$this->name = $name;
		$this->type = 'blog';
	}
	function afficherArticle()
	{
		echo 'Ceci est un magnifique article. Qui l\'eut cru ?';
	}
}

$monBlog = new Blog('30 minutes par jour');
echo $monSite->getType();

Qui nous affiche bien le mot « blog ».

Class et méthodes finales

Bon, maintenant imaginons que j’ai finis toute la programmation de mon super blog 30 minutes par jour et que cela se résume en la classe Blog30minparjour ci-dessous ! Du coup, histoire de ne pas faire de bêtises, j’ai mis cette classe en final. (ce n’est sûrement pas comme ça dans la vraie vie, mais qu’importe, on comprend l’idée)

 final class Blog30minparjour
{
	public $name= '30minparjour';
	public $type;
	function </strong>construct($type)
	{
		$this->$type;
	}
	function fairePleinDeTruc()
	{
		echo 'Cette fonction fait tout pour 30 minutes par jour !<br />';
	}
}

Maintenant, si je souhaite faire une sous classe pour mon nouveau blog 10 minutes par mois, je pourrais être flemmard et faire :

class Blog10minparmois extends Blog30minparjour {
	public $name = '10minparmois';
	function fairePleinDeTruc()
	{
		echo 'Cette fonction fait encore plus de choses, enfin, je crois...<br />';
	}
}

Mais là, PHP me rappelle à l’ordre (la flemmardise c’est mal !) en me renvoyant une erreur. En effet, je tente de surcharger des attributs et des méthodes qui font parties d’une classe finale.
Bon, reprenons le même exemple, sauf que cette fois-ci seul la fonction fairePleinDeTruc() est finale.

class Blog30minparjour
{
	public $name= '30minparjour';
	public $type;
	function <strong>construct($type)
	{
		$this->$type;
	}
	final function fairePleinDeTruc()
	{
		echo 'Cette fonction fait tout pour 30 minutes par jour !<br />';
	}
}

class Blog10minparmois extends Blog30minparjour
{
	public $name = '10minparmois';
}

$blog = new Blog10minparmois('blog');
$blog->fairePleinDeTruc();

Aucun problème, puisque je n’ai pas surchargé ma méthode fairePleinDeTruc() dans la sous classe Blog10minparmois. « Cette fonction fait tout pour 30 minutes par jour ! » s’affiche bien.
Par contre, si je cherche à surcharger fairePleinDeTruc(), PHP n’est pas content :

class Blog30minparjour
{
	public $name= '30minparjour';
	public $type;
	function </strong>construct($type)
	{
		$this->$type;
	}
	final function fairePleinDeTruc()
	{
		echo 'Cette fonction fait tout pour 30 minutes par jour !<br />';
	} } class Blog10minparmois extends Blog30minparjour {
	public $name = '10minparmois';
	function fairePleinDeTruc()
	{
		echo 'Cette fonction fait encore plus de choses, enfin, je crois...<br />';
	}
}

Eh bien voilà ! 2 petits mots clefs qui peuvent servir… parfois. Je me demande si je m’en servirais un jour.

2 Responses to Classes abstraites et finales

Répondre à jb Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *