c# - 我应该默认推荐密封类吗?

标签 c# java .net oop

在我工作的一个大项目中,我正在考虑建议其他程序员在他们没有考虑如何对他们的类进行子类化的情况下始终密封他们的类。通常,经验不足的程序员从不考虑这一点。

我觉得奇怪的是,Java 和 C# 中的类默认情况下是非密封/非最终的。我认为密封类可以大大提高代码的可读性。

请注意,这是内部代码,如果发生需要子类化的罕见情况,我们可以随时更改。

你有什么经验?我遇到了相当多的反对这个想法。那些懒得写sealed的人吗?

最佳答案

好的,因为很多人都在权衡...

是的,我认为建议默认密封类是完全合理的。

这与 Josh Bloch 在他的优秀Effective Java, 2nd edition 中的推荐一致:

Design for inheritance, or prohibit it.

为继承而设计是困难,并且可以使您的实现更少灵活,特别是如果您有虚拟方法,其中一个调用另一个。也许它们是重载,也许不是。一个调用另一个的事实必须记录否则你不能安全地覆盖任何一个方法 - 你不知道它什么时候会被调用,或者你是否可以安全地调用另一个方法不会冒堆栈溢出的风险。

现在,如果您以后想要更改在以后的版本中调用哪个方法,则不能 - 您可能会破坏子类。因此,以“灵 active ”的名义,您实际上使实现不那么灵活,并且必须更仔细地记录您的实现细节。对我来说,这听起来不是个好主意。

接下来是不可变性——我喜欢不可变类型。我发现它们比可变类型更容易推理。这是 Joda Time 的原因之一API 比在 Java 中使用 DateCalendar 更好。但是一个未密封的类永远不可能知道是不可变的。如果我接受 Foo 类型的参数,我可能能够依赖 Foo 中声明的属性不会随着时间的推移而改变,但我不能依赖对象本身没有被修改——子类中可能有一个可变属性。如果该属性也被某些虚拟方法的覆盖所使用,那么天堂会帮助我。告别不变性的许多好处。 (具有讽刺意味的是,Joda Time 具有非常大的继承层次结构 - 通常会说“子类应该是不可变的。Chronology 的大型继承层次结构使得移植到 C# 时很难理解。)

最后,还有过度使用继承的问题。在可行的情况下,我个人更喜欢组合而不是继承。我喜欢接口(interface)的多态性,偶尔我使用实现的继承 - 但它很少适合我的经验。使类密封可以避免它们不恰本地从更适合组合的地方派生出来。

编辑:我还想向读者指出 Eric Lippert's blog post from 2004关于为什么这么多框架类是密封的。有很多地方我希望 .NET 提供一个 interface 我们可以为可测试性工作,但这是一个稍微不同的要求...

关于c# - 我应该默认推荐密封类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6389417/

相关文章:

Java:在字符串中,如何提取正则表达式匹配之前的数字?

c# - 在 TLS : The remote server return an error : 234 AUTH TLS OK 上使用 FtpWebRequest 的问题

c# - 简单客户端-服务器应用程序中的 "...target machine actively refused it..."异常

c# - 网络核心: Find Application Assembly Location from Integration Test

java - org.hibernate.StaleStateException : Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

java - 从 JavaScript 访问列表项

c# - 2nd Page_Load 上的 NullReferenceException

.net - 创建具有超时的任务

c# - 如何使用 TagLib-Sharp 从 MP3 文件中读取 XingHeaders 和 VBRIHeaders

c# - 创建现有 c# 类的扩展 'copy'