Contrairement à ce que beaucoup de gens pensent, rendre une classe immuable final
es no nécessaire.
L'argument standard pour rendre les classes immuables final
est que si vous ne le faites pas, les sous-classes peuvent ajouter la mutabilité, violant ainsi le contrat de la super-classe. Les clients de la classe supposeront l'immuabilité, mais seront surpris lorsque quelque chose mute sous leur nez.
Si on pousse cet argument à son extrême logique, alors todos les méthodes doivent être faites final
En effet, dans le cas contraire, une sous-classe pourrait remplacer une méthode d'une manière qui ne serait pas conforme au contrat de sa super-classe. Il est intéressant de noter que la plupart des programmeurs Java considèrent cela comme ridicule, mais sont d'une certaine manière d'accord avec l'idée que les classes immuables doivent être final
. Je soupçonne que cela a quelque chose à voir avec le fait que les programmeurs Java en général ne sont pas tout à fait à l'aise avec la notion d'immuabilité, et peut-être une sorte de pensée floue liée aux multiples significations de l'expression "immuable". final
en Java.
Se conformer au contrat de votre super-classe n'est pas quelque chose qui peut ou doit toujours être appliqué par le compilateur. Le compilateur peut faire respecter certains aspects de votre contrat (par exemple, un ensemble minimal de méthodes et leurs signatures de type), mais de nombreuses parties des contrats typiques ne peuvent pas être appliquées par le compilateur.
L'immuabilité fait partie du contrat d'une classe. C'est un peu différent de certaines choses auxquelles les gens sont plus habitués, car il dit ce que la classe (et toutes les sous-classes) ne peut pas En effet, alors que je pense que la plupart des programmeurs Java (et généralement OOP) ont tendance à penser aux contrats comme étant liés à ce qu'une classe puede faire, pas ce qu'il ne peut pas faire.
L'immuabilité affecte également plus qu'une seule méthode - elle affecte l'instance entière - mais ce n'est pas vraiment très différent de la façon dont l equals
y hashCode
dans le travail de Java. Ces deux méthodes ont un contrat spécifique défini dans le document Object
. Ce contrat énonce très soigneusement les choses que ces méthodes ne peut pas faire. Ce contrat est rendu plus spécifique dans les sous-classes. Il est très facile de surcharger equals
o hashCode
d'une manière qui viole le contrat. En fait, si vous surchargez une seule de ces deux méthodes sans l'autre, il y a de fortes chances que vous violiez le contrat. Il faut donc equals
y hashCode
ont été déclarés final
en Object
pour éviter cela ? Je pense que la plupart des gens diraient qu'ils ne devraient pas. De même, il n'est pas nécessaire de rendre les classes immuables final
.
Cela dit, la plupart de vos classes, immuables ou non, sont probablement devrait être final
. Voir Effective Java Deuxième édition Point 17 : "Concevoir et documenter pour l'héritage ou bien l'interdire".
Donc une version correcte de votre étape 3 serait : "Rendre la classe finale ou, lors de la conception pour le sous-classement, documenter clairement que toutes les sous-classes doivent continuer à être immuables."