web-dev-qa-db-fra.com

Quand utiliser Final en PHP?

Je sais quelle est la définition d'une classe finale, mais je veux savoir comment et quand la finale est vraiment nécessaire.

<?php
final class Foo extends Bar
{
   public function()
   {
     echo 'John Doe';
   }
}

Si je comprends bien, "final" lui permet d'étendre "Foo".

Quelqu'un peut-il expliquer quand et pourquoi "final" doit être utilisé? En d'autres termes, y a-t-il une raison pour laquelle une classe ne devrait pas être étendue?

Si par exemple la classe 'Bar' et la classe 'Foo' manquent de fonctionnalités, ce serait bien de créer une classe qui étend 'Bar'.

50
Inga Johansson

Pour une utilisation générale, je déconseille de rendre une classe "finale". Il peut y avoir des cas d'utilisation où cela a du sens: si vous concevez une API/un cadre complexe et que vous voulez vous assurer que les utilisateurs de votre cadre ne peuvent remplacer que les parties de la fonctionnalité que vous souhaitez qu'ils contrôlent, il pourrait être judicieux pour vous de restreindre cette possibilité et rendre certaines classes de base définitives.

par exemple. si vous avez une classe "Integer", il peut être judicieux de la rendre finale afin de garder les utilisateurs de votre formulaire de framework en priorité, disons, la méthode "add (...)" dans votre classe.

18
mhanisch

Il y a un bel article sur "Quand déclarer les classes finales" . Quelques citations:

TL; DR: Faites toujours vos classes final, si elles implémentent une interface, et qu'aucune autre méthode publique n'est définie

Pourquoi dois-je utiliser final?

  1. Empêcher la chaîne d'héritage massive de Doom
  2. Composition encourageante
  3. Forcer le développeur à penser à l'API publique des utilisateurs
  4. Forcer le développeur à réduire l'API publique d'un objet
  5. Une classe final peut toujours être rendue extensible
  6. extends interrompt l'encapsulation
  7. Vous n'avez pas besoin de cette flexibilité
  8. Vous êtes libre de changer le code

Quand éviter final:

Les classes finales ne fonctionnent efficacement que sous les hypothèses suivantes:

  1. Il existe une abstraction (interface) que la classe finale implémente
  2. Toute l'API publique de la classe finale fait partie de cette interface

Si l'une de ces deux conditions préalables est manquante, vous atteindrez probablement un moment où vous rendrez la classe extensible, car votre code ne s'appuie pas vraiment sur des abstractions.

P.S. Merci à @ocramius pour cette excellente lecture!

45
Nikita U.

La raison en est:

  1. Déclarer une classe comme finale l'empêche d'être sous-classée - point; c'est la fin de la ligne.

  2. La déclaration finale de chaque méthode d'une classe permet la création de sous-classes, qui ont accès aux méthodes de la classe parente, mais ne peuvent pas les remplacer. Les sous-classes peuvent définir leurs propres méthodes supplémentaires.

  3. Le mot clé final contrôle uniquement la possibilité de remplacer et ne doit pas être confondu avec le modificateur de visibilité privé. Une méthode privée n'est accessible par aucune autre classe; un dernier peut.

—— cité à la page 68 du livre PHP Object-Oriented Solutions by David Powers.

Par exemple:

final childClassname extends ParentsClassname {
    // class definition omitted
}

Cela couvre toute la classe, y compris toutes ses méthodes et propriétés. Toute tentative de création d'une classe enfant à partir de childClassname entraînerait désormais une erreur fatale. Mais, si vous devez autoriser la sous-classe de la classe mais empêcher qu'une méthode particulière ne soit remplacée, le mot-clé final passe devant la définition de la méthode.

class childClassname extends parentClassname { 
    protected $numPages;

    public function __construct($autor, $pages) {
        $this->_autor = $autor;
        $this->numPages = $pages;
    }

    final public function PageCount() { 
        return $this->numPages; 
    }
}

Dans cet exemple, aucun d'entre eux ne pourra remplacer la méthode PageCount().

11
li bing zhao

Une classe finale est une classe qui ne peut pas être étendue http://www.php.net/manual/en/language.oop5.final.php

Vous l'utiliseriez là où la classe contenait des méthodes que vous ne voulez pas spécifiquement remplacer. Cela peut être dû au fait que faire ne casserait votre application d'une manière ou d'une autre.

6
Matt Asbury