Tout d'abord, je recommande cet article: Java: quand créer une classe finale
S'ils le font, quand l'utilisent-ils pour que je puisse mieux le comprendre et savoir quand l'utiliser.
Une final
classe est simplement une classe qui ne peut pas être étendue .
(Cela ne signifie pas que toutes les références aux objets de la classe agiraient comme si elles étaient déclarées comme final
.)
Quand il est utile de déclarer une classe comme finale est couvert dans les réponses à cette question:
Si Java est orienté objet et que vous déclarez une classe final
, cela n'arrête-t-il pas l'idée que la classe ait les caractéristiques des objets?
Dans un certain sens, oui.
En marquant une classe comme finale, vous désactivez une fonctionnalité puissante et flexible du langage pour cette partie du code. Cependant, certaines classes ne devraient pas (et dans certains cas ne peuvent pas) être conçues pour prendre en compte le sous-classement dans le bon sens. Dans ces cas, il est logique de marquer la classe comme finale, même si cela limite la POO. (N'oubliez pas cependant qu'une classe finale peut encore prolonger une autre classe non finale.)
En Java, les éléments avec le
final
modificateur ne peuvent pas être modifiés!Cela inclut les classes finales, les variables finales et les méthodes finales:
la source
final
modificateur ne peuvent pas être modifiés!", Est trop catégorique et, en fait, pas entièrement correcte. Comme l'a dit Grady Booch, "Un objet a un état, un comportement et une identité". Bien que nous ne puissions pas changer l'identité d'un objet une fois que sa référence a été marquée comme finale, nous avons une chance de changer son état en attribuant de nouvelles valeurs à ses non-final
champs (à condition, bien sûr, qu'il les ait.) Quiconque est l'intention d'obtenir une certification Oracle Java (comme 1Z0-808, etc.) devrait garder cela à l'esprit car il pourrait y avoir des questions sur cet aspect à l'examen ...Un scénario où final est important, lorsque vous souhaitez empêcher l'héritage d'une classe, pour des raisons de sécurité. Cela vous permet de vous assurer que le code que vous exécutez ne peut pas être remplacé par quelqu'un.
Un autre scénario est pour l'optimisation: je semble me souvenir que le compilateur Java inline certains appels de fonction des classes finales. Donc, si vous appelez
a.x()
et que a est déclaréfinal
, nous savons au moment de la compilation quel sera le code et nous pouvons l'intégrer dans la fonction appelante. Je n'ai aucune idée si cela est réellement fait, mais avec le final c'est une possibilité.la source
Le meilleur exemple est
qui est une classe immuable et ne peut pas être étendue. Bien sûr, il n'y a pas que rendre la finale de la classe immuable.
la source
Lecture pertinente: The Open-Closed Principle de Bob Martin.
Citation clé:
Le
final
mot-clé est le moyen de l'imposer en Java, qu'il soit utilisé sur des méthodes ou sur des classes.la source
final
rend- il pas la classe fermée pour l'extension plutôt que ouverte? Ou est-ce que je le prends trop à la lettre?final
sur une déclaration de classe / méthode n'aurait aucun sens si vous souhaitez que le code d'implémentation soit fermé pour modification mais ouvert pour extension par héritage.Si vous imaginez la hiérarchie des classes comme un arbre (comme c'est le cas en Java), les classes abstraites ne peuvent être que des branches et les classes finales sont celles qui ne peuvent être que des feuilles. Les classes qui n'appartiennent à aucune de ces catégories peuvent être à la fois des branches et des feuilles.
Il n'y a pas de violation des principes OO ici, le final fournit simplement une symétrie sympa.
En pratique, vous souhaitez utiliser final si vous voulez que vos objets soient immuables ou si vous écrivez une API, pour signaler aux utilisateurs de l'API que la classe n'est tout simplement pas destinée à être étendue.
la source
Le mot
final
- clé lui - même signifie que quelque chose est définitif et n'est censé être modifié d'aucune façon. Si une classe est marquée,final
elle ne peut pas être étendue ou sous-classée. Mais la question est pourquoi marquons-nous une classefinal
? OMI, il existe plusieurs raisons:J'ai entendu dire que la classe de marquage
final
améliore l'efficacité, mais franchement, je n'ai pas pu trouver cet argument de poids.Peut-être oui, mais parfois c'est le but recherché. Parfois, nous faisons cela pour obtenir de plus grands avantages de la sécurité, etc. en sacrifiant la capacité de cette classe à être étendue. Mais une classe finale peut encore étendre une classe si nécessaire.
D'un autre côté, nous devrions préférer la composition à l'héritage et le
final
mot - clé aide réellement à faire respecter ce principe.la source
Soyez prudent lorsque vous faites un cours "final". Parce que si vous voulez écrire un test unitaire pour une classe finale, vous ne pouvez pas sous-classer cette classe finale afin d'utiliser la technique de rupture de dépendance "Subclass and Override Method" décrite dans le livre de Michael C. Feathers "Working Effectively with Legacy Code" . Dans ce livre, Feathers a déclaré: «Sérieusement, il est facile de croire que scellé et final sont une erreur erronée, qu'ils n'auraient jamais dû être ajoutés aux langages de programmation. Mais la vraie faute nous incombe. Lorsque nous dépendons directement de bibliothèques qui sont hors de notre contrôle, nous demandons juste des ennuis. "
la source
final class
peut éviter de casser l'API publique lorsque vous ajoutez de nouvelles méthodesSupposons que sur la version 1 de votre
Base
classe vous fassiez:et un client fait:
Ensuite, si dans la version 2, vous souhaitez ajouter une
method
méthode àBase
:cela casserait le code client.
Si nous l'avions utilisé à la
final class Base
place, le client n'aurait pas pu hériter et l'ajout de méthode ne casserait pas l'API.la source
Si la classe est marquée
final
, cela signifie que la structure de la classe ne peut pas être modifiée par quelque chose d'extérieur. Lorsque cela est le plus visible, c'est lorsque vous effectuez un héritage polymorphe traditionnel,class B extends A
cela ne fonctionnera tout simplement pas. C'est essentiellement un moyen de protéger certaines parties de votre code (dans une large mesure) .Pour clarifier, le marquage de classe
final
ne marque pas ses champs en tantfinal
que tels et ne protège donc pas les propriétés de l'objet mais la structure de classe réelle à la place.la source
POUR RÉSOUDRE LE PROBLÈME DE LA CLASSE FINALE:
Il y a deux façons de faire une finale de classe. La première consiste à utiliser le mot-clé final dans la déclaration de classe:
La deuxième façon de rendre une classe finale est de déclarer tous ses constructeurs privés:
Le marquer comme final vous évite les ennuis si vous découvrez qu'il s'agit bien d'une finale, pour démontrer le regard sur cette classe de test. semble public à première vue.
Malheureusement, comme le seul constructeur de la classe est privé, il est impossible d'étendre cette classe. Dans le cas de la classe Test, il n'y a aucune raison que la classe soit finale. La classe Test est un bon exemple de la façon dont les classes finales implicites peuvent causer des problèmes.
Vous devez donc la marquer comme finale lorsque vous créez implicitement une finale de classe en rendant son constructeur privé.
la source
Une classe finale est une classe qui ne peut pas être étendue. Des méthodes peuvent également être déclarées comme finales pour indiquer qu'elles ne peuvent pas être remplacées par des sous-classes.
Il peut être particulièrement utile d'empêcher la classe d'être sous-classée si vous écrivez des API ou des bibliothèques et que vous souhaitez éviter d'être étendu pour modifier le comportement de la base.
la source
Un avantage de garder une classe comme finale: -
La classe de chaîne est conservée finale afin que personne ne puisse remplacer ses méthodes et modifier la fonctionnalité. par exemple, personne ne peut changer la fonctionnalité de la méthode length (). Il renverra toujours la longueur d'une chaîne.
Le développeur de cette classe ne voulait que personne ne change la fonctionnalité de cette classe, il l'a donc gardée comme finale.
la source
Oui, parfois, vous pouvez souhaiter cela, soit pour des raisons de sécurité ou de vitesse. Cela se fait également en C ++. Il ne peut pas être que applicable pour les programmes, mais plus encore pour les cadres. http://www.glenmccl.com/perfj_025.htm
la source
En java, le mot clé final utilise pour les occasions ci-dessous.
la source
Les classes finales ne peuvent pas être prolongées. Donc, si vous voulez qu'une classe se comporte d'une certaine manière et que personne ne remplace les méthodes (avec éventuellement du code moins efficace et plus malveillant), vous pouvez déclarer la classe entière comme méthodes finales ou spécifiques que vous ne voulez pas être modifié.
Puisque déclarer une classe n'empêche pas une classe d'être instanciée, cela ne signifie pas qu'elle empêchera la classe d'avoir les caractéristiques d'un objet. C'est juste que vous devrez vous en tenir aux méthodes telles qu'elles sont déclarées dans la classe.
la source
pensez à FINAL comme au «bout de la ligne» - ce type ne peut plus produire de progéniture. Donc, quand vous le voyez de cette façon, il y a des tonnes de scénarios du monde réel que vous rencontrerez qui vous obligeront à signaler un marqueur de fin de ligne à la classe. Il s'agit d'une conception pilotée par domaine - si votre domaine exige qu'une ENTITY (classe) donnée ne puisse pas créer de sous-classes, marquez-la comme FINALE.
Je dois noter que rien ne vous empêche d'hériter d'une classe "devrait être étiquetée comme finale". Mais cela est généralement classé comme «abus d'héritage», et cela est fait parce que le plus souvent, vous souhaitez hériter d'une fonction de la classe de base de votre classe.
La meilleure approche consiste à examiner le domaine et à le laisser dicter vos décisions de conception.
la source
Comme indiqué ci-dessus, si vous voulez que personne ne puisse modifier la fonctionnalité de la méthode, vous pouvez la déclarer finale.
Exemple: chemin du fichier du serveur d'applications pour le téléchargement / téléchargement, fractionnement de la chaîne en fonction de l'offset, ces méthodes vous pouvez le déclarer final afin que ces fonctions de méthode ne soient pas modifiées. Et si vous voulez de telles méthodes finales dans une classe distincte, définissez cette classe comme classe finale. Ainsi, la classe finale aura toutes les méthodes finales, alors que la méthode finale peut être déclarée et définie dans la classe non finale.
la source
La classe Android Looper en est un bon exemple pratique. http://developer.android.com/reference/android/os/Looper.html
La classe Looper fournit certaines fonctionnalités qui ne sont PAS destinées à être remplacées par une autre classe. Par conséquent, aucune sous-classe ici.
la source
Disons que vous avez une
Employee
classe qui a une méthodegreet
. Lorsque lagreet
méthode est appelée, elle s'imprime simplementHello everyone!
. Voilà donc le comportement attendu de lagreet
méthodeMaintenant, laissez la
GrumpyEmployee
sous - classeEmployee
et remplacer lagreet
méthode comme indiqué ci-dessous.Maintenant, dans le code ci-dessous, jetez un œil à la
sayHello
méthode. Il prend l'Employee
instance comme paramètre et appelle la méthode de bienvenue en espérant qu'elle diraitHello everyone!
Mais ce que nous obtenons estGet lost!
. Ce changement de comportement est dû àEmployee grumpyEmployee = new GrumpyEmployee();
Cette situation peut être évitée si le
Employee
cours a été faitfinal
. Imaginez simplement le chaos qu'un programmeur effronté pourrait causer siString
Class n'était pas déclaré commefinal
.la source
La classe finale ne peut pas être prolongée davantage. Si nous n'avons pas besoin de rendre une classe héritable en java, nous pouvons utiliser cette approche.
Si nous avons juste besoin de créer des méthodes particulières dans une classe pour ne pas les remplacer, nous pouvons simplement mettre le mot-clé final devant elles. Là, la classe est toujours héritable.
la source
L'orientation d'objet n'est pas une question d'héritage, c'est une question d'encapsulation. Et l'héritage rompt l'encapsulation.
Déclarer une finale de classe est parfaitement logique dans de nombreux cas. Tout objet représentant une «valeur» comme une couleur ou une somme d'argent pourrait être définitif. Ils sont autonomes.
Si vous écrivez des bibliothèques, rendez vos classes finales à moins que vous ne les indentiez explicitement comme dérivées. Sinon, les gens peuvent dériver vos classes et remplacer les méthodes, brisant vos hypothèses / invariants. Cela peut également avoir des conséquences sur la sécurité.
Joshua Bloch dans «Effective Java» recommande de concevoir explicitement pour l'héritage ou de l'interdire et il note que la conception pour l'héritage n'est pas si simple.
la source