jvm 過載重寫原理

2021-08-09 03:08:25 字數 1185 閱讀 7102

乙個過載的栗子:

class parent ...

class child extends parent ...

class overload

}這個是呼叫的是:overload(parent p)方法。雖然p的實際引用型別是child;

這要提到兩個重要的概念:

上段栗子中,對於物件p來說,parent稱為其 靜態型別或者外觀型別,child是其實際型別。物件本身的靜態型別是不會變的,但是實際型別是可以變化的,要在實際執行**中才能確定。

那麼依賴靜態型別來定義方法執行版本的分派動作稱為靜態分派。典型應用就是過載。

同理依賴實際型別來定義方法執行版本的分派動作稱為動態分派。典型應用就是重寫。

其實重寫的原理也是繼承多型的原理。

乙個多型+重寫(覆蓋)的栗子:

class parent --> print方法

class child extends parent --> print方法

parent p = new child(); p.print();

將子類賦值給父類p,p只能呼叫parent中的方法,但是print方法被重寫了,print的實現還是child中的實現。

以上兩個類,載入到jvm中,類資訊會被儲存在方法區。

像開頭那樣,用乙個基類的引用指向子類物件,這個引用繫結的類仍然是子類,只不過它能訪問的方法表與一般子類物件不同,方法表會限定這個類訪問的方法範圍為引用類定義的範圍內。

class編譯過程中不包含連線步驟,一切的方法呼叫在class檔案中儲存的都是符號引用,而方法的實際呼叫需要到類載入期間,甚至執行期間才能確定。

1、在類載入的解析期間會將其中一部分符號引用轉化為直接引用。包括私有方法以及靜態方法,這兩種方法都不會通過繼承或者重寫的方式被覆蓋。譬如:

invokestatic和invokespecial,能被這兩個指令呼叫的方法都可以在類載入解析階段確定呼叫版本,如:靜態方法,私有方法,類構造器,父類方法,這些方法會在編譯器將符號引用解析為直接引用。這些方法稱為非虛方法。另外final修飾的方法雖然是被invokevirtual呼叫,也是非虛方法。

2、上面栗子中,方法呼叫時使用invokevirtual 呼叫的是parent的print的方法,卻是child的實現。invokevirtual會做如下事情:先找到實際型別,在實際型別中尋找相符的方法,若沒找到,則按照繼承關係從下到上尋找相符合的方法,若都沒找到丟擲異常。

過載 重寫 隱藏

共同點 函式名相同 定義 1 如果在類裡函式名相同但是形參不同,則為過載。形參不同包括形參的型別個數以及順序。2 類間。重寫和隱藏都發生在基類和派生類之間。重寫 覆蓋 發生在派生類和基類之間。必須滿足兩個條件 1 基類有virtual宣告 2 函式名和形參必須完全相同。隱藏 發生在派生類和基類之間,...

過載 重寫 許可權

1 過載建立繼承之上的 2 只跟過載方法引數有關係。無參和有參的構造就是屬於過載 引數個數不同 引數型別不同 3 屬於多型中的一種 4 子類可以對父類繼承過來的方法的過載。1 建立在繼承基礎上 2 子類存在與父類一模一樣的方法,那麼這樣的方法就是重寫方法。3 子類物件執行這個重寫方法時,不在執行從父...

C 重構 過載 重寫

來,我們問一下自己 建構函式是幹什麼的?重構是什麼?重寫是什麼?過載是什麼?重寫和過載聯絡的是什麼?重構與過載的區別是什麼?重寫和重構又是什麼關係?它們分別怎麼用?重構是重新構什麼?重寫又是在重寫什麼?過載載的又是什麼?哈哈,撒了吧 建構函式 是一種特殊的方法。主要是用來在建立物件的時初始化物件,即...