弄清楚如何在物件上應用方法呼叫非常重要。比如下面假設要呼叫x.f(args)
,隱式引數x宣告為類c的乙個物件。下面是呼叫過程的相信資訊。
編譯器檢視物件的宣告型別和方法名。假設呼叫x.f(args)
,且隱式引數x宣告為c類的物件。要注意的是,可能有多個名字為f的方法,但是它們的引數型別和返回名稱不同。比如:f(int)和f(string)。編譯器將會一一枚舉所有c類中名為f的方法和其超類中訪問屬性為public且名為f的方法(超類私有方法不可以訪問)。
接下來,編譯器檢視呼叫方法時提供的引數型別。如果有方法f完全匹配,就是用該方法,這個過程被稱為過載解析,不過允許引數型別轉換,比如int可以轉換為double等等。如果編譯器沒有找到與引數型別匹配的方法,或者發現經過型別轉換後有多個方法與之匹配,就報錯。
如果是private、static或final方法,編譯器可以準確地知道呼叫哪個方法,我們將這種方法呼叫稱為靜態繫結(static banding)。與之相對應的是,呼叫的方法依賴於隱式引數的實際型別,並且在執行時實現動態繫結。
當程式執行時,並且採用動態繫結呼叫方法時,虛擬機器一定呼叫與x引用物件實際型別最合適的那個類的方法,如果當前類中沒有,還會在其父類中進行尋找。
因為每次呼叫方法都需要進行搜尋,時間開銷比較大。因此虛擬機器預先為每個類建立了乙個方法表,其中列出了所有方法的簽名和實際呼叫的方法。
有時候希望阻止利用某個類定義子類。不允許擴充套件的類被稱為final類。假如,我們阻止人們定義executive的子類,可以這樣宣告:
public
final
class
executive
extends
manager
將一種型別強制轉換為另一種型別的過程被稱為型別轉換。例如:
double x =
3.405
;int nx =
(int
)x;
表示式x的值轉換為整數型別,將會丟失精度。範圍較大的數轉換為範圍較小的數將會丟失精度。在進行型別轉換時,我們應該養成良好的習慣,先看下能否成功地進行轉換,可以用instanceof進行實現。
if
(staff[1]
instanceof
manager
)
其次要注意以下幾點:
只能在繼承層次中進行型別轉換
在將超類轉為子類之前,應該是用instanceof進行檢查
理解函式呼叫
在函式呼叫過程中,需要切換堆疊,先介紹幾個常用的暫存器 esp 堆疊指標暫存器,這個暫存器指向當前堆疊的棧頂 ebp 堆疊基位址暫存器,這個暫存器指向堆疊的棧底 eip 指令暫存器,儲存了下一條指令的位址 有了上面的鋪墊,開始接受當函式呼叫時候指向call以及返回ret時候堆疊的狀態,當執行call...
關於Ruby中類方法與例項方法呼叫的理解
quote img quote 對此略懂,簡單解答下你的問題,這塊確實是ruby深入理解的關鍵點.首先,要明白一點 ruby一切皆物件.什麼意思呢?ruby乙個類也是乙個物件 使用xx.class知道它的類是class 它也具備方法 即所謂的類方法 這個可以稱之謂元類 metaclass 而ruby...
理解linux系統呼叫
1.系統呼叫和普通函式完全不同,系統呼叫實際上是0x80號中斷對應的中斷處理程式的子程式。換句話說,在linux系統上,0x80中斷是系統呼叫的統一入口。某個具體的系統呼叫是這個中斷處理程式的子程式,進入具體某個系統呼叫是通過核心定義的系統呼叫號碼來實現的。linux通過執行如下彙編 陷入核心執行系...