很多時候,某個Java類中有多個類似的方法。如Math類中,計算絕對值的方 法就會有多個,因為對不同數據類型的數計算方式不同。比如對float,int, long,double各類型的計算方式各不相同,那麼Math類中就應該設計4個求絕對 值的方法,分別對每種類型進行計算。在這種情況下,最好的方式就是設計4個 同名,但是不同參的方法,如下所示(請參見API幫助文檔):
abs(double a) Returns the absolute value of a double value. abs(float a) Returns the absolute value of a float value. abs(int a) Returns the absolute value of an int value. abs(long a) Returns the absolute value of a long value.
這就是方法重載,英文為overloading。方法重載的定義為:在一個Java類中 ,多個同名,但是不同參的方法,稱為方法重載。方法重載主要能提高代碼的可 讀性,對方法的使用者提供便利。
說到方法重載,還有一個特別容易混淆的概念就是方法覆蓋,也稱為方法重 寫,英文為overridding。方法覆蓋是在繼承時才有的概念。先從代碼入手。
如父類Employee中有如下方法:
public void setSalary(double salary,double rate) { this.salary = salary*(1+rate); }
假設Employee的子類Sales中,也有該業務邏輯,只不過實現方式有些不同。 假設實現方式如下:
this.salary = salary*(1+2*rate);
這種時候,就可以在子類Sales中,定義一個與父類同名同參的方法:
public void setSalary(double salary,double rate) { this.salary = salary*(1+2*rate); }
這就是方法覆蓋。即子類中擁有一個與父類同名同參同返回值,但是方法體 的邏輯有些區別的方法,我們就稱為子類覆蓋了父類某個方法。覆蓋父類方法後 ,如下調用:
Sales s=new Sales();
s.setSalary(6000,0.1);
此時調用的是子類的setSalary方法,也就是說,子類Sales的對象,再也調 用不到Employee中的setSalary(double,double)方法,因為這個方法已經被 Sales重寫成自己的setSalary(double,double)了。
初學者看到這個定義,往往有一個疑問。既然Sales類的setSalary方法的邏 輯有所不同,那麼為什麼非要定義成與父類同名的方法,不能重新命名麼?如:
public void setSalesSalary(double salary,double rate) { this.salary = salary*(1+2*rate); }
如果這樣定義,一樣能夠完成新的邏輯。那麼方法覆蓋有意義麼?
假設我們在Sales中定義了setSalesSalary方法,那麼Sales中還擁有 Employee的setSalary方法:
public void setSalary(double salary,double rate) { this.salary = salary*(1+rate); }
這樣以來,就導致Sales類中擁有一個Sales對象不該具有的行為,這是大錯 特錯的。
方法覆蓋的概念總結如下:
1、子類中的方法與父類的方法同名、同參、同返回值
2、子類的方法的訪問權限不能縮小,只能等同或者擴大
3、子類的方法不能拋出比父類方法更多的異常類型(異常處理會在以後文章 中講解)
方法重載,方法覆蓋是兩個容易混淆的概念,其實是完全沒有關聯的。重載 指的是一個類中,多個同名不同參的方法,而覆蓋是在父類與子類中存在的概念 。