scala習題(十)——特質
重點章節,與java有著比較大的分歧,在java與scala中都僅能繼承一個基類,這麼做是為了避免菱形繼承,所以兩者都限制的很死,只能單繼承,但這樣就對類的特質化產生了障礙,而為了避免這些問題,java提供了interface,scala則提供了trait也就是特質,介面類和trait的區別在於,一個僅能提供抽象的方法,且不能包含具體實現方法和欄位,而在trait中則沒有這個限制,trait與scala中類的區別只有一點,就是沒有帶引數的建構函式
一、java.awt.Rectangle類有兩個很好用的方法translate和grow,但可惜的是像java.awt.geom.Eclipse2D這樣的類中沒有。在scala中,你可以解決掉這個問題。定義一個RectangleLike特質,加入具體的translate和grow方法,提供任何你需要用來實現的方法,即便你可以像如下的程式碼這樣混入特質
val egg=new java.awt.geom.Eclipse2D.Double(5,10,20,30) with RectangleLike
egg.translate(10,-10)
egg.groww(10,20)
trait RectangleLike {
//自身型別代表只能混入eclipse2d類
this:java.awt.geom.Ellipse2D.Double=>
def translate(x:Int,y:Int):Unit={
this.x=x;
this.y=y;
}
def grow(x:Int,y:Int){
this .x=x;
this.y=y;
}
}
2.通過把scala.math.Ordered[Point]混入java.awt.Point的方式,定義OrdererPoint類,按辭典編輯方式排序,也就是說,如果x
import java.awt.Point;
class OrderPoint extends Point with scala.math.Ordered[Point]{
def compare(that :Point):Int={
if(this.x
3.檢視bitset類,將它的所有超類和特質繪製成一張圖,忽略型別引數([….)中的所有內容,然後給出改特質的線性化規格內容
trait BitSet extends SortedSet[Int] with BitSetLike[BitSet]
繼承自SortedSet類和BitSetLike特質,具體內容可以去scaladoc中看
4.提供一個CryptoLogger類,將日誌資訊以凱撒密碼加密,預設情況下金鑰為3,不過使用者也可以重寫它,提供預設金鑰為3和-3作為金鑰時的使用示例
凱撒密碼就是原有字元基礎上+上偏移量來達成,容錯方面,下面不做深入
trait logger{
def printlog(content:String,key:Int = 3):String
}
class CryptoLogger extends logger{
def printlog(content:String,key:Int = 3):String={
val s=for(i<- content) yield {
(i+key).toChar;
}
s;
}
}
5.
在scala中雖然特質的混入沒有任何限制,但需要注意,如果特質繼承自類,則只能混入繼承該類的類裡面,否則會像下面的列子裡一樣報錯
scala> class Foo
defined class Foo
scala> trait FooTrait extends Foo
defined trait FooTrait
scala> val good = new Foo with FooTrait
good: Foo with FooTrait = $anon$1@773d3f62
scala> class Bar
defined class Bar
scala> val bad = new Bar with FooTrait
<console>:10: error: illegal inheritance; superclass Bar
is not a subclass of the superclass Foo
of the mixin trait FooTrait
val bad = new Bar with FooTrait
//題解只能是這樣
//自己實現propertyChangeSupport的特質,然後混入java.Point,直接繼承必然會報錯
trait propertyChange //自己實現
val p=new Point() with propertyChange;//混入特質
6.因為java中只可以單繼承,所以jcontainer不能夠直接繼承Container和jcomponent,scala中可以通過特質來實現
7.寫一個展現特質的類
class animal{
val animalname:String="animal";
}
trait predation{
val animalname:String;
def predation(s:String){
println(animalname+" is prey on "+s);
}
}
trait feed{
val animalname:String;
def feed(){
println(animalname+" is feed by people");
}
}
class cat extends {override val animalname="cat"} with animal with feed with predation{
}
8.在javaio類庫中,你可以通過BufferInputStream修飾器來給輸入流增加緩衝機制,用特質來重寫緩衝,簡單起見,重寫read方法
檢視java.io的原始碼,如果沒有可以使用jui來反編譯一下,之後將原始碼複製過來注意好特質的特點,不能有含有引數的構造器即可,之後補上
9.使用本章的日誌生成器特質,給前一個練習中的方案增加日誌功能,要求體現出緩衝的效果
檢視java.io的原始碼,如果沒有可以使用jui來反編譯一下,之後將原始碼複製過來注意好特質的特點,不能有含有引數的構造器即可,之後補上
10.實現一個iterableInputStream類,擴充套件java.io.inputStream並混入iterable[byte]特質
class IterableInputStream extends InputStream with Iterable[Byte]{
override def read():Int={
return 1;
}
override def iterator: Iterator[Byte]=null;
}