为什么许多SWT控件不允许子类化?

我经常发现自己想要这样做。 当您想要存储一些有用的信息或额外的状态时,它会非常有用。

所以我的问题是,是否有一个非常好的/强有力的理由为什么这是被禁止的?

谢谢

编辑:非常感谢所有这些答案。 所以听起来对此没有正确或错误的答案。

假设我接受这些类不是子类的事实,那么标记Control类final,但禁止子类化有什么意义 – 有效地将exception/错误从编译时降级到运行时?

编辑^ 2:看到我自己的答案:显然,这些类是可重写的,但需要由覆盖者明确确认。

谢谢

它看起来没有任何人在任何答案中提到过这一点,但是SWT确实提供了一个可重写的checkSubclass()方法,并且正是抛出Unextenableexception的地方。 要强制覆盖,您可以将方法覆盖为无操作,并有效地扩展合法性。 我想让这个选项保持打开最终是因为该类没有成为最终的并且扩展错误没有编译时而不是运行时。

为inheritance设计组件很难,并且可以限制将来的实现更改(当然,如果您保留一些可覆盖的方法,并从其他方法调用它们)。 禁止子类化限制用户,但意味着编写健壮的代码更容易。

这遵循Josh Bloch关于“inheritance设计或禁止设计”的建议。 这在开发社区中是一个宗教话题 – 我同意这种情绪,但其他人更喜欢一切尽可能开放。

创建可以安全子类化的类非常困难。 你必须考虑无休止的用例并保护你的课程。 我相信这是将API类标记为final的一般原因。

至于你的后续问题:

什么是不标记Control类final,但禁止子类化 – 有效地将exception/错误从编译时降级为运行时?

如果将SWT标记为final,则SWT不可能inheritanceControl类。 但他们必须在内部。 所以他们将检查推迟到运行时。

顺便说一句,如果你想要一个疯狂的黑客攻击,你仍然可以通过将你的子类放入org.eclipse.swt.widgets包中来org.eclipse.swt.widgets Control或任何其他SWT类。 但我从来没有真的那么做过。

org.eclipse.swt.widgets.Widget.checkSubclass()的方法描述说:

检查此类是否可以进行子类化。

SWT类库仅用于在特定的受控点(最值得注意的是,实现新窗口小部件时为Composite和Canvas)进行子类化。 除非被覆盖,否则此方法将强制执行此规则。

重要提示:通过提供此方法的实现,该方法允许通常不允许创建子类的类的子类,实现者同意完全负责任何此类子类可能在SWT版本之间失败并且将强烈特定平台。 没有为以这种方式实现的用户编写的类提供支持。

在允许的SWT类之外进行子类化的能力纯粹是为了使那些不在SWT开发团队中的人能够实现补丁,以便在团队可以解决这些限制之前解决特定限制。 如果没有对层次结构的密切和详细的了解,就不应该尝试子类化。

抛出:SWTException
ERROR_INVALID_SUBCLASS – 如果此类不是允许的子类