2010-11-24 91 views
12

我經常發現自己想要做到這一點。當你想存儲一些有用的信息或額外的狀態時,它可能非常有用。爲什麼許多SWT控件不允許繼承子類?

所以我的問題是,有一個很好/強烈的原因,爲什麼這是禁止的?

感謝

編輯: 非常感謝所有這些問題的答案。所以這聽起來像是沒有對或錯的答案。

假設我接受這樣的事實,這些類是不能被繼承,什麼的打標控制類決賽,但禁止子類的點 - 有效地從編譯時降級異常/錯誤運行時?

編輯^ 2: 看到我自己對此的回答:顯然,這些類是可覆蓋的,但需要overrider的明確確認。

感謝繼承

回答

18

它看起來沒有任何人在任何答案中提到過這一點,但SWT確實提供了一個可覆蓋的checkSubclass()方法,正是引發了Unextenable異常的地方。要強制覆蓋,您可以將該方法覆蓋爲禁用,並有效地擴展合法。我想打開這個選項是最終的原因,該類不是最終的,擴展錯誤不是編譯時而是運行時。

10

設計成分是很難的,並會限制未來實施的變化(當然,如果你離開一些方法重寫,並從其他方法調用它們)。禁止子類限制用戶,但意味着編寫健壯的代碼更容易。

這跟隨Josh Bloch的「繼承或禁止設計」的建議。這是開發社區中的一個宗教話題 - 我同意這種觀點,但其他人則傾向於儘可能地延伸。

+0

但是Eclipse本身以這種方式創建了我們的'Shell`類(從`Shell`繼承),然後重寫`checkSubclass() `空身。我們這樣做是否好(安全)?我有兩個shell(`Shell_1`,`Shell_2`)。 `Shell_1`是`Shell_2`的父親。我只想擴展`Shell_2`的`Shell`類,這樣我就可以在`Shell_2`的構造函數中添加控件了。這是錯誤的方式嗎? – 2011-12-05 10:15:37

3

創建可以安全分類的類是非常困難的。你必須考慮無盡的用例,並保護你的課程。我相信這是將API類標記爲最終的一般原因。

3

至於你的後續問題:

什麼不是標誌着 控制級決賽中,但禁止 子類的點 - 有效降級的編譯時 異常/錯誤 運行 - 時間?

如果SWT將Control類標記爲最終類,那麼SWT就不可能繼承這個類。但他們必須在內部。所以他們將檢查延遲到運行時間。

順便說一句,如果你想要一個瘋狂的黑客攻擊,你仍然可以繼承子類Control或任何其他SWT類,通過將你的子類放入org.eclipse.swt.widgets包。但我從來沒有真的必須這樣做。

0

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

檢查這一類可以被繼承。

SWT類庫僅用於特定的 受控點(最值得注意的是,當 實現新小部件時,Composite和Canvas)。此方法強制執行此規則,除非它被重寫爲 。

重要提示:通過提供這種方法的實現,它允許 子一類通常不允許子類是 創建的,實施者同意對事實 ,任何此類的子類很可能會失敗負全部責任SWT版本之間,並將 強烈平臺特定。不支持用戶編寫的以這種方式實現的類。

到允許SWT類以外的子類的能力旨在 純粹是爲了使那些沒有在SWT開發團隊來實現,以獲得提前當 這些限制可以通過解決圍繞具體限制 補丁球隊。如果沒有對 層次結構的親密和詳細的理解,則不應嘗試子類別 。

拋出:SWTException
ERROR_INVALID_SUBCLASS - 如果該類不是允許子類

相關問題