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

时间:2010-11-24 09:02:28

标签: java swt

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

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

由于

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

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

EDIT ^ 2: 看看我自己对此的回答:显然,这些类是可重写的,但需要由覆盖者明确确认。

由于

5 个答案:

答案 0 :(得分:20)

在任何答案中看起来都没有人提到这一点,但SWT确实提供了一种可覆盖的checkSubclass()方法;确切地说,抛出Unextendable异常的地方。将方法重写为no-op并有效地扩展合法性。我想让这个选项保持打开最终是因为该类没有成为最终的,并且扩展错误没有编译时而不是运行时。

示例:

@Override
protected void checkSubclass() {
    //  allow subclass
    System.out.println("info   : checking menu subclass");
}

答案 1 :(得分:10)

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

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

答案 2 :(得分:3)

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

答案 3 :(得分:3)

至于你的后续问题:

  

没有标记的重点是什么   控制类最终,但禁止   子类化 - 有效降级   从编译时到。的异常/错误   运行时?

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

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

答案 4 :(得分:0)

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

  

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

     

SWT类库仅用于特定的子类,   受控点(最值得注意的是,复合和画布时   实现新的小部件)。除非是这样,否则此方法会强制执行此规则   重写的。

     

重要提示:通过提供允许a的此方法的实现   通常不允许子类化的类的子类   创建者,实施者同意对事实负全部责任   任何这样的子类都可能在SWT发布之间失败   具体针对平台。没有为用户编写提供支持   以这种方式实现的类。

     

允许在允许的SWT类之外进行子类化   纯粹是为了让那些不在SWT开发团队中的人能够实施   补丁以便在何时提前解决特定限制   这些限制可以由团队解决。子类化不应该   没有亲密和详细的了解的尝试   层次结构。

     

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