如何使用關鍵字Final防止Java中的繼承

通過避免繼承來避免破壞類的行爲

Java的優勢之一是繼承的概念,其中一個類可以從另一個類派生,但有時最好防止另一個類的繼承。 爲了防止繼承,在創建類時使用關鍵字“ final”。

例如,如果一個類可能被其他程序員使用,則如果創建的任何子類可能引起問題,則你可能希望防止繼承。 一個典型的例子是String類。 如果我們想創建一個String子類:

public class MyString extends String{
} 

我們將面臨以下錯誤:

 cannot inherit from final java.lang.String 

String類的設計者意識到它不是繼承的候選者,因此阻止了對其進行擴展。

爲什麼要防止繼承?

防止繼承的主要原因是確保類的行爲方式不會被子類破壞。

假設我們有一個Account類和一個擴展它的子類OverdraftAccount。 類帳戶具有方法getBalance():

 public double getBalance()

{

 return this.balance;

 } 

至此,在我們的討論中,子類OverdraftAccount尚未覆蓋此方法。

(注意:有關使用此Account和OverdraftAccount類的另一討論,請參見如何將子類視爲超類)。

讓我們爲每個Account和OverdraftAccount類創建一個實例:


 Account bobsAccount = new Account(10);

 bobsAccount.depositMoney(50);

 OverdraftAccount jimsAccount = new OverdraftAccount(15.05,500,0.05);

 jimsAccount.depositMoney(50);

 //create an array of Account objects

 //we can include jimsAccount because we 

 //only want to treat it as an Account object

 Account[] accounts = {bobsAccount, jimsAccount};

 //for each account in the array, display the balance

 for (Account a:accounts)

 {

 System.out.printf("The balance is %.2f%n", a.getBalance());

 }

 The output is:

 The balance is 60.00

 The balance is 65.05 

一切似乎都按預期工作,在這裏。 但是,如果OverdraftAccount覆蓋方法getBalance()怎麼辦? 沒有什麼可以阻止它執行以下操作:

 public class OverdraftAccount extends Account {

 private double overdraftLimit;

 private double overdraftFee;

 //the rest of the class definition is not included

 public double getBalance()

 {

 return 25.00;

 }

 } 

如果再次執行上述示例代碼,則輸出將有所不同,因爲jimsAccount調用了OverdraftAccount類中的getBalance()行爲:

 The output is:

 The balance is 60.00

 The balance is 25.00 

不幸的是,子類OverdraftAccount將永遠不會提供正確的餘額,因爲我們已經通過繼承破壞了Account類的行爲。

如果您設計一個供其他程序員使用的類,請始終考慮任何潛在子類的含義。 這就是不能擴展String類的原因。 程序員必須知道,當他們創建一個String對象時,它總是會表現得像String一樣,這一點非常重要。

如何防止繼承

要阻止類擴展,類聲明必須明確聲明它不能被繼承。 這可以通過使用“ final”關鍵字來實現:


 public final class Account {

 } 

這意味着Account類不能是超類,而OverdraftAccount類不能再作爲其子類。

有時,您可能希望僅限制超類的某些行爲,以避免子類損壞。 例如,OverdraftAccount仍然可以是Account的子類,但是應避免覆蓋getBalance()方法。

在這種情況下,使用方法聲明中的“ final”關鍵字:

 public class Account {

 private double balance;

 //the rest of the class definition is not included

 public final double getBalance()

 {

 return this.balance;

 } 

 } 

注意在類定義中如何不使用final關鍵字。 可以創建Account的子類,但是它們不能再覆蓋getBalance()方法。 任何調用該方法的代碼都可以確信它會按原始程序員的意圖工作。

喜歡這篇文章的可以點個贊,歡迎大家留言評論,記得關注我,每天持續更新技術乾貨、職場趣事、海量面試資料等等
 > 如果你對java技術很感興趣也可以交流學習,共同學習進步。 
不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代

文章寫道這裏,歡迎完善交流。最後奉上近期整理出來的一套完整的java架構思維導圖,分享給大家對照知識點參考學習。有更多JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java乾貨

如何使用關鍵字Final防止Java中的繼承

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章