1. 主要是为了不想被继承而设计的。在class前面用sealed修饰,代表私有的。
2. 保护知识产权
3. 密封类的优点
1.版本控制: 如果类最开始就是密封的, 那么将来可以在不破坏兼容性的前提下改为非密封类
2.性能有一定的提升: 如果调用密封类的虚方法, 编译器可以生成更高效的代码
3.安全性和可预测性
缺点:密封类限制了类的派生, 对开发人员造成不便
4. 当你设计一个类,并且在设计的时候就确定不希望将来有人(或者你自己)因为凌乱的继承关系,使这个类的最初动机变得扑朔迷离的时候,可以将这个类sealed(为什么要不希望自己继承这个类后做改动?因为你的脑袋并不是电脑,你的记性并不是那么好,最初的设计初衷,在以后系统越来越庞大的时候,你可能自己都忘了自己当初设计的这个类可能考虑到的某些很细微的因素,这个因素要求你将来不要改变这个类的成员或者任何属性),当你有个基类A,然后有个类B继承A,然后类C又继承B,类D又继承类C的时候,你可能会发生凌乱。这个时候,有些类在设计之初你就可以将它sealed,以确保将来在某一个时刻脑袋短路的情况想把这个类继承出一个子类来改写的时候,编译器就会报错提示你,“唤起”你的记忆。
比如.net中,你可能没注意到过,struct也是sealed的,你不能继承一个struct。另外,.net framework中还有一些成员都是静态类型的类,比如Pen和Brushes也是sealed的,因为画笔和画刷在设计之初都已经定义好了它都有哪些颜色,并且不希望将来改变画笔和画笔的这些属性,所以直接给它sealed掉。
另外,如果你的程序中有用到反射的话,CLR对用了sealed关键字的类和属性会比普通的类有一点性能上的提升。因为反射需要找回某个类的属性,没有继承关系的类,它的“关系网”不复杂,CLR能够很轻易地定位它的“位置”。
sealed还可以用于限制类成员方法等。
比如你有一个类A包含了一个vitual虚方法FOO1,另外一个类B继承了A,并且还有另外一个类C继承了类B,在这种情况下,类C可以跳过类B而直接从类A override 方法 FOO1,而不管类B是否override了方法FOO1,这个时候很容易发生凌乱。你的设计结构很有可能拎不清了。
什么时候用sealed关键字?事实上,所有的类在设计之初,你都可以设计为sealed,直到你将来在设计别的类的时候,确定需要从这个类有继承关系,因为任何类sealed以后,你还可以将它unsealed(直接以掉sealed关键字)。
另外,在一些类含有一些安全方面考虑的成员或者属性,不希望被别的类继承或者改变的时候,可以设计为sealed。
总而言之,言而总之,sealed关键字有一部分用途比如CLR反射时候性能方面的优化,但是最主要的目的应该是为了帮助开发人员尽量避免在设计和编程的过程人为的犯错,让你在连续加班48个小时后保持清晰的思路记得你当初设计的某个不希望被继承改动的类的目的而不犯错,要求是不是太高了!所以,微软的天才们设计了这个关键字,帮助了大家一把,让这个需要注意和提醒的事情,交给了CLR和编译器。
5. 别的不说,我举一个例子,大家很多人都会用static class。这个static其实就是 abstract+sealed。
我需要澄清一点,sealed是CLR和IL层面的东西,和“设计”关系不大。
就好比你可以认为一种高级语言没有必要用到goto,但是如果你设计一个虚拟机,跳转是必须考虑的东西。
6.比如说当我们突然发现从mongodb中反序列化出来的对象实际上无法正常地得到子类对象,而都是仅仅得到了父类对象,而你以前不知道、没注意,现在出现乱子了。你已经没有时间去补充测试所有代码了,你需要在24小时内就发布产品,那么就可以把父类变为sealed的并删除子类,这样调试器就能告诉你哪些代码是出乱子的,而不需要你一点点地去学测试代码。然后当你已经发布了产品,如果你觉得懒得再把子类写回来了,懒得实现原来的既定扩展目标,你根本没有压力需要对类型进行扩展,那么你当然仍然会保留着这个sealed
7. 密封类:到他这一代已经最牛逼了,不需要生孩子来扩展天赋了。
普通类:造物者觉得他还可以通过生孩子来扩展家族天赋。
8. 最明确的就是为了预防一些因继承可能会导致的异常