快學Scala習題解答—第五章 類

[size=large][b]6 類[/b][/size]
[b]
6.1 改進5.1節的Counter類,讓它不要在Int.MaxValue時變成負數[/b]
加個判斷就OK了
class Count{
private var value = Int.MaxValue
def increment(){if(value < Int.MaxValue) value + 1 else value }
def current = value
}


[b]6.2 編寫一個BankAccount類,加入deposit和withdraw方法,和一個只讀的balance屬性[/b]
class BankAccount(val balance:Int = 0){
def deposit(){}
def withdraw(){}
}


[b]6.3 編寫一個Time類,加入只讀屬性hours和minutes,和一個檢查某一時刻是否早於另一時刻的方法before(other:Time):Boolean。Time對象應該以new Time(hrs,min)方式構建。其中hrs以軍用時間格式呈現(介於0和23之間)[/b]
class Time(val hours:Int,val minutes:Int){

def before(other:Time):Boolean={
hours < other.hours || (hours == other.hours && minutes < other.minutes)
}

override def toString():String={
hours + " : " + minutes
}
}


[b]6.4 重新實現前一個類中的Time類,將內部呈現改成午夜起的分鐘數(介於0到24*60-1之間)。不要改變公有接口。也就是說,客戶端代碼不應因你的修改而受影響[/b]
class Time(val hours:Int,val minutes:Int){

def before(other:Time):Boolean={
hours < other.hours || (hours == other.hours && minutes < other.minutes)
}

override def toString():String={
hours * 60 + minutes
}
}

[b]
6.5 創建一個Student類,加入可讀寫的JavaBeans屬性name(類型爲String)和id(類型爲Long)。有哪些方法被生產?(用javap查看。)你可以在Scala中調用JavaBeans的getter和setter方法嗎?應該這樣做嗎?[/b]
生成了name(),name_=(),id(),id_=(),setName(),getName(),setId(),getId() 編寫代碼如下
import scala.reflect.BeanProperty

class Student{

@BeanProperty var name:String = _
@BeanProperty var id:Long = _
}


javap -c Student 後顯示如下

Compiled from "Student.scala"
public class Student extends java.lang.Object implements scala.ScalaObject{
public java.lang.String name();
Code:
0: aload_0
1: getfield #13; //Field name:Ljava/lang/String;
4: areturn

public void name_$eq(java.lang.String);
Code:
0: aload_0
1: aload_1
2: putfield #13; //Field name:Ljava/lang/String;
5: return

public void setName(java.lang.String);
Code:
0: aload_0
1: aload_1
2: putfield #13; //Field name:Ljava/lang/String;
5: return

public long id();
Code:
0: aload_0
1: getfield #19; //Field id:J
4: lreturn

public void id_$eq(long);
Code:
0: aload_0
1: lload_1
2: putfield #19; //Field id:J
5: return

public void setId(long);
Code:
0: aload_0
1: lload_1
2: putfield #19; //Field id:J
5: return

public long getId();
Code:
0: aload_0
1: invokevirtual #25; //Method id:()J
4: lreturn

public java.lang.String getName();
Code:
0: aload_0
1: invokevirtual #28; //Method name:()Ljava/lang/String;
4: areturn

public Student();
Code:
0: aload_0
1: invokespecial #34; //Method java/lang/Object."<init>":()V
4: return

}


[b]6.6 在5.2節的Person類中提供一個主構造器,將負年齡轉換爲0[/b]
class Person(var age:Int){
age = if(age < 0) 0 else age
}

[b]
6.7 編寫一個Person類,其主構造器接受一個字符串,該字符串包含名字,空格和姓,如new Person("Fred Smith")。提供只讀屬性firstName和lastName。主構造器參數應該是var,val還是普通參數?爲什麼?[/b]
必須爲val。如果爲var,則對應的此字符串有get和set方法,而Person中的firstName和lastName爲只讀的,所以不能重複賦值。如果爲var則會重複賦值而報錯

[b]6.8 創建一個Car類,以只讀屬性對應製造商,型號名稱,型號年份以及一個可讀寫的屬性用於車牌。提供四組構造器。每個構造器fc都要求製造商和型號爲必填。型號年份和車牌可選,如果未填,則型號年份爲-1,車牌爲空串。你會選擇哪一個作爲你的主構造器?爲什麼?[/b]
這個沒太明白題意。。。
class Car(val maker:String,val typeName:String,val year:Int = -1,var carLice:String = ""){
}


[b]
6.9 在Java,C#或C++重做前一個練習。Scala相比之下精簡多少?[/b]
這個就不寫了。

[b]6.10 考慮如下的類

class Employ(val name:String,var salary:Double){
def this(){this("John Q. Public",0.0)}
}

重寫該類,使用顯示的字段定義,和一個缺省主構造器。你更傾向於使用哪種形式?爲什麼?[/b]
class Employ{
val name:String = "John Q. Public"
var salary:Double = 0.0
}


個人更喜歡第二種方式,簡單明瞭。
[b]
Blog URL:[/b][url]http://www.ivanpig.com/blog/?p=467[/url]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章