【2019-06-04】scala抽象成員

不完全定義的類或特質的成員為抽象成員。抽象成員將被聲明類的子類實現(xiàn)怠蹂。
四種抽象成員:val、var、方法及類型

抽象類型val
定義形式:

//指定了val的名稱和類型氢烘,不指定值。
val initial:String
//值必須由子類的具體val定義提供
 class Concrete extends Abstract {
    type T = String
    def transform(x: String) = x + x
    val initial = "hi"
    var current = initial
  }
//抽象的val聲明類似于抽象的無參數(shù)方法聲明
def initial:String

抽象的val限制了合法的實現(xiàn)方法:任何實現(xiàn)都必須是val類型的定義家厌,不可以是var或def播玖。

//重寫的抽象val及無參數(shù)方法
object DefOverVal {
  abstract class Fruit {
    val v: String // `v' for value
    def m: String // `m' for method
  }
  
  abstract class Apple extends Fruit {
    val v: String
    val m: String // 可以用val重寫def
  }
  
  abstract class BadApple extends Fruit {
    def v: String // 錯誤:不能用def重寫val
    def m: String
  }
}

抽象var

object AbstractTime {
//只聲明名稱和類型,沒有初始值饭于。
  trait AbstractTime1 {
    var hour: Int
    var minute: Int
  }

//抽象var擴展為getter和setter方法
  trait AbstractTime2 {
    def hour: Int          // getter for `hour'
    def hour_=(x: Int)     // setter for `hour'
    def minute: Int        // getter for `minute'
    def minute_=(x: Int)   // setter for `minute'
  }


  // these traits combine with no conflict
  class AbstractTime extends AbstractTime1 with AbstractTime2 {
    var hour: Int = 10
    var minute: Int = 10
  }
}

初始化抽象val

object Misc {
  object Obj1 {
//參數(shù)化特質的方式就是通過需要在子類中實現(xiàn)的抽象val完成
    trait RationalTrait { 
      val numerArg: Int 
      val denomArg: Int 
    } 
//實例化特質蜀踏,實現(xiàn)抽象的val定義
    new RationalTrait {
      val numerArg = 1
      val denomArg = 2
    }

    val expr1 = 1
    val expr2 = 2
//expr1、expr2作為匿名類初始化的一部分計算掰吕,匿名類的初始化在RationalTrait之后
    new RationalTrait {
      val numerArg = expr1
      val denomArg = expr2
    }

//枚舉類型
    object Color extends Enumeration {
      val Red = Value
      val Green = Value
      val Blue = Value
    }

    import Color._
    val color1 = Red

    object Direction extends Enumeration {
      val North, East, South, West = Value
    }

 //創(chuàng)建具體的貨幣值
    new Currency {
      val amount = 79L
      def designation = "USD"
    }
//對美元和歐元建模為貨幣類的兩個子類
    abstract class Dollar extends Currency {
      def designation = "USD"
    }
    abstract class Euro extends Currency {
      def designation = "Euro"
    }

    abstract class CurrencyZone {
      type Currency <: AbstractCurrency
      def make(x: Long): Currency
      abstract class AbstractCurrency {
        val amount: Long
        def designation: String 
        def + (that: Currency): Currency = 
          make(this.amount + that.amount)
        def * (x: Double): Currency = 
          make((this.amount * x).toLong)
      }
    }

    object US extends CurrencyZone {
      abstract class Dollar extends AbstractCurrency {
        def designation = "USD"
      }
      type Currency = Dollar
      def make(x: Long) = new Dollar { val amount = x }
    }
  }

  object Obj2 {
//使用了抽象val的特質
    trait RationalTrait { 
      val numerArg: Int 
      val denomArg: Int 
      require(denomArg != 0)
      private val g = gcd(numerArg, denomArg)
      val numer = numerArg / g
      val denom = denomArg / g
      private def gcd(a: Int, b: Int): Int = 
        if (b == 0) a else gcd(b, a % b)
      override def toString = numer +"/"+ denom
    }
//對象定義中的預初始化字段
    object twoThirds extends {
      val numerArg = 2
      val denomArg = 3
    } with RationalTrait
//類定義中的預初始化字段
    class RationalClass(n: Int, d: Int) extends {
      val numerArg = n
      val denomArg = d
    } with RationalTrait {
      def + (that: RationalClass) = new RationalClass(
        numer * that.denom + that.numer * denom,
        denom * that.denom
      )
    }

    object Color extends Enumeration {
      val Red, Green, Blue = Value
    }

    abstract class CurrencyZone {
    
