什么時(shí)候應(yīng)該使用特質(zhì)而不是抽象類?
如果你想定義一個(gè)類似接口的類型,你可能會(huì)在特質(zhì)和抽象類之間難以取舍。這兩種形式都可以讓你定義一個(gè)類型的一些行為,并要求繼承者定義一些其他行為。一些經(jīng)驗(yàn)法則:
優(yōu)先使用特質(zhì)。一個(gè)類擴(kuò)展多個(gè)特質(zhì)是很方便的,但卻只能擴(kuò)展一個(gè)抽象類。
如果你需要構(gòu)造函數(shù)參數(shù),使用抽象類。因?yàn)槌橄箢惪梢远x帶參數(shù)的構(gòu)造函數(shù),而特質(zhì)不行。例如,你不能說(shuō)trait t(i: Int) {},參數(shù)i是非法的。
你不是問(wèn)這個(gè)問(wèn)題的第一人??梢圆榭锤娴拇鸢福?a target="_blank" rel="nofollow">stackoverflow: Scala特質(zhì)vs抽象類,抽象類和特質(zhì)的區(qū)別,andScala編程:用特質(zhì),還是不用特質(zhì)?
最大化當(dāng)前視圖或編輯器:Ctrl+M
只有在需要函數(shù)類型的地方,Scala才允許你省略這個(gè)僅有的_
堆
堆棧
允許客戶向函數(shù)傳入可變長(zhǎng)度參數(shù)列表。想要標(biāo)注一個(gè)重復(fù)參數(shù),可在參數(shù)的類型之后放一個(gè)星號(hào)
def echo(args:String*)=for(arg<-args)
println(arg)
echo(arr:_*)_*這個(gè)標(biāo)注告訴編譯器把a(bǔ)rr的每一個(gè)元素當(dāng)作參數(shù),而不是當(dāng)作單一的參數(shù)傳給echo
object
在scala中沒(méi)有靜態(tài)方法和靜態(tài)字段,所以在scala中可以用object來(lái)實(shí)現(xiàn)這些功能,直接用對(duì)象名調(diào)用的方法都是采用這種實(shí)現(xiàn)方式,例如Array.toString。對(duì)象的構(gòu)造器在第一次使用的時(shí)候會(huì)被調(diào)用,如果一個(gè)對(duì)象從未被使用,那么他的構(gòu)造器也不會(huì)被執(zhí)行;對(duì)象本質(zhì)上擁有類(scala中)的所有特性,除此之外,object還可以一擴(kuò)展類以及一個(gè)或者多個(gè)特質(zhì)
class
在scala中,類名可以和對(duì)象名為同一個(gè)名字,該對(duì)象稱為該類的伴生對(duì)象,類和伴生對(duì)象可以相互訪問(wèn)他們的私有屬性,但是
他們必須在同一個(gè)源文件內(nèi)。類只會(huì)被編譯,不能直接被執(zhí)行,類的申明和主構(gòu)造器在一起被申明,在一個(gè)類中,主構(gòu)造器只有一個(gè),
所有必須在內(nèi)部申明主構(gòu)造器或者是其他申明主構(gòu)造器的輔構(gòu)造器,主構(gòu)造器會(huì)執(zhí)行類定義中的所有語(yǔ)句。scala對(duì)每個(gè)字段都會(huì)提供
getter和setter方法,同時(shí)也可以顯示的申明,但是針對(duì)val類型,只提供getter方法,默認(rèn)情況下,字段為公有類型,可以在setter
方法中增加限制條件來(lái)限定變量的變化范圍,在scala中方法可以訪問(wèn)改類所有對(duì)象的私有字段
Scala中的=>符號(hào)可以看做是創(chuàng)建函數(shù)實(shí)例的語(yǔ)法糖。例如:A => T,A,B => T表示一個(gè)函數(shù)的輸入?yún)?shù)類型是“A”,“A,B”,返回值類型是T。請(qǐng)看下面這個(gè)實(shí)例:
scala> val f: Int => String = myInt =>"The value of myInt is: "+ myInt.toString()
f: Int => String =
scala> println(f(3))
The value of myInt is:3
上面例子定義函數(shù)f:輸入?yún)?shù)是整數(shù)類型,返回值是字符串。
另外,() => T表示函數(shù)輸入?yún)?shù)為空,而A => Unit則表示函數(shù)沒(méi)有返回值。
舉例:
[plain]view plaincopy
1.var?increase?=?(x:?Int)?=>?x?+?1
increase(10)
res0: Int = 11
類似于轉(zhuǎn)化符號(hào),=>指明這個(gè)函數(shù)把左邊的東西(任何整數(shù)x)轉(zhuǎn)變成右邊的東西(x + 1)。所以,這是一個(gè)把任何整數(shù)x映射為x + 1的函數(shù)。
//這個(gè)函數(shù)的定義體現(xiàn)了一種從外剝皮的狀態(tài)
//傳入第一個(gè)參數(shù)x的值之后,從新生成一個(gè)新的函數(shù),這個(gè)函數(shù)需要一個(gè)參數(shù)y
//當(dāng)輸入y的值之后將會(huì)得到最終的結(jié)果
def first(x:Int)=(y:Int)=>x+y
first: (x: Int)Int => Int
在Scala中符號(hào)“_”有一種待定的意思在里面
在擁有頭等函數(shù)的語(yǔ)言中,即使語(yǔ)言的語(yǔ)法是固定的,你也可以有效地制作新的控制結(jié)構(gòu)。所有你需要做的就是創(chuàng)建帶函數(shù)做參數(shù)的方法。