使用 final 來限制繼承和覆蓋
final 類
當在 class
宣告中使用時,final
修飾符會阻止其他類被宣告為 extend
類。final
類是繼承類層次結構中的葉子類。
// This declares a final class
final class MyFinalClass {
/* some code */
}
// Compilation error: cannot inherit from final MyFinalClass
class MySubClass extends MyFinalClass {
/* more code */
}
final 類的用例
最終類可以與 private
建構函式結合使用,以控制或阻止類的例項化。這可以用來建立一個只定義靜態成員的所謂實用程式類; 即常數和靜態方法。
public final class UtilityClass {
// Private constructor to replace the default visible constructor
private UtilityClass() {}
// Static members can still be used as usual
public static int doSomethingCool() {
return 123;
}
}
不可變類也應該宣告為 final
。 (不可變類是在建立例項後無法更改的類;請參閱 I mmutable Objects 主題。)通過這樣做,你無法建立不可變類的可變子類。這將違反 Liskov 替代原則 ,該原則要求子型別應遵守其超型別的行為合同。
從實際角度來看,將不可變類宣告為 final
可以更容易推理程式行為。它還解決了在安全沙箱中執行不受信任的程式碼的情況下的安全問題。 (例如,由於 String
被宣告為 final
,一個受信任的類不需要擔心它可能被欺騙接受可變子類,然後不可信的呼叫者可能會偷偷地改變它。)
final
類的一個缺點是它們不適用於一些模擬框架,如 Mockito。更新:Mockito 版本 2 現在支援模擬最終類。
最後的方法
final
修飾符也可以應用於方法,以防止它們在子類中被覆蓋:
public class MyClassWithFinalMethod {
public final void someMethod() {
}
}
public class MySubClass extends MyClassWithFinalMethod {
@Override
public void someMethod() { // Compiler error (overridden method is final)
}
}
當你想要限制子類在類中可以更改的內容而不完全禁止子類時,通常會使用最終方法。
final
修飾符也可以應用於變數,但 final
對變數的含義與繼承無關。