Question

Quelles sont les bonnes raisons d'interdire l'héritage en Java, par exemple en utilisant des classes finales ou des classes utilisant un seul constructeur privé sans paramètre? Quelles sont les bonnes raisons de rendre une méthode finale?

Était-ce utile?

La solution

Votre meilleure référence ici est le point 19 de l'excellent livre de Joshua Bloch intitulé "Effective Java", intitulé "Conception et documentation pour héritage ou bien l'interdire". (Il s'agit du point 17 dans la deuxième édition et du point 15 dans la première édition.) Vous devriez vraiment le lire, mais je vais résumer.

L’interaction des classes héritées avec leurs parents peut être surprenante et imprévisible si l’ancêtre n’a pas été conçu pour en hériter.

Les classes doivent donc être de deux types:

  1. Les classes conçues pour être étendues , et avec suffisamment de documentation pour décrire la procédure à suivre

  2. Les classes marquées final

Si vous écrivez du code purement interne, cela peut être un peu excessif. Cependant, l’effort supplémentaire impliqué dans l’ajout de cinq caractères à un fichier de classe est très faible. Si vous écrivez uniquement à des fins de consommation interne, un futur codeur peut toujours supprimer le "final" - vous pouvez le considérer comme un avertissement indiquant que "cette classe n'a pas été conçue dans un souci d'héritage".

Autres conseils

Vous pouvez rendre une méthode finale afin que les classes de substitution ne puissent pas modifier le comportement pris en compte par d'autres méthodes. Les méthodes appelées dans les constructeurs sont souvent déclarées finales afin d'éviter toute mauvaise surprise lors de la création d'objets.

Une des raisons pour rendre une classe finale serait si vous voulez forcer la composition sur l’héritage. Ceci est généralement souhaitable pour éviter un couplage étroit entre les classes.

Il existe trois cas d'utilisation de méthodes finales.

  1. Pour éviter que la classe dérivée ne remplace une fonctionnalité de classe de base particulière.
  2. Ceci est pour des raisons de sécurité, où la classe de base fournit certaines fonctionnalités essentielles du framework où la classe dérivée n'est pas supposée la changer.
  3. Les méthodes finales sont plus rapides que les méthodes d'instance, car le concept de table virtuelle n'est pas utilisé pour les méthodes finales et privées. Alors, où que ce soit, essayez d’utiliser les méthodes finales.

Objectif de la finale d'une classe:

Pour qu'aucun corps ne puisse étendre ces classes et changer leur comportement.

Exemple: la classe Wrapper Integer est une classe finale. Si cette classe n'est pas finale, chacun peut étendre Integer dans sa propre classe et modifier le comportement de base de la classe entière. Pour éviter cela, Java a créé toutes les classes de wrapper en tant que classes finales.

vous pouvez créer des objets immuables ( http://fr.wikipedia.org/wiki/Immutable_object ), vous pouvez créer un singleton ( http://fr.wikipedia.org/wiki/ Singleton_pattern ) ou vous pouvez empêcher quelqu'un de remplacer la méthode pour des raisons d'efficacité, de sécurité ou de sécurité.

L'héritage est comme une tronçonneuse - très puissant, mais affreux entre de mauvaises mains. Soit vous concevez une classe dont vous héritez (ce qui peut limiter la flexibilité et prendre beaucoup plus de temps), soit vous devez l’interdire.

Voir les articles 16 et 17 de Effective 2ème édition Java, ou mon billet de blog " ; Droits de succession " .

Hmmm ... Je peux penser à deux choses:

Vous pourriez avoir une classe qui traite de certains problèmes de sécurité. En le sous-classant et en fournissant à votre système la version de ce dernier, un attaquant peut contourner les restrictions de sécurité. Par exemple. votre application peut prendre en charge des plugins et si un plugin peut simplement sous-classer vos classes relatives à la sécurité, il peut utiliser cette astuce pour en faire passer une version sous-classée. Cependant, c’est plutôt quelque chose que Sun doit gérer en ce qui concerne les applets et autres, peut-être pas un cas si réaliste.

Une solution beaucoup plus réaliste consiste à éviter qu'un objet ne devienne mutable. Par exemple. puisque les chaînes sont immuables, votre code peut en toute sécurité en conserver les références

 String blah = someOtherString;

au lieu de copier la chaîne en premier. Toutefois, si vous pouvez sous-classer String, vous pouvez y ajouter des méthodes permettant de modifier la valeur de la chaîne. Aucun code ne peut désormais plus compter sur le fait que la chaîne restera la même si elle ne fait que copier la chaîne ci-dessus. chaîne.

Empêcher les gens de faire des choses qui pourraient créer de la confusion pour eux-mêmes et pour les autres. Imaginez une bibliothèque de physique où vous avez des constantes ou des calculs définis. Sans le mot-clé final, quelqu'un pourrait se présenter et redéfinir les calculs ou les constantes de base qui ne devraient JAMAIS changer.

De même, si vous écrivez une classe source fermée commerciale, vous ne voudrez peut-être pas que les utilisateurs puissent modifier les fonctionnalités ultérieurement, en particulier si vous devez le soutenir et que les utilisateurs ont ignoré votre méthode et se plaignent de ce que l'appeler donne des résultats inattendus.

Si vous marquez les classes et les méthodes comme finales, vous remarquerez peut-être un léger gain de performances, car le moteur d’exécution n’a pas à rechercher la bonne méthode de classe à appeler pour un objet donné. Les méthodes non finales sont marquées comme virtuelles afin de pouvoir être correctement étendues si nécessaire. Les méthodes finales peuvent être directement liées ou compilées en ligne dans la classe.

Vous souhaitez rendre une méthode finale afin que le remplacement des classes ne modifie pas son comportement. Lorsque vous souhaitez pouvoir modifier le comportement, rendez la méthode publique. Lorsque vous substituez une méthode publique, elle peut être modifiée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top