Scala學習整理[第二十-二十一章 抽象成員和隱式轉換]

第二十章 抽象成員

package SecondWithProgrammingInScala

/**
  * 抽象成員
  * 不完全定義的類或者特質 ,包含val,var,def方法,type類型
  */
trait Abstract {
  //類型成員 : 簡化類型參數 ,方便定義
  type T

  def transform(x: T): T

  //表示確定的不會變化的值
  val initial: T
  //相當於生成了get/set方法
  var current: T
}

//實現時候必須要對所有抽象的成員進行實現
class Concrete extends Abstract {
  type T = String

  override def transform(x: String): String = initial + x

  override val initial: String = "hi"
  override var current: String = initial
}

//val的初始化 ,如果成員變量是一個表達式 x+3 ,
//在IntTest初始化的時候不會計算表達式 ,initial會被默認爲0
trait IntTest {
  val initial: Int
  val time: Int
  require(initial != 0)

  def result = time * initial
}

//val的懶加載
object LazyDemo {
  println("initial object")
  val x = println("initial x")
  lazy val y = println("initial y")

}

object AbstractApp {
  def main(args: Array[String]): Unit = {
    LazyDemo
    println
    LazyDemo.y

    val num = 2
    //預初始化
    val test1 = new {
      val initial = num + 3
    } with IntTest {
      val time = 2

      def print = println(result)
    }
    test1.print


    val testError = new IntTest {
      val initial = num + 3
      val time = 2
    }
  }
}

//合理利用抽象類型
trait Food {
  def name: String
}

abstract class Animal {
  def name: String

  type SuitableFood <: Food

  def eat(food: SuitableFood) = println(name + "吃" + food.name)
}

class Grass extends Food {
  override def name: String = "草"
}

class Cow extends Animal {
  override type SuitableFood = Grass

  override def name: String = "牛"
}

object AbstractTypeApp {
  def main(args: Array[String]): Unit = {
    //將抽象類型放在子類中指定 ,更細緻的控制
    val anima = new Cow
    val food = new Grass
    anima.eat(food)
  }
}

//枚舉
object Color extends Enumeration {
  val R = "red"
  val G = "green"
  val B = "blue"
}

第二十一章 隱式轉換和隱式參數

隱式轉換就像是自動的強制轉換類型 ,之前十九章的泛型中 ,一些類型限定/上下界限定/上下文限定等語法 ,其實就是爲了簡化隱式轉換 .

package SecondWithProgrammingInScala

import java.util.{Comparator, RandomAccess}

/**
  * 隱式轉換和參數
  */

//對一些已有的無法改動的類(如庫函數/第三方庫) ,擴展自己定義的方法
//通過隱式轉換 ,將類A->類B ,類B是具有需要的方法的類
class A {
  val name = "ClassA"
}

class B(val name: String) {
  def print = println("hello " + name)
}

object Transform {
  def main(args: Array[String]): Unit = {
    //定義隱式轉換將A->B
    /**
      * 隱式轉換和使用對象需要在一個作用域
      * 無歧義 ,同時只有一種隱式轉換可以調用
      * 每次只調用一個隱式轉換 ,不能嵌套
      * 優先執行顯示調用 ,只有無顯示方法纔會隱式轉換
      *
      * 類似Map(1->"A")中的->也是通過隱式轉化 ,轉化成Predef.ArrowAssoc ,並調用->方法
      */
    implicit def wapper(a: A) = new B(a.name)

    //使用a調用他並沒有的方法
    val a = new A
    a.print

    //隱式轉換還可以通過參數列表傳入
    def max1[T](a: T, b: T)(implicit cp: Comparator[T]) = {
      if (cp.compare(a, b) >= 0) a else b
    }

    //聲明參數並引入
    val cp = new Comparator[Int] {
      override def compare(a: Int, b: Int) = a - b
    }
    println(max1(5, 6)(cp))

    //直接聲明作用域變量
    implicit val cp2 = new Comparator[Int] {
      override def compare(a: Int, b: Int) = a - b
    }
    println(max1(5, 6))
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章