1. 程式人生 > >快學scala 第十章 特質 讀書筆記及習題答案程式碼

快學scala 第十章 特質 讀書筆記及習題答案程式碼

chapter 10 特質

標籤:快學scala

一、筆記

  1. scala和java一樣不允許從多個超類繼承,scala提供特質而非介面。特質可以同時擁有抽象方法和具體方法,而類可以實現多個特質。 
    不需要將方法宣告為abstract,特質中未被實現的方法預設就是抽象的。在重寫特質的抽象方法時不需要給出override關鍵字。特質跟類更為相像。用with新增額外的特質:
  1. classConsoleLoggerextendsLoggerwithCloneablewithSerialiable

由上,Logger ith Cloneable with Serialiable首先是一個整體,然後再由類來擴充套件。 
2. 特質的方法並不需要一定是抽象的:

  1. trait ConsoleLogger{
  2. def log(msg:String){ println(msg)}
  3. }
  4. classSavingAccountextendsAccountwithConsoleLogger{
  5. def withdraw(amount:Double){
  6. if(amount > balance) log("Insufficient funds")
  7. else balance -= amount
  8. }
  9. }//scala與java的區別,SavingAccount從ConsoleLogger特質得到了一個具體的log方法,java的介面是不可能做到的。scala中是ConsoleLogger的功能被混入了SavingAccount類
  1. JVM中,一個類只能擴充套件一個超類,因此來自特質的欄位不能以相同的方式繼承。
  2. 對於特質的構造順序:首先呼叫超類的構造器。特質構造器在超類構造器之後、類構造器之前執行。特質由左到右被構造。每個特質當中,父特質先被構造。如果多個特質共有一個父特質,而那個父特質已經被構造,則不會被再次構造。所有特質構造完畢,子類被構造。
  1. classSavingsAccountextendsAccountwithFileLoggerwithShortLogger
  2. //構造順序是: Account(超類)Looger(第一個特質的父特質)FileLogger(第一個特質)ShortLogger(第二個特質,它的父特質Logger已被構造),SavingsAccount(類)
  1. 特質不能有構造器引數,每個特質都有一個無引數的構造器。缺少構造器引數是特質和類之間唯一的技術差別。
  1. val acct =newSavingsAccountwithFileLogger("myapp.log")//錯誤:特質不能使用構造器引數

FileLogger構造器先於子類構造器執行,在輪到子類之前,FileLogger的構造器就會丟擲一個空指標異常。解決方法是 “提前定義”:

  1. val acct =new{
  2. val filename ="myapp.log"
  3. }withSavingsAccountwithFileLogger//提前定義發生在常規的構造序列之前,在FileLogger被構造時,filename已經是初始化過的了
  1. 特質可以擴充套件另一個特質,特質也可以擴充套件類,這個類會自動成為所有混入該特質的超類。在特質擴充套件類時,編譯器能夠確保的是所有混入該特質的類都認這個類作超類。scala還有另一套機制保證:自身型別
  1. this:型別=>
  2. //當特質以這一定義開始時,它便被混入指定型別的子類
  1. trait LoggedExceptionextendsLogged{
  2. this:Exception=>
  3. def log(){ log(getMessage)}
  4. }//該特質並不擴充套件Exception類,而是有一個自身型別Exception,這意味著,它只能被混入Exception的子類。
  5. 如果把特質混入一個不符合自身型別要求的類,就會報錯
    6.

二、習題答案

10.1 java.awt.Rectangle類有兩個很有用的方法translate和grow,但可惜的是像java.awt.geom.Ellipse2D這樣的類沒有。在Scala中,你可以解決掉這個問題。定義一個RenctangleLike特質,加入具體的translate和grow方法。提供任何你需要用來實現的抽象方法,以便你可以像如下程式碼這樣混入該特質:

  1. val egg =new java.awt.geom.Ellipse2D.Double(5,10,20,30)withRectangleLike
  2. egg.translate(10,-10)
  3. egg.grow(10,20)
  1. import java.awt.geom.Ellipse2D
  2. trait RectangleLike{//使用自身型別使得trait可以操作x,y
  3. this:Ellipse2D.Double=>
  4. def translate(x:Double, y:Double){
  5. this.x = x
  6. this.y = y
  7. }
  8. def grow(x:Double, y:Double){
  9. this.x += x
  10. this.y += y
  11. }
  12. }
  13. objectTestextendsApp{
  14. val egg =newEllipse2D.Double(5,10,20,30)withRectangleLike
  15. println("x = "+ egg.getX +" y = "+ egg.getY)
  16. egg.translate(10,-10)
  17. println("x = "+ egg.getX +" y = "+ egg.getY)
  18. egg.grow(10,20)
  19. println("x = "+ egg.getX +" y = "+ egg.getY)
  20. }

