Java類的三大特性之一:多型 以及 方法的重寫介紹
阿新 • • 發佈:2021-04-30
重寫
過載和重寫是不一樣的:
- 過載只是方法中引數列表(形參個數或順序等)的不同,而重寫是針對於有子父類關係的類中方法的(子類重寫父類的方法)。
- 重寫都是方法的重寫,和屬性沒有任何關係
//過載 引數列表跟方法體都可以不同,但是方法名必須相同
public int add(int a,int b){return a+b;}
public int add(int a,int b,int c){return a+b+c;}
//重寫 只有反方法體不同,其餘都必須相同(修飾符可以按照規則修改)
class Son extends Father{
public void test(){
System.out. println("呼叫子類中方法");
}}
class Father{
publi void test(){
System.out.println("呼叫父類中方法");
}}
重寫和static修飾的靜態方法沒有關係,重寫只體現在非靜態方法中。
有繼承關係的兩個類之間,以父類為宣告,但是父類的引用可以指向子類的物件,相當於父親找兒子借東西,在靜態方法中物件呼叫的方法是所指向的宣告類(父類)中的方法。
父類的引用指向了子類,即宣告的是父類,但實際指向了子類的物件
Father f1=new Son();
//new Son(); 指的是父類所指向的引用型別
//Father 指的是物件的實際型別(宣告)
例如:
public class Application{
public static void main(String[] args){
Son son = new son();
son.test();
//靜態方法中,方法的呼叫只和左邊即資料定義型別有關
Father father = new son();
//父類的引用指向了子類,但father物件還是父類定義的
//所以所用的仍然是父類中的方法
father.test();
}
}
class Son extends Father{
public static void test(){
System.out.println("呼叫子類中方法");
}
}
class Father{
public static void test(){
System.out.println("呼叫父類中方法");
}
}
非靜態方法中子類重寫了父類的方法,父類建立的物件但所指向的引用型別是子類的話呼叫該物件中被父類被重寫的方法執行的還是子類的方法。
非靜態類方法的重寫(注意上下兩程式碼之間的區別和輸出結果):
public class Application{
public static void main(String[] args){
Son son = new son();
son.test();
//父類的方法被子類重寫之後,建立的新的物件的是父類所宣告的,引用型別指向子類
//但是該物件呼叫方法時呼叫的是子類中被重寫的方法,這就與靜態方法的操作有所不同
Father father = new son();
father.test();
}
}
class Son extends Father{
public void test(){
System.out.println("呼叫子類中方法");
}
}
class Father{
public void test(){
System.out.println("呼叫父類中方法");
}
}
重寫的規則:
1、子類重寫父類的方法其方法名必須與父類被重寫的方法名相同
2、方法中的引數列表必須相同
3、方法的修飾符的範圍可以擴大,但是不能縮小
public > protected > default > private
4、丟擲的異常可以縮小但是不能擴大。
為什麼要重寫:因為有些父類的功能子類不一定需要,或者不一定滿足,當方法很複雜的時候重新定義一個方法又太麻煩,這個時候就需要用到重寫了。
多型:一個方法根據傳送物件的不同可以呈現不同的行為方式
多型的意義:可以提高程式的可擴充套件性
多型是方法的多型,跟屬性沒有關係
多型的存在條件:
1、類之間有繼承關係
2、方法被重寫
3、父類的引用指向子類的物件
不能被重寫的方法的一些修飾符:final,private,static
一個物件的實際型別是確定的,但是它所指向的引用型別是不確定的:父類的引用型別可以指向子類
子類可以呼叫自己的或者所繼承的父類的方法
父類可以指向子類但是不能呼叫子類獨有的方法
原始碼如下:
public class Application {
public static void main(String[] args) {
Son son = new Son(); //子類的引用型別指向子類
son.test(); //呼叫子類自己的方法
son.study("Bob");
son.teach("Alice");
Father father = new Father(); //父類的引用型別指向了父類本身
father.test(); //呼叫父類自己的方法,這個test()方法雖然被子類重寫但是呼叫的是父類中的test()方法
father.teach("John");
Father father1 = new Son(); //父類的引用型別指向子類
father1.teach("Eric"); //呼叫父類獨有的方法,不能呼叫子類獨有的方法
father1.test(); //呼叫子類重寫的test()方法,呼叫的是子類中的重寫後的方法
//子類的引用型別不能指向父類
}
}
class Son extends Father{
//定義一了一個子類的屬性,無法重寫父類的name屬性
public String name;
//子類的獨有方法
public void study(String name){
System.out.println(name+"學生在學習");
}
//重寫父類的test()方法
public void test(){
System.out.println("子類的方法被呼叫了");
}
}
class Father {
//定義了一個父類的屬性
public String name;
//父類的獨有方法
public void teach(String name){
System.out.println(name+"老師在教書");
}
public void test(){
System.out.println("父類的方法被呼叫了");
}
}