什么时候和为什么要盖一堂课?
在C#和C ++ / CLI中,使用关键字sealed
(或VB中的NotInheritable
)来保护类不受任何inheritance机会(该类将是不可inheritance的)。 我知道面向对象编程的一个特点是inheritance,我觉得使用sealed
是违背这个特性的,它会停止inheritance。 有没有一个例子显示sealed
的好处,什么时候使用它是重要的?
1)在实现安全function的类上,以便原始对象不能被“模仿”。
2)更一般地说,我最近和微软的一个人交stream过,他告诉我,他们试图把inheritance权限制在真正意义上的地方,因为如果不加以处理的话,性能上就会变得昂贵。
密封的关键字告诉CLR没有进一步寻找方法的类,并且加快了速度。
现在市场上大多数增强性能的工具,你会发现一个checkbox,将所有你没有inheritance的类。
但要小心,因为如果你想允许通过MEF发现插件或程序集,你将遇到问题。
狒狒优秀答案的附录:
3)如果一个类不是为了inheritance而devise的,那么子类可能会破坏类的不变性 。 这当然只适用于创build公共API的情况,但是按照我的经验,我将任何没有明确devise的类都加上了子类。
在相关说明中,仅适用于非密封类:任何创build的virtual
方法都是扩展点,或者至less看起来应该是扩展点。 声明virtual
方法也应该是一个有意识的决定。 (在C#中,这是一个有意识的决定;在Java中则不是)。
编辑 :一些相关的链接:
- Effective Java,第二版 ,Joshua Bloch。 请参阅第17项(需要Safari订阅)
- 有效的Java项目17:inheritance的devise和文档,或禁止它 (讨论相同的项目)
另外请注意, Kotlin默认密封课程; 其open
关键字是Java的final
或sealed
的C#的反面 。 (可以肯定的是,没有普遍认同这是一件好事 。)
我觉得这个post有一些好处,具体的情况是当试图将一个非密封类强制转换为任意的随机接口时,编译器不会抛出错误; 但是当使用密封时,编译器会抛出无法转换的错误。 密封类带来额外的代码访问安全性。
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla