您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“Java Scala泛型方法怎么使用”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Java Scala泛型方法怎么使用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識(shí)吧。
泛型的意思是泛指某種具體的數(shù)據(jù)類型
, 在Scala中, 泛型用[數(shù)據(jù)類型]
表示. 在實(shí)際開發(fā)中, 泛型一般是結(jié)合數(shù)組或者集合來使用的, 除此之外, 泛型的常見用法還有以下三種:
泛型方法
泛型類
泛型特質(zhì)
泛型方法指的是把泛型定義到方法聲明上, 即:該方法的參數(shù)類型是由泛型來決定的
. 在調(diào)用方法時(shí), 明確具體的數(shù)據(jù)類型.
格式
def 方法名[泛型名稱](..) = { //... }
需求
定義方法getMiddleElement(), 用來獲取任意類型數(shù)組的中間元素.
思路一: 不考慮泛型直接實(shí)現(xiàn)(基于Array[Int]實(shí)現(xiàn))
思路二: 加入泛型支持.
參考代碼
//案例: 泛型方法演示. //細(xì)節(jié): 泛型方法在調(diào)用方法的時(shí)候 明確具體的數(shù)據(jù)類型. object ClassDemo01 { //需求: 用一個(gè)方法來獲取任意類型數(shù)組的中間的元素 //思路一:不考慮泛型直接實(shí)現(xiàn)(基于Array[Int]實(shí)現(xiàn)) //def getMiddleElement(arr: Array[Int]) = arr(arr.length / 2) //思路二: 加入泛型支持 def getMiddleElement[T](arr: Array[T]) = arr(arr.length / 2) def main(args: Array[String]): Unit = { //調(diào)用方法 println(getMiddleElement(Array(1, 2, 3, 4, 5))) println(getMiddleElement(Array("a", "b", "c"))) } }
泛型類指的是把泛型定義到類的聲明上, 即:該類中的成員的參數(shù)類型是由泛型來決定的
. 在創(chuàng)建對(duì)象時(shí), 明確具體的數(shù)據(jù)類型.
格式
class 類[T](val 變量名: T)
需求
定義一個(gè)Pair泛型類, 該類包含兩個(gè)字段,且兩個(gè)字段的類型不固定.
創(chuàng)建不同類型的Pair泛型類對(duì)象,并打印.
參考代碼
//案例: 泛型-演示泛型類的使用. //泛型類: 在創(chuàng)建對(duì)象的時(shí)候, 明確具體的數(shù)據(jù)類型. object ClassDemo02 { //1. 實(shí)現(xiàn)一個(gè)Pair泛型類 //2. Pair類包含兩個(gè)字段,而且兩個(gè)字段的類型不固定 class Pair[T](var a:T, var b:T) def main(args: Array[String]): Unit = { //3. 創(chuàng)建不同類型泛型類對(duì)象,并打印 var p1 = new Pair[Int](10, 20) println(p1.a, p1.b) var p2 = new Pair[String]("abc", "bcd") println(p2.a, p2.b) } }
泛型特質(zhì)指的是把泛型定義到特質(zhì)的聲明上, 即:該特質(zhì)中的成員的參數(shù)類型是由泛型來決定的
. 在定義泛型特質(zhì)的子類或者子單例對(duì)象時(shí), 明確具體的數(shù)據(jù)類型.
格式
trait 特質(zhì)A[T] { //特質(zhì)中的成員 } class 類B extends 特質(zhì)A[指定具體的數(shù)據(jù)類型] { //類中的成員 }
需求
定義泛型特質(zhì)Logger, 該類有一個(gè)變量a和show()方法, 它們都是用Logger特質(zhì)的泛型.
定義單例對(duì)象ConsoleLogger, 繼承Logger特質(zhì).
打印單例對(duì)象ConsoleLogger中的成員.
參考代碼
//案例: 演示泛型特質(zhì). object ClassDemo03 { //1. 定義泛型特質(zhì)Logger, 該類有一個(gè)a變量和show()方法, 都是用Logger特質(zhì)的泛型. trait Logger[T] { //定義變量 val a:T //定義方法. def show(b:T) = println(b) } //2. 定義單例對(duì)象ConsoleLogger, 繼承Logger特質(zhì). object ConsoleLogger extends Logger[String]{ override val a: String = "張三" } //main方法, 作為程序的主入口. def main(args: Array[String]): Unit = { //3. 打印單例對(duì)象ConsoleLogger中的成員. println(ConsoleLogger.a) ConsoleLogger.show("10") } }
在使用泛型(方法, 類, 特質(zhì))時(shí),如果要限定該泛型必須從哪個(gè)類繼承、或者必須是哪個(gè)類的父類。此時(shí),就需要使用到泛型的上下界
。
使用T <: 類型名
表示給類型添加一個(gè)上界,表示泛型參數(shù)必須要從該類(或本身)繼承.
格式
[T <: 類型]
例如: [T <: Person]的意思是, 泛型T的數(shù)據(jù)類型必須是Person類型或者Person的子類型
需求
定義一個(gè)Person類
定義一個(gè)Student類,繼承Person類
定義一個(gè)泛型方法demo(),該方法接收一個(gè)Array參數(shù).
限定demo方法的Array元素類型只能是Person或者Person的子類
測(cè)試調(diào)用demo()方法,傳入不同元素類型的Array
參考代碼
//案例: 演示泛型的上下界之 上界. object ClassDemo04 { //1. 定義一個(gè)Person類 class Person //2. 定義一個(gè)Student類,繼承Person類 class Student extends Person //3. 定義一個(gè)demo泛型方法,該方法接收一個(gè)Array參數(shù), //限定demo方法的Array元素類型只能是Person或者Person的子類 def demo[T <: Person](arr: Array[T]) = println(arr) def main(args: Array[String]): Unit = { //4. 測(cè)試調(diào)用demo,傳入不同元素類型的Array //demo(Array(1, 2, 3)) //這個(gè)會(huì)報(bào)錯(cuò), 因?yàn)橹荒軅魅隤erson或者它的子類型. demo(Array(new Person())) demo(Array(new Student())) } }
使用T >: 數(shù)據(jù)類型
表示給類型添加一個(gè)下界,表示泛型參數(shù)必須是從該類型本身或該類型的父類型.
格式
[T >: 類型]
注意:
例如: [T >: Person]的意思是, 泛型T的數(shù)據(jù)類型必須是Person類型或者Person的父類型如果泛型既有上界、又有下界。下界寫在前面,上界寫在后面. 即: [T >: 類型1 <: 類型2]
需求
定義一個(gè)Person類
定義一個(gè)Policeman類,繼承Person類
定義一個(gè)Superman類,繼承Policeman類
定義一個(gè)demo泛型方法,該方法接收一個(gè)Array參數(shù),
限定demo方法的Array元素類型只能是Person、Policeman
測(cè)試調(diào)用demo,傳入不同元素類型的Array
參考代碼
//案例: 演示泛型的上下界之 下界. //如果你在設(shè)定泛型的時(shí)候, 涉及到既有上界, 又有下界, 一定是: 下界在前, 上界在后. object ClassDemo05 { //1. 定義一個(gè)Person類 class Person //2. 定義一個(gè)Policeman類,繼承Person類 class Policeman extends Person //3. 定義一個(gè)Superman類,繼承Policeman類 class Superman extends Policeman //4. 定義一個(gè)demo泛型方法,該方法接收一個(gè)Array參數(shù), //限定demo方法的Array元素類型只能是Person、Policeman // 下界 上界 def demo[T >: Policeman <: Policeman](arr: Array[T]) = println(arr) def main(args: Array[String]): Unit = { //5. 測(cè)試調(diào)用demo,傳入不同元素類型的Array //demo(Array(new Person)) demo(Array(new Policeman)) //demo(Array(new Superman)) //會(huì)報(bào)錯(cuò), 因?yàn)橹荒軅魅? Policeman類獲取它的父類型, 而Superman是Policeman的子類型, 所以不行. } }
在Spark的源代碼中大量使用到了協(xié)變、逆變、非變,學(xué)習(xí)該知識(shí)點(diǎn)對(duì)閱讀spark源代碼很有幫助。
非變: 類A和類B之間是父子類關(guān)系, 但是Pair[A]和Pair[B]之間沒有任何關(guān)系
.
協(xié)變: 類A和類B之間是父子類關(guān)系, Pair[A]和Pair[B]之間也有父子類
關(guān)系.
逆變: 類A和類B之間是父子類關(guān)系, 但是Pair[A]和Pair[B]之間是子父類
關(guān)系.
如下圖:
語法格式
class Pair[T]{}
默認(rèn)泛型類是非變的
即: 類型B是A的子類型,Pair[A]和Pair[B]沒有任何從屬關(guān)系 3.2 協(xié)變
語法格式
class Pair[+T]
類型B是A的子類型,Pair[B]可以認(rèn)為是Pair[A]的子類型
參數(shù)化類型的方向和類型的方向是一致的。
語法格式
class Pair[-T]
類型B是A的子類型,Pair[A]反過來可以認(rèn)為是Pair[B]的子類型
參數(shù)化類型的方向和類型的方向是相反的
需求
定義一個(gè)Super類、以及一個(gè)Sub類繼承自Super類
使用協(xié)變、逆變、非變分別定義三個(gè)泛型類
分別創(chuàng)建泛型類對(duì)象來演示協(xié)變、逆變、非變
參考代碼
//案例: 演示非變, 協(xié)變, 逆變. object ClassDemo06 { //1. 定義一個(gè)Super類、以及一個(gè)Sub類繼承自Super類 class Super //父類 class Sub extends Super //子類 //2. 使用協(xié)變、逆變、非變分別定義三個(gè)泛型類 class Temp1[T] //非變 class Temp2[+T] //協(xié)變 class Temp3[-T] //逆變. def main(args: Array[String]): Unit = { //3. 分別創(chuàng)建泛型類來演示協(xié)變、逆變、非變 //演示非變. val t1:Temp1[Sub] = new Temp1[Sub] //val t2:Temp1[Super] = t1 //編譯報(bào)錯(cuò), 因?yàn)榉亲兪? Super和Sub有父子類關(guān)系, 但是Temp1[Super] 和 Temp1[Sub]之間沒有關(guān)系. //演示協(xié)變 val t3:Temp2[Sub] = new Temp2[Sub] val t4:Temp2[Super] = t3 //不報(bào)錯(cuò), 因?yàn)閰f(xié)變是: Super和Sub有父子類關(guān)系, 所以Temp2[Super] 和 Temp2[Sub]之間也有父子關(guān)系. //Temp2[Super]是父類型, Temp2[Sub]是子類型. //演示逆變 val t5:Temp3[Super] = new Temp3[Super] val t6:Temp3[Sub] = t5 //不報(bào)錯(cuò), 因?yàn)槟孀兪? Super和Sub有父子類關(guān)系, 所以Temp3[Super] 和 Temp3[Sub]之間也有子父關(guān)系. //Temp3[Super]是子類型, Temp3[Sub]是父類型. } }
讀到這里,這篇“Java Scala泛型方法怎么使用”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。