Scala編程之伴生對象
阿新 • • 發佈:2019-05-12
返回值 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") } }
反編譯看源碼
小結
- Scala中伴生對象采用 object關鍵字聲明,伴生對象中聲明的全是"靜態"內容,可以通過伴生對象名稱直接調用。
- 伴生對象對應的類稱之為伴生類,伴生對象的名稱應該和伴生類名一致
- 伴生對象中的屬性和方法都可以通過伴生對象名(類名)直接調用訪問
- 從語法角度來講,所謂的伴生對象其實就是類的靜態方法和成員的集合
- 從技術角度來講, scala還是沒有生成靜態的內容,只不過是將伴生對象生成了一個新的類,實現屬性和方法的調用。[反編譯看源碼]
- 從底層原理看,伴生對象實現靜態特性是依賴於 public static final MODULE$實現的
- 伴生對象的聲明應該和伴生類的聲明在同一個源碼文件中(如果不在同一個文件中會運行錯誤!),但是如果沒有伴生類,也就沒有所謂的伴生對象了,所以放在哪裏就無所謂了。
- 如果 class A獨立存在,那麽A就是一個類,如果 object A獨立存在,那麽A就是一個"靜態性質的對象[即類對象],在 object A中聲明的屬性和方法可以通過A.屬性和A.方法來實現調用
- 當一個文件中,存在伴生類和伴生對象且不存在其他類時,文件的圖標會發生變化
apply方法
apply方法是非常常用的,它主要的作用就是簡化創建對象的寫法
//創建一個List集合 val list=List(("A",0),("A",2),("B",1),("B",2),("C",1))
我們創建list的時候,並沒有new 創建對象,也沒有通過反射創建對象,那麽為什麽直接List()就可以創建一個list集合呢?答案就在List()底層實現了apply()方法
可以看到,底層實現了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編程之伴生對象