天天看點

Java中的重載和重寫關于Java中重載和重寫的一些問題

關于Java中重載和重寫的一些問題

重載:

概念:

指 在一個類中,多個方法(包括構造方法)的方法名相同,但是形參清單不同,即參數個數、類型、順序不同。調用時,Java虛拟機(JVM)會根據傳入的實參清單,去選擇合适的方法執行。

重載,是一個類中 多态的表現;

注意:

1.不能對 通路權限、傳回類型、抛出的異常 進行重載;

2.使用重載時隻能通過不同的形參清單,且必須具有不同的清單;

3.異常的類型和數目不會影響重載;

舉例:

1.傳回類型不同 或者 參數類型相同,順序不同,不能重載

public static int add(int a,int b){
        return (a+b);
    }
    public static long add(int a,int b){
        return (a+b);
    }

           

2.參數類型,個數、順序 不同 可以 重載(可以有不同的 通路權限,傳回類型)

public static void main(String[] args) {
        // 根據 傳入實參不同 調用相應的方法
        add(,'s');  // 注意 此處 沒有比對到 方法,則會  隐式轉換,就近原則轉換。
        add(,L);
        add(L,);
    }

    // 測試 方法的重載
    public static int add(int a,int b){
        System.out.println("1.111");
        return (a+b);
    }
    private static long add(int a,long b){
        System.out.println("2.2222");
        return (a+b);
    }
    protected static int add(long b,int a){
        System.out.println("3.333");
        return (int) (a+b);
    }
           

重寫:

概念:

首先,重寫,是針對,繼承關系的父類和子類之間關系的。

子類繼承父類,繼承了父類中所有(非私有,不同包則 非預設)屬性和方法,

當子類可以根據需要修改父類的方法,擴充其功能,這樣的操作就稱為

重寫,也叫覆寫/覆寫.重寫:是指子類中的方法與父類中繼承的方法有完全相同的傳回值類型、方法名、參數個數以及參數類型。

重寫規則:

==”兩同兩小一大“規則==

”兩同“:方法名,形參清單 相同;

“兩小”:子類的 傳回值類型,抛出的異常,小于父類;

比如:父類抛出IOException 則子類隻能抛出 同類型以及 其子異常;
           

“一大”:子類的 通路權限,大于 父類的 通路權限;

比如:父類是 預設 權限,則子類隻能是同權限或者 protected或者

public(注意,預設權限,異包子類不能通路)。
           

調用規則:

對于 父類對象:

調用的是 自身的 方法;
           

對于子類對象:

F s = new S();// 父類變量 指向 子類 執行個體

  s.add();
   調用的是 重寫的 方法,當子類沒有重寫父類的 方法時 ,調用的是 父類的方法。
           
public static void main(String[] args) {
        F f = new F();
        f.add();// 調用自身 方法

        F s = new S();
        s.add();// 調用 重寫 方法
        s.add3();//  調用 父類 方法
}
class F{

    void add(){
        System.out.println("父類add方法");
    }
    protected void add2(){
        System.out.println("父類add2方法");
    }
    public void add3(){
        System.out.println("父類add3方法");
    }
}
class S extends F{

    public void add(){// 重寫 時 通路權限 應 大于等于 父類
        System.out.println("子類add2方法");
    }
    protected void add2(){
        System.out.println("子類add2方法");
    }
}
           

重載和重寫的差別;

override(重寫)

   1、方法名、參數、傳回值相同。

   2、子類方法不能縮小父類方法的通路權限。

   3、子類方法不能抛出比父類方法更多的異常(但子類方法可以不抛出異常)。

   4、存在于父類和子類之間。

   5、方法被定義為final不能被重寫。

 overload(重載)

  1、參數類型、個數、順序至少有一個不相同。

  2、不能重載隻有傳回值不同的方法名。

  3、存在于父類和子類、同類中。

對于重寫的一點深入探讨

先上代碼:

public class Base {

    private String baseName= "base";
    public Base(){
        callName();
    }

    public void callName(){
        System.out.println(baseName);
    }

    static class Sub extends Base{
        private String baseName = "sub";
        public void callName(){
            System.out.println(baseName);
        }
    }

    public static void main(String[] args){
        Base b = new Sub();
    }

}
           

上述代碼輸出時什麼?

分析:

1.首先,看結構,一個外部類,一個靜态内部類,靜态内部類繼承了外部類,最後一個main方法測試。

2.我們看,main方法中 Base b = new Sub(); 父類變量 指向了 子類的引用,那麼明顯的,在方法中調用的是 子類的callName 方法。

這裡我們要清楚調用順序:

new Sub() 時 是先建立 父類對象,再去建立 子類對象,即,先會調用 父類的構造器,則會調用 callName() 方法,而 該方法 被 子類重寫,則會調用 子類的callName() 方法,但是,此時 子類還沒有構造,那麼 這裡的 baseName 就是 一個 null 值;

3.

執行 Base b = new Sub();時,由于多态 b編譯時表現為Base類特性,運作時表現為Sub類特性,Base b = new Sub();不管是哪種狀态都會調用Base構造器執行 callName()方法;執行方法時,由于多态表現為子類特性,是以會先在子類是否有 callName();而此時子類尚未初始化(執行完父類構造器後才會開始執行子類),如果有 就 執行(此時,因為還沒有調用子類構造函數, 是以子類的 baseName 輸出為 null),沒有再去父類尋找。

如果是這樣的:

public static void main(String[] args){
        Base b = new Sub();
        b.callName();
    }
           

則會輸出 :

null

sub

總的來說:

先成員變量再構造方法,先父類再子類

多态表現:有同名方法執行子類的