您好,登錄后才能下訂單哦!
通過避免繼承來避免破壞類的行為
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()方法。 任何調用該方法的代碼都可以確信它會按原始程序員的意圖工作。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。