您好,登錄后才能下訂單哦!
泛型介紹:泛型用于指定方法或類可以接受任意類型參數,參數在實際使用時才被確定,泛型可以有效 地增強程序的適用性,使用泛型可以使得類或方法具有更強的通用性。泛型的典型應用場景 是集合及集合中的方法參數。
泛型方法:指定方法可以接受任意類型參數。
泛型類:指定類可以接受任意類型參數。
例:
object GenericTypeTest01 {
def main(args: Array[String]): Unit = {
println(new Student11[String,Int]("黃渤",33).name)
println(new Student12[String,Int]("zs",18).name)
println(new Student22[String,Int]("zs",8).age)
}
}
class Student12[T,S](var name:T,var age:S){}
class Student11[T,S](var name:T, var age:S){}
class Person11[T](var name:T)
class Student22[T,S](name:T,var age:S) extends Person11(name) {}
類型變量界定是指在泛型的基礎上,對泛型的范圍進行進一步的界定,從而縮小泛型的具體范圍。
例:
object Test01 {
def main(args: Array[String]): Unit = {
var generic=new Generic
val result: Int = generic.compare("aa","bb")
}
}
class Generic{
/**
*T<:Comparable 表示compare方法中如果輸入的類型處于Comparable類對應的繼承體系中,則是合法的,否則編譯不通過
* 作用是:當調用泛型的方法是,但是不知道這個泛型是否有這個方法,此時使用泛型的類型變量界定,縮寫范圍,使得,泛型中有這個方法
*/
def compare[T<:Comparable[T]](first:T,second:T)={
val result=if(first.compareTo(second)>0) 1 else 0
result
}
}
類型變量界定建立在類繼承的層次上,但有時候這種限定不能滿足實際要求,如果希望跨越類繼承層次結構時,可以使用視圖界定來實現,原理是通過隱式轉換來實現。
隱含參數和方法也可以定義隱式轉換,稱作視圖。視圖的綁定從另一個角度看就是 implicit 的轉換。其實視圖的綁定就是為了更方便的使用隱式轉化,視圖界定利用<%符號來實現。
例:
object Test01 {
def main(args: Array[String]): Unit = {
var ann1 = new Animals("zs", "18")
var ann2 = new Animals("zs", 18)
}
}
case class Animals[T, S <: Comparable[S]](var name: T, var age: S)
此時如果在[T, S <: Comparable[S]]使用<:的話,在運行的時候會報錯
因為:在類型變量界定的使用,默認的只能界定的類的是繼承體系中的一員才成立,如果是使用隱式轉換的方式默認不成立。上面代碼:String類繼承了Comparable,但是Int沒有繼承Comparable,只是隱式的將Int轉換成了RichInt,RichInt繼承了Comparable,所以此處出現了錯誤。
如果想隱式轉換也可以通過泛型的話可以:
object Test01 {
def main(args: Array[String]): Unit = {
var ann1 = new Animals("zs", "18")
var ann2 = new Animals("zs", 18)
}
}
case class Animals[T, S <% Comparable[S]](var name: T, var age:
利用<%號對泛型 S 進行限定,它的意思是 S 可以是 Comparable 類繼承層次結構中實現了 Comparable 接口的類,也可以是能夠經過隱式轉換得到的實現了 Comparable 接口的類。
在指定泛型類型時,有時需要界定泛型類型的范圍,而不是接收任意類型。比如,要求某個 泛型類型,必須是某個類的子類,這樣在程序中就可以放心的調用父類的方法,程序才能正 常的使用與運行。此時,就可以使用上下邊界 Bounds 的特性; Scala 的上下邊界特性允許泛型類型是某個類的子類,或者是某個類的父類。
U>:T這是類型下界的定義,也就是 U 必須是類型 T 的父類(或本身,自己也可以認為是自己的父 類)。
S<:T這是類型上界的定義,也就是 S 必須是類型 T 的子類(或本身,自己也可以認為是自己的子 類)。
上界:
class Generic2{
//指定上界,T必須是Comparable的子類或者是Comparable
def compare[T<:Comparable[T]] (first:T,second:T) ={
}
}
下界:
class Generic3{
//指定下界,T必須是Comparable的父類或者是Comparable
def compare[T>:Comparable[T]] (first:T,second:T) ={
}
}
object Test01 {
def main(args: Array[String]): Unit = {
var list1:MyList[Person]=new MyList(new Person)
var list2:MyList[Son]=new MyList(new Son)
list1=list2
}
}
class Person
class Son extends Person
class MyList[+T](val value:T)
這種方式,在list中只能將子類轉化成為父類的list,如果在轉變之后,這個list中也只能存放子類的類型對象。協變的性質:輸入的類型必須是 Son 的超類。
逆變
逆變定義形式如:trait List[-T]{}
當類型 B 是類型 A 的子類型,則 Queue[A]反過來可以認為是 Queue[B}的子類型。也就是被參數化類型的泛化方向與參數類型的方向是相反的,所以稱為逆變(contravariance)。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。