第四章 系統軟體介紹
4.2. 繼承(I NHERITANCE )機制說明
在物件導向(Object-Oriented)的程式語言,繼承是相當重要的一個特性,在談實作繼承 機制前我們先對繼承的行為做說明,所謂繼承,是指物件型別物件的資源可以延伸和重複使 用,像是可以透過子物件型別或是子物件型別產生的物件呼叫繼承至父物件型別實作的方法、
存取父物件型別宣告的 field data,在使用上,我們在程式中可以利用 extends 關鍵字來表示 繼承關係,而 JAVA 的語法只允許單一繼承(Single Inheritance),也就是說子物件型別同時只 能繼承一個父物件型別,這邊需注意的一點在 JAVA 語言中雖然只允許單一繼承,但是當我 們卻可以使用 extend 讓介面去繼承多個介面時,但是在物件型別格式(Class format)上形式 會將繼承的介面資訊放在表示這個物件型別有實作的介面資訊上,而非放在表示這個物件型 別的父物件型別資訊上,實作介面的資訊如何解讀這部份我們放在後面章節討論。
為了實現上述特性,我們在物件型別解析的流程設計上,需要在解析每個物件型別檔時
4D4D 4553 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0044 0000 0000 0000 0000 0000 0000 0000 003C 0000 0040 0000 0000 0000 0000 0000 0063 18D4 0063 18D8 0063 18C8 0001 0001 0001 0001 2AB7 000C B100 0001 0003 0002 0003 2A1B B500 142A 1CBC 0AB5 0016 B100
Class Simple Table
Method Code
先完成其父物件型別的解析,以建立完整的子物件型別映像檔,這邊是以遞迴的方式去解析 物件型別檔,所以愈上層的物件型別會愈先被完成解析,其遞迴演算法的流程如圖 20 所示。
圖20. 在物件型別解析的流程中實作繼承的機制
除了解析父物件型別外,我們還需要從父物件型別的資料結構上複製部分資訊到目前解 析物件型別的資料結構中,這邊包含了物件大小、介面資訊(interface info)、Field Data 以及
Parse constant pool
Check this class’s parent class has been parsed or not.
Continue parse this class No
Yes
Parse parent class
Continue parse this class Copy info from parent class
圖21. 產生新物件時在記憶體中配置的情形
介面資訊(interface info)主要複製內容包含實作的介面數量以及被實作介面的 Class ID,
讓呼叫介面方法時透過父物件型別實作的介面,也可以找到子物件型別有繼承或覆寫的方法,
這邊關於介面的應用詳細內容以及複製介面資訊的原由我們保留在下一個章節 4.3 來討論。
另外這邊在說明複製 Field Data 資訊前,我們先針對 Field Data 的參照資料(Reference Data)上的資料結構再做詳細的描述,在 32bit 的 Field Data 參照資料中我們使用前 16bit 表 示 Class ID 表示 field data 所屬的物件型別,當繼承至父物件型別時這部分會替換成子物件型 別的 Class ID,而後半段的 16bit 拆成 4bit 表示 Field Tag,Field Tag 分別表示其是否為靜態的 Field Data、基本型態、長整數型態以及當 Field Data 存放的是記憶體中的位址時,所表示的 是陣列或是物件的起始位置,另外在 XRT 上我們還新增了 32bit 的 Static Field Address 欄位 用以存放當今天是靜態 Field Data 時,所有物件應該都會參照到的相同記憶體空間位址,以 上結構的說明,(如圖 22、表 2 列舉 Field Tag 所表示的意義所示),要特別注意的是除了長 整數的 Field Data 在物件上是佔 64bit 的空間,其他型態的資料都是以 32bit 的空間來存放,
在位移量也除了長整數型態是加二表示佔兩個 words 的空間,其餘每增加一個資料量為加一,
最後我們以實際例子來描述資料結構及其對應到的記憶體配置關係,(如圖 23 所示)。
Heap Memory Space
Class ID Field data
( inherited parent class) Field data
(define by this class)
Object size
圖22. 關於物件型別所定義的資料在資料結構中的表式
這邊對於 Field Tag 的意義除了在幫助我們分辨是否為靜態 field data 外,在後面章節所 提到的 Native Method 實作中也會需要參考其他 flag 資訊。
表 2 列舉 Field Tag 所表示的意義
所以在實作繼承機制時,子物件型別透過先複製父物件型別的靜態與非靜態 Field Data
Cross reference table
Class [x]
: :
Field Data[i] Field Name Class ID & Field Offset Field Tag
: :
Definition Access flag Reserve Primitive flag Long Type flag Array/Obj flag
Space (bit) 8 5 1 1 1
Field Tag Long
Access Flag
00000 | 110
Int 00000 | 100
Short 00000 | 100
Char 00000 | 100
Array 00000 | 001
Object 00000 | 000
圖23. 舉例描述物件型別資料結構中 Field Data 對應物件在 Heap Memory 上的關係
最後實作繼承至父物件型別的方法,僅需在子物件型別複製一份完整父物件型別方法的 資訊,包含方法的名稱、描述以及父物件型別方法完整的參照資訊[父物件型別 Class ID | Method Offset],這邊之所以不用替換 Class ID,是因為在我們設計的機制中當 invoke method 時,執行的位元組碼(bytecode)仍是使用位在父物件型別的執行映像檔(run time image)
上某個方法中。
Cross reference table
Class [5]
: :
Field Data[0] field_test_1 0x00056001 0x0106 Field Data[1] field_test_2 0x00054003 0x0104 Field Data[2] field_test_3 0x00051004 0x0101 Field Data[3] field_test_4 mem_addr 0x0904
: :
Heap Memory Space
5 (Class ID) Long Type D ata
Other Primitive Type Data Array Address
Static Data
Object base address
0x001 0x000
0x003 0x004
Array Data
Example :
public class test {
long field_test_1;
int field_test_2;
int field_test_3[] = new int[64];
static int field_test_4;
: }