      type Currency <: AbstractCurrency
      def make(x: Long): Currency
    
      abstract class AbstractCurrency {
        val amount: Long
        def designation: String 
    
        def + (that: Currency): Currency = 
          make(this.amount + that.amount)
        def * (x: Double): Currency = 
          make((this.amount * x).toLong)
        def - (that: Currency): Currency = 
          make(this.amount - that.amount)
        def / (that: Double) = 
          make((this.amount / that).toLong)
        def / (that: Currency) = 
          this.amount.toDouble / that.amount
    
        def from(other: CurrencyZone#AbstractCurrency): Currency = 
          make(Math.round(
            other.amount.toDouble * Converter.exchangeRate
              (other.designation)(this.designation)))
    
        private def decimals(n: Long): Int = 
          if (n == 1) 0 else 1 + decimals(n / 10)
    
        override def toString = 
          ((amount.toDouble / CurrencyUnit.amount.toDouble)
           formatted ("%."+ decimals(CurrencyUnit.amount) +"f")
           +" "+ designation)
      }
    
      val CurrencyUnit: Currency
    }

    object Converter {
//帶有匯率表的轉換器對象
      var exchangeRate = Map(
        "USD" -> Map("USD" -> 1.0   , "EUR" -> 0.7596, 
                     "JPY" -> 1.211 , "CHF" -> 1.223),
        "EUR" -> Map("USD" -> 1.316 , "EUR" -> 1.0   , 
                     "JPY" -> 1.594 , "CHF" -> 1.623),
        "JPY" -> Map("USD" -> 0.8257, "EUR" -> 0.6272, 
                     "JPY" -> 1.0   , "CHF" -> 1.018),
        "CHF" -> Map("USD" -> 0.8108, "EUR" -> 0.6160, 
                     "JPY" -> 0.982 , "CHF" -> 1.0  )
      )
    }
  }

  class Outer {
    class Inner
  }
}

抽象類型

object Animals {
//用抽象類型建模合適的食物
  class Food
  abstract class Animal {
    type SuitableFood <: Food
    def eat(food: SuitableFood)
  }

  class Grass extends Food
//在子類中實現(xiàn)抽象類型
  class Cow extends Animal {
    type SuitableFood = Grass
    override def eat(food: Grass) {}
  }

}

路徑依賴類型

//不同的路徑產生不同類型
 class DogFood extends Food
  class Dog extends Animal {
    type SuitableFood = DogFood
    override def eat(food: DogFood) {}
  }

懶加載val

//讓系統(tǒng)本身管理初始化的順序
//通過懶加載 val初始化特征
 trait LazyRationalTrait { 
    val numerArg: Int 
    val denomArg: Int 
    lazy val numer = numerArg / g
    lazy val denom = denomArg / g
    override def toString = numer +"/"+ denom
    private lazy val g = {
      require(denomArg != 0)
      gcd(numerArg, denomArg)
    }
    private def gcd(a: Int, b: Int): Int = 
      if (b == 0) a else gcd(b, a % b)
  }
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末果覆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子殖熟,更是在濱河造成了極大的恐慌局待,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異钳榨,居然都是意外死亡舰罚,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門薛耻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來营罢,“玉大人,你說我怎么就攤上這事饼齿∷茄” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵候醒,是天一觀的道長能颁。 經常有香客問我,道長倒淫,這世上最難降的妖魔是什么伙菊? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮敌土,結果婚禮上镜硕,老公的妹妹穿的比我還像新娘。我一直安慰自己返干,他們只是感情好兴枯,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著矩欠,像睡著了一般财剖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上癌淮,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天躺坟,我揣著相機與錄音,去河邊找鬼乳蓄。 笑死咪橙,一個胖子當著我的面吹牛,可吹牛的內容都是我干的虚倒。 我是一名探鬼主播美侦,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼魂奥!你這毒婦竟也來了菠剩?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤捧弃,失蹤者是張志新(化名)和其女友劉穎赠叼,沒想到半個月后擦囊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡嘴办,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年瞬场,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涧郊。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡贯被,死狀恐怖,靈堂內的尸體忽然破棺而出妆艘,到底是詐尸還是另有隱情彤灶,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布批旺,位于F島的核電站幌陕,受9級特大地震影響,放射性物質發(fā)生泄漏汽煮。R本人自食惡果不足惜搏熄,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望暇赤。 院中可真熱鬧心例,春花似錦、人聲如沸鞋囊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽溜腐。三九已至译株,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工鼠证, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赞季,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓肃续,卻偏偏與公主長得像黍檩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子始锚,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內容