10.2 把scala.math.Ordered[Point]混入java.awt.Point的方式,定義OrderedPoint類。按辭典編輯方式排序,也就是說,如果

  1. x<x'或者x=x'y<y'則(x,y)<(x',y')
  1. import scala.math.Ordered
  2. import java.awt.Point
  3. classOrderedPoint(x:Int, y:Int)extendsPoint(x,y)withOrdered[Point]{//Point(x,y)寫全
  4. def compare(that:Point):Int={
  5. if(this.x <= that.x){
  6. if(this.x == that.x){
  7. if(this.y < that.y)-1
  8. elseif(this.y > that.y)1
  9. else0
  10. }else-1
  11. }else-1
  12. }
  13. overridedef toString ="[%d, %d]".format(getX(), getY())
  14. }
  15. val x1 =newOrderedPoint(1,1)
  16. val x2 =newOrderedPoint(1,-1)
  17. val x3 =newOrderedPoint(2,1)
  18. println(x1 < x2)
  19. println(x1 >= x3)

10.4 提供一個CryptoLogger類,將日誌訊息以凱撒密碼加密。預設情況下密匙為3,不過使用者也可以重寫它。提供預設密匙和-3作為密匙是的使用示例

  1. trait Logger{
  2. def log(msg:String)={}
  3. }
  4. trait ConsoleLoggerextendsLogger{
  5. overridedef log(msg:String)=Console.println(msg)
  6. }
  7. trait CaesarLoggerextendsLogger{
  8. val shift:Int=3
  9. overridedef log(msg:String)={
  10. super.log((for(x <- msg)yield(x + shift).toChar).mkString)
  11. // more elegant
  12. super.log(msg.map(_ + shift).map(_.toChar).mkString)
  13. // speedup but less elegant
  14. super.log(msg.map((x :Char)=>(x + shift).toChar).mkString)
  15. }
  16. }
  17. classSampleextendsLogger{
  18. def doSomeWork()={
  19. log("Some Log Message")
  20. }
  21. }
  22. val x =newSamplewithConsoleLogger
  23. x.doSomeWork
  24. val y =newSamplewithConsoleLoggerwithCaesarLogger
  25. y.doSomeWork
  26. val z =new{override val shift =-3}withSamplewithConsoleLoggerwithCaesarLogger
  27. 相關推薦

    scala 特質 讀書筆記習題答案程式碼

    chapter 10 特質 標籤:快學scala 一、筆記 scala和java一樣不允許從多個超類繼承,scala提供特質而非介面。特質可以同時擁有抽象方法和具體方法,而類可以實現多個特質。  不需要將方法宣告為abstract,特質中未

    scala 操作符 讀書筆記習題答案程式碼

    標籤:快學scala 一、筆記 scala種可以在反引號中包含幾乎任何字元序列, val 'val'=42 所有的操作符都是左結合的,除了以冒號(:)結尾的操作符,和賦值操作符。用於構造列表的::操作符是又結合的。1::2::Ni1的意思是1::(2::Ni1),先創建出包含2

    scala 讀書筆記習題答案程式碼

    chapter 5 類 標籤:快學scala 一、筆記 scala類方法預設是公有的, classCounter{private val value =0def increment(){ value +=1}def current()= value}val = my

    scala 讀書筆記習題答案程式碼

    chapter 3 陣列相關操作 標籤:快學scala 一、筆記 scala的Array以java陣列方式實現,陣列在JVM中的型別為java.lang.String[]. scala>import scala.collection.mutable.Array

    scala 包和引入 讀書筆記習題答案程式碼

    chapter 7 包和引入 標籤:快學scala 一、筆記 scala中的包名是相對的,原始檔的目錄與包之間沒有強制的關聯關係,完全可以在同一檔案中為多個包貢獻內容。  包可以包含類、物件和特質,但是不能包含函式和變數的定義,這是java虛擬機器的侷限,但是包物件

    Scala10----特質

    本章要點 類可以實現任意數量的特質 特質可以要求實現它們的類具備特定的欄位、方法或超類 和Java介面不同,Scala特質可以提供方法和欄位的實現 當你將多個特質疊加在一起時,順序很重要—-其方法先被執行的特質排在更後面 為什麼沒有多重繼承 S

    scala 讀書筆記習題答案程式碼

    chapter 4 元組與對映 標籤:快學scala 一、筆記 預設Map為不可變對映,可變對映定義: scala> val scores = scala.collection.mutable.Map("Allic"->1,"Bob"->3,"Ci

    c++ primer(五版)學習筆記習題答案程式碼版(第一

    筆記較為零散,都是自己不熟悉的知識點。 習題答案至於一個.cc中,需要執行某一題直接修改#define NUM**, 如執行第一題為#define NUM11,題1.24定義為NUM124chapter 1 1、std::cout << "Entertwo nu

    scala習題——XML處理

    本章主要講解對XML的處理,要處理xml需要引入scala-xml-x.x.x.x.jar包,建立普通scala 類不會自動新增此jar包,需要手動引入之後就可以使用了 1.(0)得到什麼,(0)(0)又得到什麼,為什麼? 仍然為<fred/>

    Scala 八課 (trait多繼承)

    rtl 思想 logs err fun 含義 tex color saving trait多繼承: trait的繼承並不像類擁有相同的含義!在下面這個例子中,如果還是運用類的繼承的思想,那麽運行結果將是什麽也沒有。 trait Logged { def log(m

    Scala #4答案

    數組 第三章 給定 arr val scala 一個 filter array 4.給定一個整數數組,產生一個新的數組,包含原數組中的所有正值,按原有順序排序 之後的元素是所有的零或者負值,按原有順序排序 scala> val arr = Array(1, 2, 3

    Scala 習題答案

    1.編寫一段程式碼,將a設定為一個n個隨機整數的陣列,要求隨機數介於0(包含)和n(不包含)之間。 val n = 100 //n是自己給定的 val a = scala.util.Random val b = new Array[Int](n) //

    Scala習題答案

    5.1 改進5.1節的Counter類,讓它不要在Int.MaxValue時變成負數。 class Counter{ private var value = Int.MaxValue def increment(){ if(va

    Scala學習筆記

    1、固定長度陣列Array,長度變化陣列ArrayBuffer,在陣列緩衝中尾端新增或移除元素是一個高效的操作。也可以在任意位置插入或移除元素,這樣操作不高效--所有在哪個位置的元素都必須被平移。2、for(...) yield 迴圈建立了一個型別與原始集合的相同的新集合。如

    Scala13----集合

    本章要點 所有集合都擴充套件自Iterable特質 集合有三大類:序列、集、對映 對於幾乎所有集合類,Scala都同時提供了可變的和不可變的版本 Scala列表要麼是空的,要麼擁有一頭一尾,其中尾部本身又是一個列表 集是無先後次序的集合 用Linkedhas

    03 scala習題答案

    \1. 編寫一段程式碼,將a設定為一個n個隨機整數的陣列,要求隨機數介於0和n之間。 1 2 3 4 5 6 7 8 9 10 11 12 objectApp { def main(args:

    Scala 習題答案

    1.設定一個對映,其中包含你想要的一些裝備,以及它們的價格。然後構建另一個對映,採用同一組鍵,但在價格上打9折。 val item = Map(("computer"->4500.0),("keyboard"->291.0)) val item

    scala6習題——物件相關

    1.編寫一個conversion物件,加入inchestoCentimeters,gallonstoliters,milestoKilometers方法 object Conversions{ def inchesToCentimeters()

    Scala習題解答— 特質

    10 特質 10.1 java.awt.Rectangle類有兩個很有用的方法translate和grow,但可惜的是像java.awt.geom.Ellipse2D這樣的類沒有。在Scala中,你可以解決掉這個問題。定義一個RenctangleLike特質,加入具體的tr

    Scala 六課 (類構造函數)

    ora per 如果 輔助 text log ring nbsp string 類 主構造器: class Person (var name: String){ } 主構造參數可以不帶val或者var,如果沒有被其他方法使用,則不保存為字段。 如果被其他方法