1. 程式人生 > >Scala編程之伴生對象

Scala編程之伴生對象

返回值 test 自動 serial list str img ctr 重載方法

伴生對象是scala中靜態的概念

Scala語言是完全面向對象(萬物皆對象)的語言,所以並沒有靜態的操作(即在 Scala中沒有靜態的概念)。但是為了能夠和Java語言交互(因為Java中有靜態概念),就產生了一種特殊的對象來模擬類對象,我們稱之為類的伴生對象。這個類的所有靜態內容都可以放置在它的伴生對象中聲明和調用。

伴生對象的使用

下面我們通過一個小案例,對伴生對象和伴生類的特點進行探討

//首先我們創建伴生類class ScalaPerson和伴生對象 object ScalaPerson,然後在裏面設置幾個方法和屬性
object AccompanyObject {

  def main(args: Array[String]): Unit = {

    println(ScalaPerson.sex) //true   底層等價於ScalaPerson$.MODULE$.sex
    ScalaPerson.sayHi  //object ScalaPerson sayHi  底層等價  ScalaPerson$.MODULE$.sayHi()
  }
}
//說明:
//當在一個文件之後有class ScalaPerson 和object ScalaPerson
//class ScalaPerson被稱為object ScalaPerson的伴生類,我們常常把非靜態內容寫進該類中
//object ScalaPerson被稱為class ScalaPerson的伴生對象,將靜態內容寫入該對象中
//class ScalaPerson在底層被編譯為class ScalaPerson.class
//object ScalaPerson在底層被編譯為class ScalaPerson$.class
class ScalaPerson{
  var name:String=_
}
object ScalaPerson{
  val sex:Boolean=true
  def sayHi: Unit ={
    println("object ScalaPerson sayHi")
  }
}

反編譯看源碼

技術分享圖片

小結

  1. Scala中伴生對象采用 object關鍵字聲明,伴生對象中聲明的全是"靜態"內容,可以通過伴生對象名稱直接調用。
  2. 伴生對象對應的類稱之為伴生類,伴生對象的名稱應該和伴生類名一致
  3. 伴生對象中的屬性和方法都可以通過伴生對象名(類名)直接調用訪問
  4. 從語法角度來講,所謂的伴生對象其實就是類的靜態方法和成員的集合
  5. 從技術角度來講, scala還是沒有生成靜態的內容,只不過是將伴生對象生成了一個新的類,實現屬性和方法的調用。[反編譯看源碼]
  6. 從底層原理看,伴生對象實現靜態特性是依賴於 public static final MODULE$實現的
  7. 伴生對象的聲明應該和伴生類的聲明在同一個源碼文件中(如果不在同一個文件中會運行錯誤!),但是如果沒有伴生類,也就沒有所謂的伴生對象了,所以放在哪裏就無所謂了。
  8. 如果 class A獨立存在,那麽A就是一個類,如果 object A獨立存在,那麽A就是一個"靜態性質的對象[即類對象],在 object A中聲明的屬性和方法可以通過A.屬性和A.方法來實現調用
  9. 當一個文件中,存在伴生類和伴生對象且不存在其他類時,文件的圖標會發生變化技術分享圖片

    apply方法

    apply方法是非常常用的,它主要的作用就是簡化創建對象的寫法

    //創建一個List集合
    val list=List(("A",0),("A",2),("B",1),("B",2),("C",1))

    我們創建list的時候,並沒有new 創建對象,也沒有通過反射創建對象,那麽為什麽直接List()就可以創建一個list集合呢?答案就在List()底層實現了apply()方法

    我們可以Ctrl +鼠標左鍵點擊List技術分享圖片
    可以看到,底層實現了apply方法
    我們現在來實際使用一下apply方法吧

object ApplyDemo extends App {

  //使用apply方法創建對象
  val pig1=Pig("佩奇") // 自動觸發apply(pname: String)
  val pig2=Pig()     //自動觸發apply()

  printf("小豬1為%s \n",pig1.name)//小豬1為佩奇
  printf("小豬2為%s \n",pig2.name)//小豬2為匿名Pig

}

class Pig(pname:String){
  var name=pname
}

object Pig{
  def apply(pname: String): Pig = new Pig(pname)   //自動生成
  def apply():Pig=new Pig("匿名Pig")    //重載方法

}

apply在實際生產中使用的特別多,雖然簡單,但是很重要。

我們可以利用本文的知識完成下面的問題~練練手~

下面的題,是一道java題,請使用scala完成該題的要求
1)在 Frock類中聲明私有的靜態屬性 currentNum,初始值為100000,作為衣服出廠的序列號起始值。
2)聲明公有的靜態方法 getNextNum,作為生成上衣唯一序列號的方法。每調用一次,將 currentNum增加100,並作為返回值
3)在 TestFrock類的main方法中,分兩次調用 getNextNum方法,獲取序列號並打印輸出
4)在Frock類中聲明 serialNumber(序列號)屬性,並提供對應的get方法;
5)在Frock類的構造器中,通過調用 getNextNum方法為Frok對象獲取唯一序列號,賦給 serialNumbe屬性。
6)在 Test Frock類的main方法中,分別創建三個 Frock對象,並打印三個對象的序列號,驗證是否按100遞增

Scala編程之伴生對象