學習Scala 伴生物件和伴生類之間的關係 二

2021-10-01 19:13:15 字數 3128 閱讀 4890

孤立物件是只有乙個object關鍵字修飾的物件,該物件會編譯成兩個class檔案,乙個是以孤立物件的名字命名的class, 乙個是以孤立物件的名字後面加上乙個$ 字元命名的class, 這個class又叫做虛構類, 原始碼中的孤立物件中的字段和方法,都被編譯成以孤立物件的名字命名的class中靜態方法, 這些靜態方法都會訪問單例的虛構類物件。虛構類市傳統意義上的單例模式, 並且在類初始化的時候, 就會建立唯一的物件, 原始碼中的所有欄位和方法都會在虛構類中有相對應的成員.

伴生類和伴生物件. 所謂伴生物件,也是乙個scala中的單例物件,使用object關鍵字修飾, 除此之外,還有乙個使用class關鍵字定義的同名類, 這個類和單例物件存在於同乙個檔案中,這個類就叫做這個單例物件的伴生類,相對來說, 這個單例物件叫做伴生類的伴生物件.

伴生類和伴生物件的簡單例子:

class

test

object test

此時多了乙個伴生類, 伴生類中有乙個欄位field和乙個方法dosomething.

編譯這個檔案, 同時生成了兩個class, 乙個test.class和乙個test$.class, 這個test $.class叫做虛構類.

下面反編譯test.class.

單例物件(伴生物件)中的每個字段或者方法,都對應test類中的乙個靜態同名方法.從反編譯的結果就可以看到,這些靜態方法仍然存在. 這些方法如下:

public

static

void

printstring()

public

static string a()

除了這兩個靜態方法之外, test類中還存在一些其他的字段和方法, 這些欄位和方法都是成員方法,而不是靜態的。這些欄位和方法如下:

public string field()

public

void field_$eq

(string x$1

)private string field =

"field"

;public

void

dosomething()

這些欄位和方法是和伴生類中的字段和方法相對應的.其中會為字段field新增相關方法public void field_&eq(string x$1) 和

public string field(). 為字段新增同名getter()方法和***_&eq這樣的setter()方法. 是scala編譯器的預設行為。

總結一下:

1.伴生類中定義的字段和方法, 對應同名class類(如上例子中的test.class)中的成員欄位和成員方法

2. 伴生物件中的定義的字段和方法, 對應同名類(如上例子中的test.class)中的靜態方法,所以可以認為scala中的object關鍵字是靜態的另乙個表示方式, 只是scala將這些靜態的東西也封裝成了物件

3.伴生物件中定義的字段和方法,對應虛構類(test$.class)中的成員欄位和方法

4.同名類(如上例子中的test.class)中的靜態方法,會訪問單例的虛構類物件, 將相關的邏輯呼叫到虛構類中的成員方法中.由於虛構類是單例的, 所以可以保證伴生物件中的字段都是唯一的. 也就是說虛構類的單例性,保證了 伴生物件(即scala中的object修飾的單例物件)中資訊的唯一性.

5.我們在編寫scala**時,訪問伴生類的內容,需要建立物件來訪問, 訪問伴生物件時, 將其內部所有內容直接作為靜態, 通過類名. 的方式呼叫即可.

6.在scala中並沒有真正靜態的概念, 因為看起來像靜態呼叫訪問和呼叫的地方, 實際上是通過伴生物件自己的靜態單例物件來訪問和呼叫的.

注意下面的例子:

//伴生類

class

worker

def aa =

"printn"

}// 伴生物件

object worker

}}

編譯生成兩個class檔案, 乙個worker.class, 乙個是worker$.class

先反編譯worker.class

再編譯worker $.class

可以看出伴生類中定義的字段和方法, 在同名類中(worker.class)中有著相對應的字段和方法,在虛構類中不會出現相對應的字段和方法. 伴生物件中定義的字段和方法,對應虛構類(worker$.class)中的成員欄位和方法. 伴生物件中的定義的字段和方法, 對應同名類(如上例子中的worker.class)中的靜態方法.

注意的是: 在伴生物件中在haha方法裡定義了乙個test方法. 方法裡還有方法, 方法的巢狀, 從反編譯中可以看出的是, test方法並沒有出現在同名類(worker.class)中, 而是出現在虛構類(worker $.class)中, 而且還是靜態私有方法. 呼叫該方法直接通過方法名的形式來呼叫。 在haha方法裡定義了zhangshaojun變數, 型別為string. 值為"張少軍"。 從反編譯中可以看出的是: 該變數並沒有出現在同名類(worker.class)中, 而是出現在虛構類中test方法裡面, 並沒有出現在haha方法外面, 該變數也沒有類似於getter方法(public string zhangshaojun() )和setter方法(public void zhangshaojun_ $eq(int zhangshaojun$1) ) , zhangshaojun變數只出現在方法體內部. 只在haha方法區域性有效.

總結一下:

1.在伴生物件中如果在方法裡出現字段, 那麼在同名類中沒有對應的靜態方法, 只會出現在虛構類中方法裡的內部,在虛構類中沒有對應的getter方法和setter方法.

2.在伴生物件中如果在方法裡出現方法, 那麼在同名類中沒有對應的靜態方法, 只會出現在虛構類中。 並且還是靜態私有方法.

scala伴生類和伴生物件

伴生類和伴生物件在同一檔案中,名字相同 class類稱為object的伴生類,object稱為class的伴生物件 class person uname string,uage int def this name string def this age int println class 變數定義完...

scala伴生物件

美圖欣賞 一.背景 基礎不牢,地洞山搖。哈哈,來點乾貨補充能量 二.伴生物件 1.定義 在scala的類中,與類名相同並且用object修飾的物件叫做伴生物件,類和伴生物件之間可以相互訪問私有的方法和屬性,他們必須存在同乙個原始檔中 2.案例詳解 package day04 類名和類檔名稱可以不統一...

初學伴生類和伴生物件

伴生類和伴生物件應在同乙個檔案中,名字相同 class類稱為object的伴生類,object稱為class的伴生物件 例項1 class person uname string,uage int def this age int def this name string println class...