快學scala 第十章 特質 讀書筆記及習題答案程式碼
chapter 10 特質
標籤:快學scala
一、筆記
- scala和java一樣不允許從多個超類繼承,scala提供特質而非介面。特質可以同時擁有抽象方法和具體方法,而類可以實現多個特質。
不需要將方法宣告為abstract,特質中未被實現的方法預設就是抽象的。在重寫特質的抽象方法時不需要給出override關鍵字。特質跟類更為相像。用with新增額外的特質:
classConsoleLoggerextendsLoggerwithCloneablewithSerialiable
由上,Logger ith Cloneable with Serialiable首先是一個整體,然後再由類來擴充套件。
2. 特質的方法並不需要一定是抽象的:
trait ConsoleLogger{
def log(msg:String){ println(msg)}
}
classSavingAccountextendsAccountwithConsoleLogger{
def withdraw(amount:Double){
if(amount > balance) log("Insufficient funds")
else balance -= amount
}
}//scala與java的區別,SavingAccount從ConsoleLogger特質得到了一個具體的log方法,java的介面是不可能做到的。scala中是ConsoleLogger的功能被混入了SavingAccount類
- JVM中,一個類只能擴充套件一個超類,因此來自特質的欄位不能以相同的方式繼承。
- 對於特質的構造順序:首先呼叫超類的構造器。特質構造器在超類構造器之後、類構造器之前執行。特質由左到右被構造。每個特質當中,父特質先被構造。如果多個特質共有一個父特質,而那個父特質已經被構造,則不會被再次構造。所有特質構造完畢,子類被構造。
classSavingsAccountextendsAccountwithFileLoggerwithShortLogger
//構造順序是: Account(超類)Looger(第一個特質的父特質)FileLogger(第一個特質)ShortLogger(第二個特質,它的父特質Logger已被構造),SavingsAccount(類)
- 特質不能有構造器引數,每個特質都有一個無引數的構造器。缺少構造器引數是特質和類之間唯一的技術差別。
val acct =newSavingsAccountwithFileLogger("myapp.log")//錯誤:特質不能使用構造器引數
FileLogger構造器先於子類構造器執行,在輪到子類之前,FileLogger的構造器就會丟擲一個空指標異常。解決方法是 “提前定義”:
val acct =new{
val filename ="myapp.log"
}withSavingsAccountwithFileLogger//提前定義發生在常規的構造序列之前,在FileLogger被構造時,filename已經是初始化過的了
- 特質可以擴充套件另一個特質,特質也可以擴充套件類,這個類會自動成為所有混入該特質的超類。在特質擴充套件類時,編譯器能夠確保的是所有混入該特質的類都認這個類作超類。scala還有另一套機制保證:自身型別
this:型別=>
//當特質以這一定義開始時,它便被混入指定型別的子類
trait LoggedExceptionextendsLogged{
this:Exception=>
def log(){ log(getMessage)}
}//該特質並不擴充套件Exception類,而是有一個自身型別Exception,這意味著,它只能被混入Exception的子類。
如果把特質混入一個不符合自身型別要求的類,就會報錯
-
6.
二、習題答案
10.1 java.awt.Rectangle類有兩個很有用的方法translate和grow,但可惜的是像java.awt.geom.Ellipse2D這樣的類沒有。在Scala中,你可以解決掉這個問題。定義一個RenctangleLike特質,加入具體的translate和grow方法。提供任何你需要用來實現的抽象方法,以便你可以像如下程式碼這樣混入該特質:
val egg =new java.awt.geom.Ellipse2D.Double(5,10,20,30)withRectangleLike
egg.translate(10,-10)
egg.grow(10,20)
import java.awt.geom.Ellipse2D
trait RectangleLike{//使用自身型別使得trait可以操作x,y
this:Ellipse2D.Double=>
def translate(x:Double, y:Double){
this.x = x
this.y = y
}
def grow(x:Double, y:Double){
this.x += x
this.y += y
}
}
objectTestextendsApp{
val egg =newEllipse2D.Double(5,10,20,30)withRectangleLike
println("x = "+ egg.getX +" y = "+ egg.getY)
egg.translate(10,-10)
println("x = "+ egg.getX +" y = "+ egg.getY)
egg.grow(10,20)
println("x = "+ egg.getX +" y = "+ egg.getY)
}
10.2 把scala.math.Ordered[Point]混入java.awt.Point的方式,定義OrderedPoint類。按辭典編輯方式排序,也就是說,如果
x<x'或者x=x'且y<y'則(x,y)<(x',y')
import scala.math.Ordered
import java.awt.Point
classOrderedPoint(x:Int, y:Int)extendsPoint(x,y)withOrdered[Point]{//Point(x,y)寫全
def compare(that:Point):Int={
if(this.x <= that.x){
if(this.x == that.x){
if(this.y < that.y)-1
elseif(this.y > that.y)1
else0
}else-1
}else-1
}
overridedef toString ="[%d, %d]".format(getX(), getY())
}
val x1 =newOrderedPoint(1,1)
val x2 =newOrderedPoint(1,-1)
val x3 =newOrderedPoint(2,1)
println(x1 < x2)
println(x1 >= x3)
10.4 提供一個CryptoLogger類,將日誌訊息以凱撒密碼加密。預設情況下密匙為3,不過使用者也可以重寫它。提供預設密匙和-3作為密匙是的使用示例
trait Logger{
def log(msg:String)={}
}
trait ConsoleLoggerextendsLogger{
overridedef log(msg:String)=Console.println(msg)
}
trait CaesarLoggerextendsLogger{
val shift:Int=3
overridedef log(msg:String)={
super.log((for(x <- msg)yield(x + shift).toChar).mkString)
// more elegant
super.log(msg.map(_ + shift).map(_.toChar).mkString)
// speedup but less elegant
super.log(msg.map((x :Char)=>(x + shift).toChar).mkString)
}
}
classSampleextendsLogger{
def doSomeWork()={
log("Some Log Message")
}
}
val x =newSamplewithConsoleLogger
x.doSomeWork
val y =newSamplewithConsoleLoggerwithCaesarLogger
y.doSomeWork
val z =new{override val shift =-3}withSamplewithConsoleLoggerwithCaesarLogger
相關推薦
快學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虛擬機器的侷限,但是包物件
快學Scala第10章----特質
本章要點 類可以實現任意數量的特質 特質可以要求實現它們的類具備特定的欄位、方法或超類 和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 迴圈建立了一個型別與原始集合的相同的新集合。如
快學Scala第13章----集合
本章要點 所有集合都擴充套件自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
快學scala第6章習題——物件相關
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,如果沒有被其他方法使用,則不保存為字段。 如果被其他方法