重寫(覆蓋)與重載 Override and Overload

 

覆蓋、重寫與重載的理解

初次見到這兩個單詞並沒有什麼特別的感覺,但是時間長了,卻發現書上一會兒用override,一會兒又用overload,搞得我的迷迷糊。於是就做了個總結,希望能對和我一樣對這兩個概念模糊不清的網友有一個幫助。

    override可以翻譯爲覆蓋,從字面就可以知道,它是覆蓋了一個方法並且對其重寫,以求達到不同的作用。對我們來說最熟悉的覆蓋就是對接口方法的實現,在接口中一般只是對方法進行了聲明,而我們在實現時,就需要實現接口聲明的所有方法。除了這個典型的用法以外,我們在繼承中也可能會在子類覆蓋父類中的方法。在覆蓋要注意以下的幾點:

   1、覆蓋的方法的標誌必須要和被覆蓋的方法的標誌完全匹配,才能達到覆蓋的效果;

   2、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致;

   3、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類;

   4、被覆蓋的方法不能爲private,否則在其子類中只是新定義了一個方法,並沒有對其進行覆蓋。

    overload對我們來說可能比較熟悉,可以翻譯爲重載,它是指我們可以定義一些名稱相同的方法,通過定義不同的輸入參數來區分這些方法,然後再調用時,VM就會根據不同的參數樣式,來選擇合適的方法執行。在使用重載要注意以下的幾點:

   1、在使用重載時只能通過不同的參數樣式。例如,不同的參數類型,不同的參數個數,不同的參數順序(當然,同一方法內的幾個參數類型必須不一樣,例如可以是fun(int, float) 但是不能爲fun(int, int));

   2、不能通過訪問權限、返回類型、拋出的異常進行重載;

   3、方法的異常類型和數目不會對重載造成影響;

   下面是對overrideoverload的測試程序,其中註釋中的內容都是會產生編譯錯誤的代碼,我們將註釋去掉,看看在編譯時會產生什麼效果。

// overload測試的文件:OverloadTest.java

public class OverloadTest {

 // 下面幾個方法用來驗證可以通過定義不同的參數類型和參數的數目進行方法重載。

 public void fun(){

  System.out.println("method fun in OverloadTest, no parameter");

 }

 

 public void fun(float f) {

  System.out.println("method fun in OverloadTest, parameter type: float");

 }

   

 public void fun(int i){

  System.out.println("method fun in OverloadTest, parameter type: int");

 }

 

 public void fun(int i1, int i2) {

  System.out.println("method fun in OverloadTest, parameter type: int, int");

 }

   

 // 下面的兩個方法用來驗證可以通過定義不同的參數順序進行方法重載。

 // 需要注意:這裏的參數肯定不是相同的類型,否則的順序的先後就毫無意義。

 public void fun1(int i, float f) {

  System.out.println("method fun1 in OverloadTest, sequence of parameters is: int, float");

 }

 

 public void fun1(float f, int i) {

  System.out.println("method fun1 in OverloadTest, sequence of parameters is: float, int");

 }

 

 // 下面的兩個方法用來驗證方法拋出的異常對於重載的影響.

 // 無論是異常的類型還是異常的個數都不會對重載造成任何的影響。

 public void fun2() throws TestException {

  System.out.println("fun2 in OverloadTest, exception: TestException");

 }

 

 public void fun2(int i) throws TestException, TestException1 {

  System.out.println("fun2 in OverloadTest, exception: TestException, TestException1");

 }

 

 public void fun2(float f) throws Exception {

  System.out.println("fun2 in OverloadTest, exception: Exception");

 }

 

 // 不能通過拋出的異常類型來重載fun方法。

 //public void fun(int i) throws Exception {

 // System.out.println("method fun in OverloadTest, parameter type: int, exception: Exception");

 //}

 

    // ? 不能通過返回值重載fun方法。

 //public boolean fun(int i) throws Exception {

 // System.out.println("method fun in OverloadTest, parameter type: int, exception: Exception, return: boolean");

 // return true;

 //}

 

 private void fun3() { }

 

 // 不能通過不同的訪問權限進行重載

 public void fun3() { }

 

 public static void main(String[] args) {

  // 這裏只是定義了OverloadTest的實例,所以test不會調用

  // OverloadTest1中的方法。

  OverloadTest test = new OverloadTest1();

  // 這裏定義了OverloadTest1的實例,因爲OverloadTest1OverloadTest

  // 的子類,所以test1會調用OverloadTest中的方法。

  OverloadTest1 test1 = new OverloadTest1();

 

  try {

   int i = 1, j = 2, m = 3;

 

   // 這裏不會調用OverloadTest1fun方法

   // test.fun(i, m, j);

   test1.fun(i, j, m);

   test1.fun();

   // 這個調用不會執行,因爲fun3()OverloadTest中訪問權限是priavte

   //test1.fun3();

   test1.fun3(i);

  } catch(Exception e) { }

 }

}

class OverloadTest1 extends OverloadTest{

 // 在子類中重載fun

 public void fun(int i, int m, int n) {

  System.out.println("Overload fun1 in OverloadTest1, parameter type: int, int, int");

 }

 

 // 這個不是對父類中方法的重載,只是一個新的方法。

 public void fun3(int i) {

  System.out.println("fun2 in OverloadTest1");

 }

}

 

// override測試的文件:OverrideTest.java

public class OverrideTest {

 public void fun() throws TestException {

  System.out.println("method fun in OverrideTest");

 }

 

 private void fun1() {

  System.out.println("method fun1 in OverrideTest");

 }

 

 public static void main(String[] args) {

  OverrideTest test = new OverrideTest1();

  try {

    test.fun();

    test.fun1();

  } catch(Exception e) { }

 }

}

 

class OverrideTest1 extends OverrideTest{

 // 以下正常Override

 public void fun() throws TestException2 {

  System.out.println("fun in OverrideTest1");

 }

 

 // 不能Override父類中的方法,因爲它定義了不同的異常類型和

 // 返回值。

 //public int fun() throws TestException1 {

 // System.out.println("method fun in Test");

 // return 1;

 //}

   

 // 不能Override父類中的方法,因爲它拋出了比父類中非法範圍

 // 更大的異常。

 //public void fun() throws Exception {

 // System.out.println("fun in OverrideTest1");

 //}

 

 // 這個方法並沒有Override父類中的fun1方法,因爲這個方法在

 // 父類是private類型,所以這裏只是相當於定義了一個新方法。

 public void fun1() {

  System.out.println("method fun1 in Test");

 }

}

 

class TestException extends Exception{

 public TestException(String msg) {

  super(msg);

 }

}

 

class TestException1 extends TestException {

 public TestException1(String msg) {

  super(msg);

 }

}

 

class TestException2 extends TestException {

 public TestException2(String msg) {

  super(msg);

 }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章