什么可以成为阻止类继承的原因? (例如使用密封的ac#class)现在我想不出任何。

===============>>#1 票数:21

因为编写类可以被替代地扩展是非常困难的,并且需要您准确预测未来用户将如何扩展您所编写的内容。

密封你的类迫使他们使用更强大的组合。

===============>>#2 票数:9

如果您还不确定界面,并且根据当前界面不需要任何其他代码,那怎么样? [这不是我的头脑,但我也会对其他原因感兴趣!]

编辑:一些谷歌搜索给出了以下内容: http//codebetter.com/blogs/patricksmacchia/archive/2008/01/05/rambling-on-the-sealed-keyword.aspx

引用:

密封类比未密封类更好的原因有三个:

  • 版本控制 :当一个类最初被密封时,它可以在将来更改为未密封而不会破坏兼容性。 (......)
  • 性能 :(...)如果JIT编译器看到使用密封类型调用虚方法,JIT编译器可以通过非虚拟地调用该方法来生成更高效的代码。(...)
  • 安全性和可预测性 :一个类必须保护自己的状态,不允许自己被破坏。 当一个类被解封时,如果内部操作字段的任何数据字段或方法是可访问的而不是私有的,派生类可以访问和操作基类的状态。(...)

===============>>#3 票数:8

我想从“代码完成”中给你这条消息:

继承 - 子类 - 倾向于违背您作为程序员的主要技术要求,即管理复杂性。为了控制复杂性,您应该保持对继承的严重偏见。

===============>>#4 票数:2

继承的唯一合法用法是定义基类的特定情况,例如,从Shape继承以派生Circle。 要检查这个相反方向的关系:是一个Circle的泛化吗? 如果答案是肯定的,那么可以使用继承。

因此,如果您有一个类,其中不存在任何特殊情况的特殊情况,则应该将其密封。

同样由于LSP(Liskov替换原则),可以使用派生类,其中基类是预期的,这实际上对继承的使用产生了最大的影响:使用基类的代码可能被赋予一个继承的类,它仍然必须按预期工作 为了在没有明显需要子类的情况下保护外部代码,您可以密封该类,并且其客户端可以依赖其行为不会被更改。 否则,需要明确设计外部代码以期望子类中行为的可能变化。

一个更具体的例子是Singleton模式。 你需要密封单身,以确保不会打破“单身”。

===============>>#5 票数:1

这可能不适用于您的代码,但.NET框架中的许多类都是故意密封的,因此没有人尝试创建子类。

在某些情况下,内部结构很复杂并且需要非常具体地控制某些事情,因此设计者决定不应该继承该类,以便没有人通过错误的方式使用某些东西而意外地破坏功能。

===============>>#6 票数:1

@jjnguy

另一个用户可能希望通过对您的类进行子类化来重用您的代码。 我没有理由阻止这一点。

如果他们想要使用我的类的功能,他们可以通过包含来实现它,并且因此它们将具有更少的脆弱代码。

组成似乎经常被忽视; 很多时候人们都希望跳上继承的潮流。 他们不应该! 可替代性很难。 默认为组合; 从长远来看,你会感谢我的。

===============>>#7 票数:1

我同意jjnguy ...我认为封印课程的原因很少而且很远。 恰恰相反,我不止一次出现这种情况,我想延长课程,但不能因为它是密封的。

作为一个完美的例子,我最近创建了一个小包(Java,而不是C#,但原理相同)来围绕memcached工具包装功能。 我想要一个接口,所以在测试中我可以模拟我正在使用的memcached客户端API,并且如果需要的话我们也可以切换客户端(memcached主页上列出了2个客户端)。 此外,如果出现需求或愿望,我希望有机会完全替换功能(例如,如果memcached服务器由于某种原因而关闭,我们可能会与本​​地缓存实现进行热交换)。

我公开了一个与客户端API交互的最小接口,扩展客户端API类然后只需用我的新接口添加implements子句就太棒了。 我在接口中与实际接口匹配的方法将不需要进一步的细节,因此我不必明确地实现它们。 但是,这个类是密封的,所以我不得不代理调用这个类的内部引用。 结果:更多的工作和更多的代码没有真正的理由。

也就是说,我认为有可能你想要一个密封的类......我能想到的最好的事情是你将直接调用的API,但允许客户实现。 例如,您可以针对游戏进行编程的游戏......如果您的课程没有密封,那么添加功能的玩家可能会利用API来获得优势。 这是一个非常狭窄的情况,我认为只要你完全控制代码库,就没有什么理由让一个类密封。

这就是我真正喜欢Ruby编程语言的原因之一......即使核心类是开放的,不仅仅是为了扩展而是动态地添加和更改功能,自始至终! 它被称为monkeypatching,如果被滥用可能是一场噩梦,但玩起来真是太棒了!

===============>>#8 票数:1

从面向对象的角度来看,密封课程清楚地记录了作者的意图而无需评论。 当我封印课程时,我试图说这个课程的目的是封装一些特定的知识或某些特定的服务。 它并不意味着进一步增强或继承。

这与模板方法设计模式很相配。 我有一个界面说“我执行此服务”。 然后我有一个实现该接口的类。 但是,如果执行该服务依赖于基类不知道(并且不应该知道)的上下文,该怎么办? 会发生什么是基类提供虚拟方法,这些方法是受保护的或私有的,并且这些虚方法是子类的钩子,用于提供基类不知道和不知道的信息或动作。 同时,基类可以包含所有子类共有的代码。 这些子类将被密封,因为它们旨在实现该服务的唯一一个具体实现。

您能否提出这些子类应进一步子类化以增强它们的论点? 我会说不,因为如果那个子类无法在第一时间完成工作,那么它应该永远不会从基类派生出来。 如果你不喜欢它,那么你有原始的接口,去编写自己的实现类。

密封这些子类也会阻碍深层次的继承,这对GUI框架很有效,但对业务逻辑层的效果很差。

===============>>#9 票数:0

因为各种原因,你总是希望被提交给类而不是派生类的引用:
一世。 您在代码的其他部分中使用的不变量
II。 安全
等等

此外,因为它是一个关于向后兼容性的安全赌注 - 如果它的发布未密封,你永远无法关闭该类继承。

或者您可能没有足够的时间来测试类暴露的接口,以确保您可以允许其他人继承它。

或者也许没有必要(你现在看到)有一个子类。

或者,当人们尝试子类化并且无法获得所有细节时,您不需要错误报告 - 削减支持成本。

===============>>#10 票数:0

有时你的类接口并不意味着被激活。 公共接口不是虚拟的,虽然有人可以覆盖现有的功能,但这只是错误的。 是的,一般来说,它们不应该覆盖公共接口,但是你可以通过使类不可继承来确保它们不会。

我现在想到的例子是自定义包含.Net中具有深度克隆的类。 如果你从他们那里继承你就失去了深刻的克隆能力。[我在这个例子上有点模糊,自从我使用IClonable已经有一段时间]如果你有一个真正的singelton类,你可能不希望继承的形式它周围,数据持久层通常不是你想要大量继承的地方。

===============>>#11 票数:0

并非所有在类中重要的东西都很容易在代码中断言。 存在可以通过继承和重写方法容易地破坏的语义和关系。 一次覆盖一个方法是一种简单的方法。 你将一个类/对象设计为一个有意义的实体,然后有人出现并认为一个或两个方法“更好”它不会造成伤害。 这可能是也可能不是。 也许你可以正确地区分私有和非私有或虚拟之间的所有方法,而不是虚拟但仍然可能还不够。 要求所有类的继承也给原始开发人员带来了巨大的额外负担,以预见继承类可以搞砸的所有方式。
我不知道一个完美的解决方案。 我同情防止继承,但这也是一个问题,因为它阻碍了单元测试。

===============>>#12 票数:0

我公开了一个与客户端API交互的最小接口,扩展客户端API类然后只需用我的新接口添加implements子句就太棒了。 我在接口中与实际接口匹配的方法将不需要进一步的细节,因此我不必明确地实现它们。 但是,这个类是密封的,所以我不得不代理调用这个类的内部引用。 结果:更多的工作和更多的代码没有真正的理由。

嗯,有一个原因:你的代码现在与memcached接口的更改有些隔离。

===============>>#13 票数:0

性能: (...)如果JIT编译器看到使用密封类型调用虚方法,JIT编译器可以通过非虚拟地调用该方法来生成更高效的代码。(...)

这确实是一个很好的理由。 因此,对于性能关键的课程, sealed和朋友是有道理的。

到目前为止,我所看到的所有其他原因都归结为“没有人触及我的班级!”。 如果你担心有人可能误解了它的内部结构,那你记录下来的工作很糟糕。 您不可能知道添加到您的课程中没有任何用处,或者您已经知道它的每个可以想象的用例。 即使你是对的,而另一个开发人员不应该使用你的类来解决他们的问题,使用关键字也不是防止这种错误的好方法。 文档是。 如果他们忽略了文档,他们的损失。

===============>>#14 票数:0

大多数答案(抽象时)表明密封/最终类是保护其他程序员免受潜在错误的工具。 有意义的保护和无意义的限制之间存在着模糊的界限。 但只要程序员是理解该程序的人,我就几乎没有理由限制他重复使用部分课程。 大多数人都在谈论课程。 但这都是关于物体的!

在他的第一篇文章中,DrPizza声称设计可继承的类意味着预期可能的扩展。 我是否认为只有在可能扩展好的课程时才能继承这个课程? 看起来好像你习惯于从最抽象的类中设计软件。 请允许我简要解释一下设计时的想法:

从非常具体的对象开始,我发现了它们共有的特征和[因此]功能,并将它抽象为那些特定对象的超类。 这是一种减少代码重复性的方法。

除非开发一些特定的产品,比如框架,否则我应该关心我的代码,而不是其他(虚拟)代码。 其他人可能觉得重用我的代码很有用的事实是一个很好的奖励,而不是我的主要目标。 如果他们决定这样做,他们有责任确保扩展的有效性。 这适用于整个团队。 前期设计对生产力至关重要。

回到我的想法:你的对象应该主要服务于你的目的,而不是它们的子类型的一些可能的shoulda / woulda / coulda功能。 你的目标是解决给定的问题。 面向对象的语言使用许多问题(或者更可能是它们的子问题)相似的事实,因此可以使用现有代码来加速进一步的开发。

密封课程迫使那些可能利用现有代码而无需实际修改您的产品的人重新发明轮子。 (这是我的论文的一个重要思想:继承一个类不会修改它!这似乎非常行人和明显,但它通常被忽略)。

人们常常害怕他们的“开放”阶级会扭曲成无法替代其优势的东西。 所以呢? 你为什么要关心? 没有工具可以防止坏程序员创建坏软件!

我不是试图将可继承的类表示为最终正确的设计方法,认为这更像是对我对可继承类的倾向的解释。 这就是编程之美 - 几乎无限的正确解决方案,每个都有自己的缺点和优点。 欢迎您提出意见和建议。

最后,我对原始问题的回答是:我最终确定了一个类,让其他人知道我认为该类是分层类树的一个叶子,我认为它绝对不可能成为父节点。 (如果有人认为它确实可以,那么要么我错了,要么他们没有得到我)。

  ask by FantaMango77 translate from so

未解决问题?本站智能推荐: