206 votes

De bonnes raisons pour interdire l'héritage en Java ?

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 ?

1 votes

Pédantisme : Le constructeur par défaut est celui généré pour vous par le compilateur Java si vous n'en écrivez pas explicitement un dans votre code. Vous voulez dire le constructeur sans argument.

0 votes

N'est-ce pas le "constructeur implicite par défaut" ?

2 votes

" Vous n'êtes pas obligé de fournir des constructeurs pour votre classe, mais vous devez faire attention en le faisant. Le compilateur fournit automatiquement un constructeur par défaut, sans argument, pour toute classe sans constructeur." java.sun.com/docs/books/tutorial/java/javaOO/constructeurs.html - John Topley

204voto

DJClayworth Points 11288

Votre meilleure référence ici est le point 19 de l'excellent livre de Joshua Bloch "Effective Java", intitulé "Design and document for inheritance or else prohibit it". (C'est le point 17 dans la deuxième édition et le 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 être hérité.

Les cours devraient donc être de deux types :

  1. Classes conçu pour être **étendu **, et avec une documentation suffisante pour décrire comment le faire

  2. Classes marqué **final **

Si vous écrivez du code purement interne, cela peut être un peu excessif. Toutefois, l'effort supplémentaire que représente l'ajout de cinq caractères à un fichier de classe est très faible. Si vous écrivez uniquement pour une consommation interne, un futur codeur pourra toujours supprimer le "final" - vous pouvez le considérer comme un avertissement disant "cette classe n'a pas été conçue avec l'héritage en tête".

1 votes

C'est une bonne réponse, mais c'est un peu exagéré dans la plupart des situations.

7 votes

D'après mon expérience, ce n'est pas excessif si quelqu'un d'autre que moi utilise le code. Je n'ai jamais compris pourquoi Java a des méthodes surchargées par défaut.

12 votes

Pour comprendre certains éléments d'Effective Java, vous devez comprendre la vision de Josh sur le design. Il dit qu'il faut toujours concevoir les interfaces de classe comme s'il s'agissait d'une API publique. Je pense que l'opinion majoritaire est que cette approche est généralement trop lourde et inflexible. (YAGNI, etc.)

31voto

Bill the Lizard Points 147311

Vous pourriez vouloir faire d'une méthode une méthode finale afin que les classes de surcharge ne puissent pas modifier le comportement qui est prévu dans d'autres méthodes. Les méthodes appelées dans les constructeurs sont souvent déclarées finales afin de ne pas avoir de mauvaises surprises lors de la création d'objets.

0 votes

Je n'ai pas bien compris cette réponse. Si vous le voulez bien, pourriez-vous expliquer ce que vous entendez par "les classes de surcharge ne peuvent pas modifier le comportement qui est pris en compte dans d'autres méthodes" ? Je demande d'abord parce que je n'ai pas compris la phrase, et ensuite parce que Netbeans recommande que l'une de mes fonctions que j'appelle depuis le constructeur, soit final .

1 votes

@Nav Si vous rendez une méthode finale, alors une classe surchargeante ne pourra pas avoir sa propre version de cette méthode (ou alors ce sera une erreur de compilation). De cette façon, vous savez que le comportement que vous implémentez dans cette méthode ne changera pas plus tard lorsque quelqu'un d'autre étendra la classe.

0 votes

C# vous avertira si vous appelez des méthodes virtuelles à partir d'un constructeur. Les méthodes appelées dans les constructeurs reflètent en quelque sorte ceci.

22voto

John Topley Points 58789

Une raison de rendre une classe finale serait de vouloir forcer la composition plutôt que l'héritage. Ceci est généralement souhaitable pour éviter un couplage étroit entre les classes.

18voto

user1923551 Points 502

Il existe trois cas d'utilisation pour lesquels vous pouvez opter pour les méthodes finales.

  1. Pour éviter que la classe dérivée ne surcharge une fonctionnalité particulière de la classe de base.
  2. C'est pour des raisons de sécurité, lorsque la classe de base fournit certaines fonctionnalités importantes du cadre et que la classe dérivée n'est pas censée les modifier.
  3. Les méthodes finales sont plus rapides que les méthodes d'instance, car il n'y a pas d'utilisation du concept de table virtuelle pour les méthodes finales et privées. Donc, chaque fois que vous en avez la possibilité, essayez d'utiliser les méthodes finales.

Objectif de rendre une classe finale :

Pour que personne ne puisse étendre ces classes et changer leur comportement.

Ex : La classe wrapper Integer est une classe finale. Si cette classe n'est pas finale, alors n'importe qui peut étendre Integer dans sa propre classe et changer le comportement de base de la classe Integer. Pour éviter cela, Java a fait de toutes les classes wrapper des classes finales.

0 votes

Je ne suis pas très convaincu par votre exemple. Si c'est le cas, alors pourquoi ne pas rendre les méthodes et les variables finales au lieu de rendre la classe entière finale. Pouvez-vous s'il vous plaît éditer votre réponse avec les détails.

4 votes

Même si vous faites en sorte que toutes les variables et méthodes soient finales, d'autres personnes peuvent hériter de votre classe et ajouter des fonctionnalités supplémentaires et modifier le comportement de base de votre classe.

7 votes

> Si cette classe n'est pas finale, alors n'importe qui peut étendre Integer dans sa propre classe et changer le comportement de base de la classe Integer. Admettons que cela soit autorisé et que cette nouvelle classe s'appelle DerivedInteger cela ne change toujours pas la classe Integer originale, et quiconque utilise DerivedInteger le fait à ses risques et périls, donc je ne comprends toujours pas pourquoi c'est un problème.

13voto

Ray Tayek Points 4635

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X