Why is subclassing not allowed for many of the SWT Controls?

It doesn't look like anybody mentioned this in any of the answers, but SWT does provide an overrideable checkSubclass() method; precisely where the Unextendable exception is thrown. Override the method to a no-op and effectively make extending legal. I guess to leave this option open is ultimately the reason that the class is not made final and the extension error not made compile-time instead of run-time.

Example:

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

As for your follow-up question:

what's the point of not marking a Control class final, but prohibiting subclassing - effectively demoting the exception/error from compile-time to run-time?

It's not possible for SWT to subclass the Control class, if they mark it final. But they have to internally. So they defer the checking to runtime.

BTW, if you want an insane hack, you can still subclass Control or any other SWT class, by putting your subclass into the org.eclipse.swt.widgets package. But I never really had to do that.


Designing components for inheritance is hard, and can limit future implementation changes (certainly if you leave some methods overridable, and call them from other methods). Prohibiting subclassing restricts users, but means it's easier to write robust code.

This follows Josh Bloch's suggestion of "design for inheritance or prohibit it". This is a bit of a religious topic in the dev community - I agree with the sentiment, but others prefer everything to be as open to extension as possible.


It is very hard to create class that can be safely subclassed. You have to think about endless use cases and protect you class very well. I believe that this is a general reason to mark API class as final.

Tags:

Java

Swt