web-dev-qa-db-fra.com

Quand et pourquoi voudriez-vous sceller une classe?

En C # et C++/CLI, le mot clé sealed (ou NotInheritable en VB) est utilisé pour protéger une classe de toute chance d'héritage (la classe ne sera pas héritable). Je sais qu'une caractéristique de la programmation orientée objet est l'héritage et je pense que l'utilisation de sealed va à l'encontre de cette fonctionnalité, elle arrête l'héritage. Existe-t-il un exemple qui montre l'avantage de sealed et quand il est important de l'utiliser?

79
Aan
  1. Sur une classe qui implémente des fonctionnalités de sécurité, de sorte que l'objet d'origine ne peut pas être "emprunté".

  2. Plus généralement, j'ai récemment échangé avec une personne de Microsoft, qui m'a dit qu'elle avait essayé de limiter l'héritage aux endroits où cela avait vraiment du sens, car cela devient coûteux en termes de performances s'il n'est pas traité.
    Le mot clé scellé indique au CLR qu'il n'y a pas de classe plus bas pour rechercher des méthodes, ce qui accélère les choses.

Dans la plupart des outils d'amélioration des performances sur le marché de nos jours, vous trouverez une case à cocher qui scellera toutes vos classes qui ne sont pas héritées.
Attention cependant, car si vous voulez autoriser la découverte de plugins ou d'assemblys via MEF, vous rencontrerez des problèmes.

89
Louis Kottmann

Un addendum à l'excellente réponse de Baboon:

  1. Si une classe n'est pas conçue pour l'héritage, les sous-classes peuvent casser les invariants de classe . Cela ne s'applique vraiment que si vous créez une API publique, bien sûr, mais comme je le dis, je scelle toute classe non explicitement conçue pour être sous-classée.

Sur une note connexe, applicable aux classes non scellées uniquement: toute méthode créée virtual est un point d'extension, ou du moins il devrait être un point d'extension. La déclaration des méthodes virtual devrait également être une décision consciente. (En C #, c'est une décision consciente; en Java ce n'est pas le cas.)


[~ # ~] modifier [~ # ~] : Quelques liens pertinents:

Notez également que Kotlin scelle les classes par défaut; son mot clé open est l'opposé de final ou sealed de C # de Java. (Pour être sûr, il n'y a pas d'accord universel que c'est une bonne chose .)

14

Le marquage d'une classe comme Sealed empêche la falsification de classes importantes qui peuvent compromettre la sécurité ou affecter les performances.

Plusieurs fois, sceller une classe est également logique lorsque l'on conçoit une classe utilitaire avec un comportement fixe, que nous ne voulons pas changer.

Par exemple, System espace de noms dans C# fournit de nombreuses classes scellées, telles que String. S'il n'est pas scellé, il serait possible d'étendre ses fonctionnalités, ce qui pourrait être indésirable, car il s'agit d'un type fondamental avec des fonctionnalités données.

De même, structures dans C# sont toujours implicitement scellés. Par conséquent, on ne peut pas dériver une structure/classe d'une autre structure. Le raisonnement est que structures est utilisé pour modéliser uniquement les types de données autonomes, atomiques, définis par l'utilisateur, que nous ne voulons pas modifier.

Parfois, lorsque vous créez des hiérarchies de classes, vous souhaiterez peut-être plafonner une certaine branche de la chaîne d'héritage, en fonction de votre modèle de domaine ou de vos règles métier.

Par exemple, un Manager et PartTimeEmployee sont tous deux Employee, mais vous n'avez aucun rôle après les employés à temps partiel dans votre organisation. Dans ce cas, vous souhaiterez peut-être sceller PartTimeEmployee pour éviter toute nouvelle ramification. En revanche, si vous avez des employés à temps partiel horaires ou hebdomadaires, il peut être judicieux de les hériter de PartTimeEmployee.

1
Akshay Khot

Je pense que ce post a un bon point, le cas spécifique était lorsque vous essayez de lancer une classe non scellée sur une interface aléatoire, le compilateur ne lance pas d'erreur; mais une fois scellé, le compilateur génère une erreur qu'il ne peut pas convertir. La classe scellée apporte une sécurité d'accès au code supplémentaire.
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla

0
strisunshine