特質(zhì)和抽象類怎么選擇
- 優(yōu)先使用特質(zhì)啡直。一個(gè)類擴(kuò)展多個(gè)特質(zhì)是很方便的脱吱,但卻只能擴(kuò)展一個(gè)抽象類切油。
- 如果你需要構(gòu)造函數(shù)參數(shù)庆杜,使用抽象類。因?yàn)槌橄箢惪梢远x帶參數(shù)的構(gòu)造函數(shù)蛮拔,而特質(zhì)不行述暂。例如,你不能說trait t(i: Int) {}建炫,參數(shù)i是非法的畦韭。
類型
一個(gè)使用泛型鍵和值的緩存的例子
trait Cache[K, V] {
def get(key: K): V
def put(key: K, value: V)
def delete(key: K)
}
apply方法
當(dāng)類或者對(duì)象有一個(gè)主要用途時(shí),apply方法提供了一個(gè)很好的語法糖,可以讓實(shí)例化對(duì)象看起來像是在調(diào)用一個(gè)方法
scala> FooMaker
res5: FooMaker.type = FooMaker$@27305e6
scala> object FooMaker {
def apply() = ()=>println("1")}
| defined object FooMaker
scala> FooMaker
res6: FooMaker.type = FooMaker$@ce5a68e
scala> FooMaker()
res7: () => Unit = <function0>
單例對(duì)象
單例對(duì)象用于持有一個(gè)類的唯一實(shí)例肛跌。通常用于工廠模式
object Timer {
var count = 0
def currentCount(): Long = {
count += 1
count
}
}
scala> Timer.currentCount()
res0: Long = 1
模式匹配
- 匹配值
val times = 1
times match {
case 1 => "one"
case 2 => "two"
case _ => "some other number"
}
使用守衛(wèi)進(jìn)行匹配
times match {
case i if i == 1 => "one"
case i if i == 2 => "two"
case _ => "some other number"
}
- 匹配類型
def bigger(x:Any):Any={
x match {
case i:Int if i<0 => i-1
case i:Int if i>=0 => i+1
case d:Double if d<0.0 => d
case text:String => text
case _ => "fuck"
}
}
- 匹配樣本類成員
使用樣本類可以方便得存儲(chǔ)和匹配類的內(nèi)容艺配。你不用new關(guān)鍵字就可以創(chuàng)建它們察郁。
case class Calculator(brand: String, model: String)
def calcType(calc: Calculator) = calc match {
case Calculator("HP", "20B") => "financial"
case Calculator("HP", "48G") => "scientific"
case Calculator("HP", "30B") => "business"
case Calculator(ourBrand, ourModel) => "Calculator: %s %s is of unknown type".format(ourBrand, ourModel)
case Calculator(_, _) => "Calculator of unknown type"http://與上句相同
}
變性 Variance
Scala的類型系統(tǒng)必須同時(shí)解釋類層次和多態(tài)性
- 協(xié)變
scala> class Covariant[+A]
defined class Covariant
scala> val cv: Covariant[AnyRef] = new Covariant[String]
cv: Covariant[AnyRef] = Covariant@4035acf6
2.逆變
scala> class Contravariant[-A]
defined class Contravariant
scala> val cv: Contravariant[String] = new Contravariant[AnyRef]
cv: Contravariant[AnyRef] = Contravariant@49fa7ba
協(xié)變、逆變都是對(duì)應(yīng)泛型參數(shù)转唉,之前把泛型參數(shù)和函數(shù)參數(shù)搞混了皮钠。可以把協(xié)變逆變理解為一個(gè)殼子里套的某個(gè)參數(shù)支持協(xié)變逆變
class Animal { val sound = "rustle" }
class Bird extends Animal { override val sound = "call" }
class Chicken extends Bird { override val sound = "cluck" }
class Test[-R]{
def sum(a:Test[Bird]) ="wuxiang"
val a = new Test
a.sum(new Test[Bird])
res24: String = wuxiang
a.sum(new Test[Animal])
res25: String = wuxiang