標籤:main 初始化 ffffff pre called str update 執行個體化 ack
我們在使用scala的時候經常會用到對象的apply方法和update方法。
雖然我們表面沒有察覺,但是實際上兩個方法都會遵循相關約定被調用。
apply
apply方法的約定:用括弧傳遞給變數(對象)一個或多個參數的時候,會把它轉換成對apply方法的調用。
我們先看一個例子。
class ClassApplyTest{ //類的apply方法調用樣本 def apply(param:String): String ={ println("apply method called,the paramter is "+param); "Hello,world";//傳回值 }}object Main{ def main(args:Array[String]): Unit ={ val myApply = new ApplyTest;//執行個體化ApplyTest println(myApply("param1"));//傳入參數param1 }}
輸出結果
apply method called,the paramter is param1
Hello,world
我們從上個例子看到,我們給ApplyTest類執行個體一個對象myApply,然後給myapply傳入了param1的參數。
過程中並沒有調用對象的apply方法,myapply對象自己調用了apply方法。
我們再看一個例子
object SingleObjectApplyTest{//單例對象的apply方法調用樣本 def apply(param1:String,param2:String):String = { println("apply method called"); param1+" and "+param2; } def main(args:Array[String]): Unit ={ val myApply = SingleObjectApplyTest("zyh","zqy");
//注意,我們這裡建的是單例對象不是類,並不用new關鍵字。 println(myApply); }}
輸出結果
apply method called
zyh and zqy
我們定義了一個單例對象,並在對象中定義了apply方法。
當我們建立單例對象並傳參的時候自動調用了apply方法返回了param1 and param2到了myApply。
class ClassAndObjectApplyTest{ //伴生類和對象apply方法的結合使用}class ApplyTest{ def apply()={ println("apply method in class is called."); } def greetingFromClass = println("Greet method is called."); //沒有參數的時候可以省略圓括弧}object ApplyTest{ def apply() = { println("apply method in object is called."); new ApplyTest;//返回一個ApplyTest類型的執行個體 }}object ClassAndObjectApplyTest{ def main(args:Array[String]): Unit ={ val myApply = ApplyTest();//ApplyTest伴生對象的調用,這裡的括弧一定不能省略 //注意,我們這裡沒有new關鍵字,是對ApplyTest的伴生對象的調用 //伴生對象會自動調用伴生對象的apply方法 myApply.greetingFromClass; myApply(); //ApplyTest伴生類的調用 //然後自動調用了伴生類的apply方法 }}
輸出結果
apply method in object is called.
Greet method is called.
apply method in class is called.
我們這個例子包含了兩對的伴生類和對象。
因為我們這裡並沒有任何參數,所以我們這裡使用()就是向其傳入參數。
我們在調用ApplyTest伴生對象並傳參的時候,自動調用了ApplyTest伴生對象的apply方法,返回一個ApplyTest伴生類的一個執行個體對象。
我們可以通過ApplyTest伴生類的對象訪問類中的方法,雖然被執行個體化了但是並沒有傳遞參數,所以並沒有調用其apply方法。
當我們執行myApply()的時候是對ApplyTest伴生類傳參的操作,因為沒有參數,所以只加了圓括弧,然後自動調用其apply方法。
下面看一個scala文法中的apply的例子
val myStrArr = Array("BigDate","Hadoop","Spark");
注意到,我們在定義數組的時候,並沒有像Java那樣需要使用new關鍵字建立,
沒有new執行個體,並不能用構造器建立,而且還直接傳遞了三個參數,怎麼建立的呢?
其實這裡,scala就會自動轉換成對Array的伴生對象apply方法的調用,完成數組的建立和初始化。
update
update方法的約定:當對帶有圓括弧並包括一到若干參數的對象進行賦值時,編譯器將調用對象的update方法。
在調用時,是把括弧裡的參數和等號右邊的對象一起作為方法的輸入參數來執行調用。
樣本
val myStrArr = new Array[String](3);//聲明一個長度為3的字串數組myStrArr(0) = "BigDate";//這裡正好符合了update方法的調用規則 //調用了伴生類的Array的update方法 //執行了myStrArr.update(0,"BigDate")
從上個例子可以看出,在進行數組賦值的時候,之所以沒有向java一樣採用了myStrArr[0]這樣的賦值的方式,
而是採用了update方法的賦值機制,為了能觸發update方法的機制,所以才使用myStrArr(0)這樣圓括弧的形式進行賦值。
【scala】apply和update