泛型類        ---> T 可以代表任意類型class Person[T]{   private var nam..."/>
溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Scala 語言學習之泛型(7)

發(fā)布時間:2020-06-13 13:40:04 來源:網絡 閱讀:6303 作者:菜鳥的征程 欄目:開發(fā)技術

==> 泛型類

        ---> T 可以代表任意類型

class Person[T]{
  private var name:T = _

  def setName(name:T) = {this.name = name}
  def getName():T = {this.name}
}

// ***********測試*****************
object Person{
  def main(args:Array[String]):Unit = {
    var p = new Person[String]()
    p.setName("hello")
    println(p.getName())
  }
}


==> 泛型函數(shù)

        ---> 類型參數(shù)放在方法名之后

//* 泛型函數(shù)
// 創(chuàng)建一個固定類型的數(shù)組
// 普通函數(shù)
def mkInt(elems:Int*) = Array[Int](elems:_*)
def mkString(str:String*) = "mkString"

// 使用泛型函數(shù),可以接收任意類型
def mkArray[T:ClassTag](elems:T*) = Array[T](elems:_*)

// ***********測試*****************
// 普通函數(shù)只能傳入相對應類型的參數(shù)
mkInt(1,2,3)
mkString("hello", "world")

// 泛型函數(shù)可以傳入任意類型的參數(shù)
mkArray(11.26,665, 84, "hello")


==> 類型的上界和下界(Upper Bounds 和 Lower Bounds)

        ---> 用來定義泛型變量的范圍 :  

        ---> S <: T  (上界)        S 必須是 T 類型的子類類本身

class Person1{
  def gender() = {println("gender")}
}

class Man extends Person1{
  override def gender() = {println("man")}
}

class Women extends Person1{
  override def gender() = {println("women")}
object UpperBoundsAndLowerBounds {
  // 定義一個泛型函數(shù),通過上界的方式指定泛型的范圍必須是 Person1 的子類或者Person1 類,并調用類中的 gender 方法
  def getGender[T <: Person1](g:T) = {g.gender()}

  def main(args:Array[String]): Unit = {
    // 創(chuàng)建一個Person1 對象 ,調用getGender 方法調用 Personal 中的 gender 方法
    var p:Person1 = new Person1
    getGender(p)

    // 創(chuàng)建一個 Man 對象 ,通過 getGender 方法調用Man 類中的 gender 方法
    var m = new Man
    getGender(m)
  }

}


        ---> U >: T(下界)        U 必須是 T 類型的父類類本身,此處不作示例,與上面例子類似,只是傳入 getGender 方法中的參數(shù)必須是 Person1 類其父類的對象


==> 視圖界定    <%

        ---> 與類型的上界相似,但是比類型的上界適用范圍更廣,除了所有的子類與類本身,它還允許通過隱式轉換得到的類型

def int2String[T <% String](x:T, y:T) = {
  println(x + "*****" + y)
}

// ***********測試*****************
int2String("hello", "world")
implicit def int2String1(n:Int):String = {n.toString}
int2String(100, 120)


==> 協(xié)變和逆變

        ---> 協(xié)變: 泛型變量的值可以是子類類本身     在類型參數(shù)前加一個 “+” 符號    轉換為父類

//* 協(xié)變和逆變   在類型的前面加入 +號,就可以使類的特征變?yōu)閰f(xié)變了
// 將子類對象轉換為父類對象稱為協(xié)變 +
// 將父類對象轉換為子類對象稱為逆變 -
package demo1{
  // 父類
  class Animal{}
  // 子類
  class Bird extends Animal
  class Sparrow extends Bird
  
  // 吃東西的類      協(xié)變
  class EatSomethings[+T](t:T){}

  // ***********測試*****************
  object Demo1{

    def main(args:Array[String]): Unit={
      // 創(chuàng)建一個吃東西的對象
      var c1:EatSomethings[Sparrow] = new EatSomethings[Sparrow](new Sparrow)

      var c2:EatSomethings[Animal] = c1
    }
  }
}


        ---> 逆變: 泛型變量的值可以是父類類本身    在類型參數(shù)前加一個 “ ” 符號    父類轉換為子類    例:省略


==> 隱式轉換函數(shù)    

        ---> 以關鍵字  implicit   申明

        ---> 單個參數(shù)

class Fruit(name:String){
  def getFruitName():String = {name}
}

class Monkey(f:Fruit){
  def say() = {println("Monkey like " + f.getFruitName()) }
}

// ***********測試*****************
object ImplicitDemo {
  def main(args:Array[String]):Unit = {
    var f:Fruit = new Fruit("bnanan")

    // 調用 fruit 的方法,希望 Monkey這個say 方法來實現(xiàn)
    // 需要將 fruit 的對象轉換為 monkey 對象, 即定義一個隱匿轉換函數(shù)
    implicit def fruit2Monkey(f:Fruit):Monkey = {new Monkey(f)}     // 將 fruit 對象轉換為 Monkey 對象
    // 調用Monkey中的 say 方法
    f.say()
  }
}


==> 隱式參數(shù)    使用 implicit 關鍵字申明的函數(shù)參數(shù)

        ---> 可以使用隱式參數(shù)進行類型轉換

// 隱式參數(shù)
def testParam(implicit name:String) = {println("The value is " + name)}
implicit val name:String = "這是一個隱式值"

// ***********測試*****************
testParam
//---------------------------------------------------------------

// 帶隱式參數(shù)的泛型函數(shù)
// Ordered[T] 使類型可排序,
//     原型:def smaller
// (implicit order:T      =>    Ordered[T])
def smaller[T](a:T, b:T)(implicit order:T => Ordered[T]) = if(order(a) < b) a else b

// ***********測試*****************
smaller(100, 56)
smaller("hello", "hi")


==> 隱式類    對類  增加 implicit 限定 的類,其主要作用就是對類的功能增強

        ---> 編寫一個隱式類,使類實現(xiàn)更多的功能

object testImplicit {

  // 定義一個隱式類
  implicit class Calc(x:Int){
    def add(a:Int):Int = a + x
  }

  // ***********測試*****************
  def main(args:Array[String]):Unit = {
    println("兩個數(shù)字的和:" + 1.add(2))
  }
}

        ---> 程序過程分析:

                --- 當 1.add(2)時,scala 的編譯器不會報錯,在當前域中查找,有沒有 implicit 修飾的,同時可以將 Int 作為參數(shù)的構造器,并且具有 add 方法的類,通過查找,找到 Calc

                --- 利用隱式類 Calc 來執(zhí)行 add 方法


==> 個人總結:

        ---> 通過泛型,可以使我們定義一個模具,就像蛋糕的模具,我們可以分別放入草莓,藍莓等不同的原料加工出不同口味的蛋糕來

        ---> 通過使用 上界,下界,視圖界定,協(xié)變,逆變,對泛型的范圍制定規(guī)則,使我們可以傳入的符合規(guī)則的參數(shù)

        ---> 隱式函數(shù),隱式參數(shù),隱式類,會在程序運行時首先被查找,若有符合 以 implicit 修飾的參數(shù),函數(shù)以及類,先執(zhí)行,然后才運行程序


若總結有誤,還請多多指教,謝謝?。。?/b>


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI