※泛型類別、泛型方法
def genericMethod[T](t: T, list: List[T]): Unit = {}class Chicken[T] extends Bird {
def genericMethod(t: T, list: List[T]): Unit = {}
}
※寫在類別名稱或方法名稱後面
※傳參
class Animal{}class Bird extends Animal{}
class Chicken extends Bird{}
def main(args: Array[String]): Unit = {
val listA = List[Animal](new Animal)
val listB = List[Bird](new Bird)
val listC = List[Chicken](new Chicken)
xxx(listA, listB, listC)
}
def xxx(a: List[Animal], b: List[Bird], c: List[Chicken]): Unit = {
// ooo(a)
ooo(b)
ooo(c)
}
def ooo[T](list: List[Bird]) {}
※賦值
val listA = ListBuffer[Animal](new Animal)val listB = ListBuffer[Bird](new Bird)
val listC = ListBuffer[Chicken](new Chicken)
val a = new Animal()
val b = new Bird()
val c = new Chicken()
listA += a
listA += b
listA += c
// listB += a
listB += b
listB += c
// listC += a
// listC += b
listC += c
※以上都和 java 一樣
※沒有通配符「?」
※<:、>:
<::類似 java 的 extends
>::類似 java 的 super
.只能跟著自定義名稱,如 T
val listA = ListBuffer[Animal](new Animal)
val listB = ListBuffer[Bird](new Bird)
val listC = ListBuffer[Chicken](new Chicken)
ooo(listA)
ooo(listB)
// ooo(listC)
def ooo[T >: Bird](listBuffer: ListBuffer[T]) = {}
※+T、-T
如果只有 T,沒有辦法將子類轉成父類或父類轉成子類class GenericTest[T](t: T){} // +T、-T
class Animal{}
class Bird extends Animal{}
class Chicken extends Bird{}
.+T:表示子類可轉成父類
val a = new GenericTest[Animal](new Animal())val b = new GenericTest[Bird](new Bird())
val c = new GenericTest[Chicken](new Chicken())
val d:GenericTest[Animal] = b
val f:GenericTest[Bird] = c
val e:GenericTest[Animal] = c
.-T:表示父類可轉成子類
val a = new GenericTest[Animal](new Animal())val b = new GenericTest[Bird](new Bird())
val c = new GenericTest[Chicken](new Chicken())
val d:GenericTest[Chicken] = b
val f:GenericTest[Bird] = a
val e:GenericTest[Chicken] = a
※隱式轉換
.隱式方法
def printStr(data: String): Unit = println(data)// implicit def int2Str(i: Int):String = i + "xxx"
implicit def intToStr(j: Int):String = j.toString
// -------------------
printStr("abc")
printStr(123)
※用 java 的 overloading 也可以做到轉換的功能,但這裡說的是 scala 的隱式轉換
※如果沒有 implicit 的方法時,給 int 會編譯錯誤
※printStr 要的是 String 參數,但給的是 int,所以會去找參數是 int,回傳是 String 的隱式方法,如果有兩個(含)以上會報錯
再一個例子:
class Animal(name: String) {
private var iname: String = ""
def sname = name
def sname_=(name: String): Unit = {
this.iname = name
}
}
class Bird(name: String) {
private var iname: String = ""
def sname = name
def sname_=(name: String): Unit = {
this.iname = name
}
}
※兩個類別,然後給 getter/setter 方法
def printNameOfAnimal(animal: Animal): Unit = println(animal.sname)
implicit def birdToAnimal(b: Bird): Animal = {
new Animal("b" + b.sname)
}
// -------------------
printNameOfAnimal(new Animal("chicken"))
printNameOfAnimal(new Bird("chicken"))
.隱式值
object ScalaTest {implicit val xxx = new Animal("qoo")
def main(args: Array[String]): Unit = {
xxx("x")
}
def xxx(name: String)(implicit a: Animal): Unit = {
println(a.sname)
}
class Animal(name: String) {
private var iname: String = ""
def sname = name
def sname_=(name: String): Unit = {
this.iname = name
}
}
}
※有了隱式值了以後,呼叫 xxx 方法可以不用參數,當然 xxx 方法也要有 implicit 關鍵字
※如果值在其他的類別,就需要 import
.隱式參數
def printStr(implicit data: String, num: Int): Unit = println(data, num)// def printStr[T <% String](data: String, num: Int): Unit = println(data, num)
implicit def intToStr(j: Int):String = j.toString
printStr("abc", 7)
printStr(123, 7)
※這裡的隱式參數,雖然不寫也能找得到
※還可以用隱式視圖「<%」,但 IDE 提示我已經 deprecated 了,用隱式參數取代
.隱式類別
def main(args: Array[String]): Unit = {println(new Animal("xxx").show())
println("qoo".show())
}
implicit class Animal(name: String) {
def show(): String = {
name
}
}
※第二個 println 原本是不行的,但因為有隱式類別所以可以用
※隱式類別只能有一個參數,太多太少都不行
沒有留言:
張貼留言