原文:geeks4geeks
子類可以重新定義父類的方法吸祟,這種屬性被稱為方法重寫(Overriding)色鸳。簽名(返回類型,參數(shù)類型舞萄,參數(shù)數(shù)量)保持和父類中定義的一致,完成方法重寫以實現(xiàn)運行時多態(tài)(重寫的方法是根據(jù)調(diào)用它的對象被調(diào)用恕曲,而不是根據(jù)它的引用類型)鹏氧。
// 簡單的演示重寫的例子
// 父類
class Parent{
void show() {
System.out.println("Parent's show()");
}
}
// 子類
class Child extends Parent{
// 重寫父類的方法
void show() {
System.out.println("Child's show()");
}
}
// 測試類
class Test {
public static void main(String[] args) {
// 如果父類引用父類的對象,則父類的 show 方法被調(diào)用
Parent obj1 = new Parent();
obj1.show();
// 如果父類引用子類的對象佩谣,則子類的 show 方法被調(diào)用
// 這種被稱為運行時多態(tài)
Parent obj2 = new Child();
obj2.show();
}
}
輸出:
Parent's show()
Child's show()
一些有趣的事實:
- C++ 中需要 virtual 關(guān)鍵字以實現(xiàn)重寫或運行時多態(tài)。Java 中方法默認是 virtual 的实蓬。
- 可以有多級的重寫:
// 簡單的演示多級重寫的例子
// 父類
class Parent {
void show() {
System.out.println("Parent's show()");
}
}
// 子類
class Child extends Parent {
// 重寫父類的方法
void show() {
System.out.println("Child's show()");
}
}
// 孫類
class GrandChild extends Child {
// 重寫子類的方法
void show() {
System.out.println("GrandChild's show()");
}
}
// 測試類
class Test {
public static void main(String[] args) {
Parent obj1 = new GrandChild();
obj1.show();
}
}
輸出:
GrandChild's show()
- 如果不想讓一個方法被重載茸俭,可以用 final 關(guān)鍵字修飾它
// 簡單的演示 final 關(guān)鍵字重寫的例子
class Parent {
// 不能被重寫
final void show() { }
}
class Child extends Parent {
// 會產(chǎn)生錯誤
void show() { }
}
輸出:
error: show() in Child cannot override show() in Parent
void show() { }
^
overridden method is final
- 重寫的方法的訪問限制不能收窄,只能擴大安皱。如父類中是 protected 方法 调鬓,子類不能以 private 限制符重寫方法。
- Private 的方法不能被重寫酌伊,因為在 private 方法在編譯時綁定會它的引用類型腾窝。
- 我們可以給子類中與父類相同簽名的方法加上 static 關(guān)鍵詞,但這不認為是重寫居砖,因為沒有任何運行時多態(tài)虹脯。
- 我們可以在重寫的方法中使用 super 關(guān)鍵字調(diào)用父類的方法。
// 簡單的例子演示 super 關(guān)鍵字重寫的例子
// 父類
class Parent {
void show() {
System.out.println("Parent's show()");
}
}
// 子類
class Child extends Parent {
// 重寫父類的 show 方法
void show() {
super.show();
System.out.println("Child's show()");
}
}
// 測試類
class Test {
public static void main(String[] args) {
Parent obj = new Child();
obj.show();
}
}
輸出:
Parent's show()
Child's show()
應(yīng)用
重寫的方法允許我們調(diào)用任何派生類的方法奏候,甚至不必知道派生類對象的種類循集。
JavaOVerriding.jpg
上圖的管理軟件中基類 Employee 有不同的方法,如 raiseSalary(), transfer(), promote(), salary()等蔗草。不同的子類 Manager 和 Clerk 可能對這些父類的方法有自己的實現(xiàn)咒彤。在實際使用場景中,我們只需要傳遞一份完整的員工名單咒精,而不必知道他所屬的類型是 Manager 或 Clerk 之類的镶柱。例如,我們只需通過遍歷名單給每位員工 raiseSalary()
模叙,每位員工都有自己的 raiseSalary()
邏輯歇拆,我們不必知道每個員工對應(yīng)的類型。每個員工只要有 raiseSalary()
方法向楼,便會被調(diào)用查吊。
// 簡單的演示重寫應(yīng)用的例子
// 基類
class Employee {
public static int base = 10000;
int salary() {
return base;
}
}
// 派生類
class Manager extends Employee {
// This method overrides show() of Parent
int salary() {
return base + 20000;
}
}
// 派生類
class Clerk extends Employee {
// This method overrides show() of Parent
int salary() {
return base + 10000;
}
}
// 測試類
class Test {
// 打印雇員的薪資
static void printSalary(Employee e) {
System.out.println(e.salary());
}
public static void main(String[] args) {
Employee obj1 = new Manager();
System.out.print("Manager's salary : ");
printSalary(obj1);
Employee obj2 = new Clerk();
System.out.print("Clerk's salary : ");
printSalary(obj2);
}
}
輸出:
Manager's salary : 30000
Clerk's salary : 20000