聊聊 Scala 的伴生對象及其意義


2019-04-22

關鍵字:Scala 伴生對象的作用

關於 Scala 伴生對象,比教材更詳細的解釋。


 

什么是伴生對象?

教材中關於伴生對象的解釋是:實現類似 Java 中那種既有實例成員有靜態成員的類的功能。

 

為什么上面說它是一種 “功能” 呢?因為要想實現像 Java 中那樣的類,光靠一個 Scala 類可不行。在 Scala 中,我們必須:

1. 定義一個 class 並在這里面實現所有的實例成員

2. 添加一個 object ,這個 object 要與上面的 class 同名,然后在這里面實現所有的靜態成員

3. 定義的 class 與 object 必須在同一個文件內

 

滿足了上面 3 條要求以后,就可以實現類似 Java 中一個類既存在實例成員又存在靜態成員的功能了。然后我們通常把第 2 步添加的 object 稱為 “伴生對象” 。轉化成代碼,就像下面這樣

class CompanionDemo {
  
  println("new CompanionDemo clz")
  
  def init(): Unit = {
    // our codes...
  }
  
}

object CompanionDemo {

  println("new CompanionDemo object")
  
  def prt(): Unit = {
    // our codes...
  }
  
}

 

伴生對象有什么特點?

毫無疑問,伴生對象這種存在最大的特點就是可以實現類似 Java 中那樣,在同一個類里既有實例成員又有靜態成員的功能。

 

另一個特點就是 class CompanionDemo 和 object CompanionDemo 雖然分開兩處定義,但卻可以訪問對方的 private 變量及方法。訪問私有屬性的一個小示例如下

class CompanionDemo {
  
  private var clzi = 0
  
  def init(): Unit = {
    
    println("variable in clz:" + clzi)
    println("variable from object:" + CompanionDemo.obji)
    CompanionDemo.access(this)
    
  }
  
}

object CompanionDemo {
  
  private var obji = 1
  
  def access(clz: CompanionDemo): Unit = {
    
    println("variable in object:" + obji)
    println("variable from clz:" + clz.clzi)
    
  }
  
}
相互訪問私有屬性

並通過如下代碼來訪問伴生對象

object cpDemp {
  
  def main(args: Array[String]){
    
    val cd = new CompanionDemo()
    cd.init()
    
  }
  
}

執行結果如下

variable in clz:0
variable from object:1
variable in object:1
variable from clz:0
如您所想的執行結果

 

伴生對象中要想訪問對方的私有屬性,需要注意以下 2 點

1. class 中要訪問 object 中的私有屬性,直接以 object 名來 “點” 相應的變量或方法即可,可以參考上面例子

2. object 中要訪問 class 中的私有屬性,必須要通過 class 的對象引用來 “點” 相應變量或方法,可以參考上面例子

 

伴生對象的意義是什么?

Scala 中沒有 static 關鍵字,而 Scala 又運行與 JVM 之上,與 Java 類庫完全兼容的編程語言,同時類中擁有靜態屬性又是如此的有必要,因此推出這個伴生對象機制就顯得很有必要了。所以第 1 個意義就是為了彌補類中不能定義 static 屬性的缺陷

 

那我們知道,在 Java 中靜態屬性是屬於類的,在整個 JVM 中只開辟一塊內存空間,這種設定使得靜態屬性可以很節省內存資源,不用擔心像實例屬性那樣有內存溢出的風險。在 Scala 中伴生對象本質上也是生成靜態屬性,所以這第 2 個意義就是節省內存資源

 

既然靜態屬性在整個 JVM 中僅開辟一塊內存空間,那就說明我們可以在所有實例當中共享這塊內存里面的信息,所以第 3 個意義就是資源共享

 


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM