一、方法重載:
在同一個類中,允許存在一個及以上的同名方法,只要他們的參數列表不同(參數的個數或者參數的類型不同)即可。注意方法重載與返回值類型、訪問權限修飾符、和拋出的異常無關。重載是在本類中,與繼承關系無關。
(1)為什么要進行方法重載?
剛剛接觸java的同學,可能會對方法重載的用處有點疑惑。方法重載最經典的就是構造器了,我們知道構造器是和類名一致的,但我們要用不同的方式來實例化對象時,單一的構造器已經不能滿足我們的要求,所以這時就用到了方法重載,方法重載起源於構造器。
當然除了構造器之外我們也可以在其他方法中用到方法重載,例如一個程序完成兩個數相加,如果不用方法重載時,我就需要寫n個方法,給n個方法起n個方法名,在調用時我不知道該調用哪一個,然后翻來翻去才找到,這很不利於別人來使用這些方法。原本這些方法完成的功能都是一致的,為了統一管理和調用方便,所以引入方法重載這一概念。
public class Test { //方法1 public static int add(int a, int b) { return a + b; } //方法2 public static double add(int a, double b) { return a + b; } //方法3 public static double add(double a, int b) { return a + b; } //方法4 public static int add(int a, int b, int c) { return a + b + c; } //方法5 public static int add(int... a) { int temp = 0; for(int i = 0; i < a.length; i++) { temp += a[i]; } return temp; } public static void main(String[] args) { } }
如上面的代碼,有因為不同數據類型的重載、有參數位置不同的重載、有參數個數不同的重載。由此看來重載還是很強大的。
(2)重載方法的調用
有了方法,我們就要想該怎樣使用這些方法,當我們傳實參時,編譯器會調用哪個方法呢?這其中就有一個匹配度的問題,編譯器會自動調用高匹配度的那個方法,例如:當我add(1,1);時會調用方法1,因為他的匹配度為100(安全匹配)。當然編譯器找不到那個完全匹配的方法,會調用實參類型能夠自動轉化成形參類型的那個方法(兼容性匹配)。但這也就引發了問題,當我把方法1去掉,再調用add(1,1);這時會調用哪個方法?答案是編譯器會報錯。因為方法2與方法3的匹配度是相同的,引起了沖突。
最后方法重載支持可變參數重載,可變參數本身就相當於一個數組,在匹配中他的匹配度是最低的,當其他方法不滿足時,才會調用可變參數方法。
二、方法重寫:
方法的重寫與方法的重載沒有一點關系,硬要說有關系,那就是它們很容易被弄混。
class Person{ public void say() { System.out.println("人說話"); } } public class Student extends Person{ @Override public void say() { System.out.println("學生說話"); } }
(1)為什么要進行方法重寫:
方法的重寫發生在繼承關系中,在繼承中子類可以繼承父類中的除了構造器、靜態屬性、靜態方法、內部類、代碼塊外的所有東西。方法也不例外,但是如果父類的方法並不能滿足我的需求,這時候子類就需要對父類的方法進行改造擴充,這就是方法的重寫。
(2)方法重寫遵循的規則:(下面的大於和小於是一種描述習慣)
1.重寫的方法與被重寫的方法的方法簽名要一致
2.子類重寫方法的訪問權限必須大於等於父類方法的訪問權限,例如父類方法用public修飾,那么子類方法也必須用public修飾。
3.重寫與被重寫的方法不能被static與final修飾
4.子類拋出的受檢異常不能大於父類的受檢異常(注意只針對受檢異常,非受檢異常沒有此限制)
5.子類的方法的返回值類型可以小於等於父類的返回值類型
6.子類不能重寫父類的private方法,添加@override注解會報錯,因為這個方法是父類私有的子類不能訪問,雖然子類繼承了這個方法,但是子類只有擁有權沒有使用權。如果去掉@override注解就不會再報錯,所以說進行方法重寫時要記得添加@override注解,讓編譯器幫助你做檢查。
當以個方法被子類重寫了,調用這個方法時,調用的時重寫后的方法,但如果你就是想調用原來的方法,可以通過super關鍵字來實現。super關鍵字是一個標識,代表父類內存空間的標識。super可以用於訪問父類中定義的屬性,可以用於調用父類中定義的成員方法(例如toString中可以調用父類的toString然后再拼接上子類的特有的東西)、可以在子類中調用父類的構造器(后面詳細說明)。
文章中有不對的地方,請批評指正!