Question

J'utilise le classe Scanner pour la lecture de plusieurs fichiers similaires. Je voudrais étendre à assurer qu'ils faire utiliser le même delimiter et je peux aussi ajouter des méthodes comme skipUntilYouFind (String thisHere) que tous valables pour tous.

Je peux faire une classe utilitaire qui les contiennent, ou intégrer la classe Scanner comme une variable dans une autre classe, mais cela est plus lourd.

J'ai trouvé quelques raisons pour déclarer une classe finale, mais pourquoi est-il fait ici?

Était-ce utile?

La solution

Probablement parce que son extension et écrasez certaines des méthodes de ce serait probablement le casser. Et ce qui rend plus facile aux méthodes Ecraser exposerait à une grande partie du fonctionnement interne, donc si dans l'avenir, ils décident de changer les (pour une performance ou d'autres raisons), il serait plus difficile pour eux de changer la classe sans casser toutes les classes que l'étendre.

Par exemple, considérez la méthode suivante dans la classe:

public boolean nextBoolean()  {
    clearCaches();
    return Boolean.parseBoolean(next(boolPattern()));
}

Dites que vous voulez écraser parce que vous voulez faire « awesome » évaluer dans un booléen « vrai » (quelle qu'en soit la raison). Si vous écrasez, vous ne pouvez pas appeler super.nextBoolean (), car cela consommera le prochain jeton à l'aide de la logique par défaut. Mais si vous n'appelez super.nextBoolean (), clearCaches () ne seront pas appelés, briser éventuellement les autres méthodes ne sont pas écrasées. Vous ne pouvez pas appeler clearCaches () parce qu'il est privé. S'ils l'ont fait protégé, mais alors rendu compte que cela cause un problème de performance, et je voulais une nouvelle implémentation qui ne cache plus claires, ils pourraient briser votre mise en œuvre qui serait encore écrasée appellerez cela.

Donc, fondamentalement, il est donc ils peuvent facilement changer les pièces cachées à l'intérieur de la classe, qui sont assez complexes, et vous protéger de faire une classe enfant brisée (ou une classe qui pourrait être facilement brisée).

Autres conseils

Je suppose que cela est dû à des raisons de sécurité. Cette classe lit l'entrée de l'utilisateur, de sorte que quelqu'un avec de mauvaises intentions pourrait l'étendre, modifier son comportement et vous seriez vissé. Si elle est définitive, il est facile pour le méchant, parce que s'il fait son propre type de scanner (non java.util.Scanner), les principes de Polymorphisme seraient brisés. Voir le méchant peut être assez intelligent pour écrire un bot / script qui fait automatiquement sur des serveurs distants ... Il peut même le faire par classloading dynamique application compilée.

Je pense que le lien fourni explique tout.

Dans votre cas, il semble que vous devriez préférer la composition au lieu de l'héritage de toute façon. Vous créez un utilitaire qui a un comportement prédéfini, et qui peut cacher certaines (ou toutes) des détails de la classe du scanner.

Je l'ai vu de nombreuses implémentations que l'héritage utilisé afin de changer un comportement. Le résultat final est généralement une conception monolithique, et dans certains cas, un contrat rompu, et / ou un comportement cassé.

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