1.擴展如下的bankaccount類,新類checkingacount對每次存款和取款都收取1美元手續費
class BankAccount(initialBalance:Double){
private var balance=initialBalance;
def deposit(amount:Double)={
balance+=amount;balance;
}
def withdraw(amount:Double)={
balance-=amount;balance;
}
}
class CheckingAccount(initialBalance:Double) extends BankAccount(initialBalance){
private var balance=initialBalance;
override def deposit(amount:Double)={
balance+=(amount-1);balance;
}
override def withdraw(amount:Double)={
balance-=(amount+1);balance;
}
def show=balance;
}
``
2.擴展前一個練習的BankAccount類,新類SavingAccount每個月都有利息產生(earnMonthlyInterest方法被調用),並且有每月三次免手續費的存款或取款,在earnMonthlyInterest方法中重置交易計數,
class SavingAccount(initialBalance:Double) extends BankAccount(initialBalance){
private var balance=initialBalance;
private var traceCount=3;
private val lixi=0.003;
import java.util.Date;
val date=new Date();
private var lastMonth=date.getMonth();//初始化是記錄月份
override def deposit(amount:Double)={
if(traceCount>0){
traceCount-=1;
balance+=(amount);
}else{
balance+=(amount-1);
}
balance;
}
override def withdraw(amount:Double)={
if(traceCount>0){
traceCount-=1;
balance-=(amount);
}else{
balance-=(amount+1);
}
balance;
}
def earnMonthlyInterest():Unit={
val nowdate=new Date();
val nowmonth=nowdate.getMonth();
if(nowmonth!=lastMonth){
lastMonth=nowmonth;
traceCount=3;
balance=balance*(1+lixi);
}
}
3.翻開你喜歡的C++或者java教科書,一定會找到用來繼承層級的示例,可能是員工,動物,圖形或類似的東西,用scala來生成這個示例
動物示例
class animal{
def speak:Unit={println(“I am a Animal”)};
}
class Cat extends animal{
override def speak:Unit={
println(“I am a Cat”);
}
}
class Tiger extends Cat{
override def speak:Unit={
println(“I am a Tiger”);
}
}
4.定義一個抽象類Item,加入方法price和description,SimpleItem是一個構造器中給出價格好描述的物件。利用val可以重寫def這個事實。Bundle是一個可以包含其他物件的物件,其價格是打包中所有物件的價格之和,同時提供一個將物件添加到打包中的機制,以及一個合適的description方法
def返回類型與之後的重寫類型必須一致
abstract class item{
def price:Double;
def description:String;
override def toString="Description="+description()+"price="+price();
}
class SimpleItem(Price:Double,Description:String) extends item{
override val price:Double=Price;
override val description:String=Description;
}
class Bundle extends item{
import scala.collection.mutable.ArrayBuffer;
val itemArray=new ArrayBuffer[SimpleItem]();
var totalPrice:Double=0;
override def price:Double={
for(i<- (0 until itemArray.length)){
totalPrice=totalPrice+itemArray(i).price;
}
totalPrice;
}
override val description:String={
itemArray.mkString(",");
}
def addItem(item:SimpleItem){
itemArray+=item;
}
}
5.設計一個Point類,其X座標和Y座標可以通過構造器提供,提供一個子類LabledPoint,其構造器接受一個標籤值和x,y,比如
new LabeledPoint("Black Thursday"),1929,30);
class Point(X:Double,Y:Double){
val x=X;
val y=Y;
}
class LabledPoint(label:String,X:Double,Y:Double) extends Point(X,Y){
private val Label=label;
override def toString=”Label=”+Label+”X=”+X+”Y=”+Y;
}
6.定義一個抽象類Shape,一個抽象方法centerPoint,以及該抽象類的子類Rectangle和Circle,爲子類提供合適的構造器,並重寫centerPoint方法
abstract class Shape{
def centerPoint:(Double,Double);
}
class Cicrle(x:Double,y:Double,Radius:Double) extends Shape{
override def centerPoint={(x,y)};
}
class Rectangle(x:Double,y:Double,len:Double,width:Double) extends Shape{
override def centerPoint={
(x+len/2,y+width/2);
};
}
7.提供一個square類,擴展自java.awt.Rectangle並且有三個構造器,一個以給定的端點和寬度構造正方形,一個以(0,0)爲端點,0爲寬度的構造的正方形,一個以0,0爲端點,給定的寬度來構造正方形
import java.awt.{Point => Po,Rectangle=>Rect}
class Square(point:Po,len:Int) extends Rect(point.x,point.y,len,len){
def this(){
this(new Po(0,0),0);
}
def this(len:Int){
this(new Po(0,0),len);
}
}
8.編譯8.6節的Person和SecretAgent類並使用javap分析類文件。總共有多少name的構造方法?他們分別取什麼值(提示,可以用-c和private選項)
Microsoft Windows [版本 6.1.7601]
版權所有 (c) 2009 Microsoft Corporation。保留所有權利。
C:\Users\pengchen>javap C:\Users\pengchen\workspace\hello\bin\person.class
Compiled from “person.scala”
public class person {
public java.lang.String name();
public java.lang.String toString();
public person(java.lang.String);
}
C:\Users\pengchen>javap C:\Users\pengchen\workspace\hello\bin\SecretAgent.class
Compiled from “person.scala”
public class SecretAgent extends person {
public java.lang.String name();
public java.lang.String toString();
public SecretAgent(java.lang.String);
}
C:\Users\pengchen>javap -c C:\Users\pengchen\workspace\hello\bin\SecretAgent.cla
ss
Compiled from “person.scala”
public class SecretAgent extends person {
public java.lang.String name();
Code:
0: aload_0
1: getfield #14 // Field name:Ljava/lang/String;
4: areturn
public java.lang.String toString();
Code:
0: aload_0
1: getfield #18 // Field toString:Ljava/lang/String;
4: areturn
public SecretAgent(java.lang.String);
Code:
0: aload_0
1: aload_1
2: invokespecial #22 // Method person.””:(Ljava/lan
g/String;)V
5: aload_0
6: ldc #24 // String secret
8: putfield #14 // Field name:Ljava/lang/String;
11: aload_0
12: ldc #24 // String secret
14: putfield #18 // Field toString:Ljava/lang/String;
17: return
}
C:\Users\pengchen>javap -private C:\Users\pengchen\workspace\hello\bin\SecretAge
nt.class
Compiled from “person.scala”
public class SecretAgent extends person {
private final java.lang.String name;
private final java.lang.String toString;
public java.lang.String name();
public java.lang.String toString();
public SecretAgent(java.lang.String);
}
C:\Users\pengchen>
“`
兩個值,一個是傳入的codename,另一個是“secret”
9.在8.10節的creature類中,將val range替換成一個def,如果你在Ant子類中也用def的話會有什麼效果,如果子類中也用val的話又會有什麼效果?爲甚麼
用def的話並無副作用,但子類使用val的話編譯無法通過,因爲val只能重寫val或者不帶參數的def,而此時的def會帶上Int參數
10.文件scala/collection/immutable/Stack.scala包含如下定義
class Stack[A] protected {protected val elems:List[A]}
請解釋protected關鍵詞的含義(提示:回顧我們在第5章關於私有構造器的討論)
此構造方法只能被其子類調用,其他類不能調用