首先咱們來說講:重載(Overloading)java
(1) 方法重載是讓類以統一的方式處理不一樣類型數據的一種手段。多個同名函數同時存在,具備不一樣的參數個數/類型。web
重載Overloading是一個類中多態性的一種表現。編程
(2) Java的方法重載,就是在類中能夠建立多個方法,它們具備相同的名字,但具備不一樣的參數和不一樣的定義。函數
調用方法時經過傳遞給它們的不一樣參數個數和參數類型來決定具體使用哪一個方法, 這就是多態性。學習
(3) 重載的時候,方法名要同樣,可是參數類型和個數不同,返回值類型能夠相同也能夠不相同。沒法以返回型別做爲重載函數的區分標準。this
下面是重載的例子:
package c04.answer;//這是包名
//這是這個程序的第一種編程方法,在main方法中先建立一個Dog類實例,而後在Dog類的構造方法中利用this關鍵字調用不一樣的bark方法。spa
不一樣的重載方法bark是根據其參數類型的不一樣而區分的。設計
//注意:除構造器之外,編譯器禁止在其餘任何地方中調用構造器。
code
package c04.answer; public class Dog { Dog() { this.bark(); } void bark()//bark()方法是重載方法 { System.out.println(\"no barking!\"); this.bark(\"female\", 3.4); } void bark(String m,double l)//注意:重載的方法的返回值都是同樣的, { System.out.println(\"a barking dog!\"); this.bark(5, \"China\"); } void bark(int a,String n)//不能以返回值區分重載方法,而只能以「參數類型」和「類名」來區分 { System.out.println(\"a howling dog\"); } public static void main(String[] args) { Dog dog = new Dog(); //dog.bark(); [Page] //dog.bark(\"male\", \"yellow\"); //dog.bark(5, \"China\"); }
而後咱們再來談談 重寫(Overriding)orm
(1) 父類與子類之間的多態性,對父類的函數進行從新定義。若是在子類中定義某方法與其父類有相同的名稱和參數,咱們說該方法被重寫 (Overriding)。在Java中,子類可繼承父類中的方法,而不須要從新編寫相同的方法。
但有時子類並不想原封不動地繼承父類的方法,而是想做必定的修改,這就須要採用方法的重寫。
方法重寫又稱方法覆蓋。
(2)若子類中的方法與父類中的某一方法具備相同的方法名、返回類型和參數表,則新方法將覆蓋原有的方法。
如需父類中原有的方法,可以使用super關鍵字,該關鍵字引用了當前類的父類。
(3)子類函數的訪問修飾權限不能少於父類的;
下面是重寫的例子:
概念:即調用對象方法的機制。
動態綁定的內幕:
一、編譯器檢查對象聲明的類型和方法名,從而獲取全部候選方法。試着把上例Base類的test註釋掉,這時再編譯就沒法經過。
二、重載決策:編譯器檢查方法調用的參數類型,從上述候選方法選出惟一的那一個(其間會有隱含類型轉化)。
若是編譯器找到多於一個或者沒找到,此時編譯器就會報錯。試着把上例Base類的test(byte b)註釋掉,這時運行結果是1 1。
三、若方法類型爲priavte static final ,java採用靜態編譯,編譯器會準確知道該調用哪
個方法。
四、當程序運行而且使用動態綁定來調用一個方法時,那麼虛擬機必須調用對象的實際類型相匹配的方法版本。
在例子中,b所指向的實際類型是TestOverriding,因此b.test(0)調用子類的test。
可是,子類並無重寫test(byte b),因此b.test((byte)0)調用的是父類的test(byte b)。
若是把父類的(byte b)註釋掉,則經過第二步隱含類型轉化爲int,最終調用的是子類的test(int i)。
學習總結:
多態性是面向對象編程的一種特性,和方法無關,
簡單說,就是一樣的一個方法可以根據輸入數據的不一樣,作出不一樣的處理,即方法的
重載——有不一樣的參數列表(靜態多態性)
而當子類繼承自父類的相同方法,輸入數據同樣,但要作出有別於父類的響應時,你就要覆蓋父類方法,
即在子類中重寫該方法——相同參數,不一樣實現(動態多態性)
OOP三大特性:繼承,多態,封裝。
public class Base { void test(int i) { System.out.print(i); } void test(byte b) { System.out.print(b); } } public class TestOverriding extends Base { void test(int i) { i++; System.out.println(i); } public static void main(String[]agrs) { Base b=new TestOverriding(); b.test(0) b.test((byte)0) } }
這時的輸出結果是1 0,這是運行時動態綁定的結果。
重寫的主要優勢是可以定義某個子類特有的特徵:
public class Father{ public void speak(){ System.out.println(Father); } } public class Son extends Father{ public void speak(){ System.out.println("son"); } }
這也叫作多態性,重寫方法只能存在於具備繼承關係中,重寫方法只能重寫父類非私有的方法。
當上例中Father類speak()方法被private時,Son類不能重寫出Father類speak()方法,此時Son類speak()方法至關與在Son類中定義的一個speak()方法。
Father類speak()方法一但被final時,不管該方法被public,protected及默認所修飾時,Son類根本不能重寫Father類speak()方法,
試圖編譯代碼時,編譯器會報錯。例:
public class Father{ final public void speak(){ System.out.println("Father"); } } public class Son extends Father{ public void speak(){ System.out.println("son"); } } //編譯器會報錯;
Father類speak()方法被默認修飾時,只能在同一包中,被其子類被重寫,若是不在同一包則不能重寫。
Father類speak()方法被protoeted時,不只在同一包中,被其子類被重寫,還能夠不一樣包的子類重寫。
重寫方法的規則:
一、參數列表必須徹底與被重寫的方法相同,不然不能稱其爲重寫而是重載。
二、返回的類型必須一直與被重寫的方法的返回類型相同,不然不能稱其爲重寫而是重載。
三、訪問修飾符的限制必定要大於被重寫方法的訪問修飾符(public>protected>default>private)
四、重寫方法必定不能拋出新的檢查異常或者比被重寫方法申明更加寬泛的檢查型異常。例如:
父類的一個方法申明瞭一個檢查異常IOException,在重寫這個方法是就不能拋出Exception,只能拋出IOException的子類異常,能夠拋出非檢查異常。
而重載的規則:
一、必須具備不一樣的參數列表;
二、能夠有不責罵的返回類型,只要參數列表不一樣就能夠了;
三、能夠有不一樣的訪問修飾符;
四、能夠拋出不一樣的異常;
重寫與重載的區別在於:
重寫多態性起做用,對調用被重載過的方法能夠大大減小代碼的輸入量,同一個方法名只要往裏面傳遞不一樣的參數就能夠擁有不一樣的功能或返回值。
用好重寫和重載能夠設計一個結構清晰而簡潔的類,能夠說重寫和重載在編寫代碼過程當中的做用非同通常.