scala習題八——繼承

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,以及該抽象類的子類RectangleCircle,爲子類提供合適的構造器,並重寫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的構造方法?他們分別取什麼值(提示,可以用-cprivate選項)

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章關於私有構造器的討論)
此構造方法只能被其子類調用,其他類不能調用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章