建立子類對象時,父類構造函數中調用被子類重寫的方法爲何調用的是子類的方法?

問題:建立子類對象時,父類構造函數中調用被子類重寫的方法爲何調用的是子類的方法,而被子類重載的方法不會調用?java

public class Basic{
    public void add(int i)
    {
        System.out.println("Basic add");
    }
    
    public Basic()
    {
        add('a');
    }
}

public class A extends Basic{
    public void add(int i)
    {
        System.out.println("A add");
    }
}

public class B extends Basic{
    public void add(char i)
    {
        System.out.println("B add");
    }
}

public class Main{
    public static void main(String[] args)
    {
        A a = new A();
        B b = new B();
    }
}

問題:爲何建立A對象的時候父類會調用子類方法? 可是:建立B對象父類會調用父類的方法?函數

答案: 當子類被加載到內存方法區後,會繼續加載父類到內存中。 若是,子類重寫了父類的方法,子類的方法引用會指向子類的方法,不然子類的方法引用會指向父類的方法引用。 若是子類重載了父類方法,則子類重載方法引用還指向子類方法。 若是子類方法沒有重寫也沒有重載父類方法,則方法引用會指向父類方法。code

當子類對象建立時,會先行調用父類的構造方法(構造方法也是方法),虛擬機會在子類方法區尋找該方法並運行。 可是:因爲java語言是靜態多分派,動態單分派。其結果是當編譯的時候,父類構造方法調用的方法的參數已經強制轉換爲符合父類方法的參數了。 上邊代碼在編譯前已經轉換爲下面這個樣子的了。對象

public class Basic{
    public void add(int i)
    {
        System.out.println("Basic add");
    }
    
    public Basic()
    {
        add((int)'a');
    }
}

public class A extends Basic{
    public void add(int i)
    {
        System.out.println("A add");
    }
}

public class B extends Basic{
    public void add(char i)
    {
        System.out.println("B add");
    }
}

public class Main{
    public static void main(String[] args)
    {
        A a = new A();
        B b = new B();
    }
}

看一下上邊的代碼,是否是恍然大悟?blog

更多文章:http://blog.gavinzh.com內存

相關文章
相關標籤/搜索