Scala學習(八)練習

Scala中繼承&練習java

1. 擴展以下的BankAccount類,新類CheckingAccount對每次存款和取款都收取1美圓的手續費 設計模式

class BankAccount ( initialBalance: Double) { ide

private var balance = initialBalance 函數

def deposit (amount: Double) = { balance += amount; balance } this

def withdraw(amount: Double)={ balance -= amount; balance } spa

} scala

程序代碼:設計

  1. class BankAccount(initialBalance:Double){
  2.   private var balance=initialBalance
  3.   def deposit(amount:Double)={
  4.     balance+=amount
  5.     balance
  6.   }
  7.   def withdraw(amount:Double)={
  8.     balance-=amount
  9.     balance
  10.   }
  11.   def currentBalance=balance
  12. }
  13. //一種實現
  14. class checkingAccount (initialBalance:Double) extends BankAccount(initialBalance){
  15.   override def deposit(amount:Double)={
  16.     super.deposit(amount-1)
  17.   }
  18.   override def withdraw(amount:Double)={
  19.     super.withdraw(amount+1)
  20.   }
  21. }
  22. object checkingAccount{
  23.   val cha=new checkingAccount(1000)
  24.   val dbal=1000
  25.   val wbal=800
  26.   def main(args: Array[String]): Unit = {
  27.     cha.deposit(dbal)
  28.     println(" 存入 : "+dbal+" 餘額 : "+cha.currentBalance)
  29.     cha.withdraw(wbal)
  30.     println(" 取出 : "+wbal+" 餘額 : "+cha.currentBalance)
  31.   }
  32. }

運行結果:rest

存入 :1000 餘額: 1999.0code

取出 :800 餘額: 1198.0

2. 擴展前一個練習的BankAccount類,新類SavingsAccount每月都有利息產生( earnMonthlylnterest方法被調用 ),而且有每個月三次免手續費的存款或取款。在eamMonthlylnterest方法中重置交易計數

程序代碼:

  1. class SavingsAccount(initialBalance:Double) extends BankAccount(initialBalance){
  2.   private var freeCount=3
  3.   private val interestRate=0.03
  4.   def CurrentCount = freeCount
  5.   def earnMonthlyInterrest:Double={
  6.     freeCount=3
  7.     super.deposit(super.deposit(0)*interestRate)
  8.     super.deposit(0)*interestRate
  9.   }
  10.   override def deposit(amount:Double):Double={
  11.     if(freeCount>0){
  12.       freeCount-=1
  13.       super.deposit(amount)
  14.     }else{
  15.       super.deposit(amount-1)
  16.     }
  17.   }
  18.   override def withdraw(amount:Double):Double={
  19.     if(freeCount>0){
  20.       freeCount-=1
  21.       super.withdraw(amount)
  22.     }else{
  23.       super.withdraw(amount+1)
  24.     }
  25.   }
  26. }
  27. object SaveTest{
  28.   val dbal=1000
  29.   val wbal=100
  30.   var interest=0.0
  31.   val sa=new SavingsAccount(1000)
  32.   def main(args: Array[String]): Unit = {
  33.     for(i<- 1 to 32){
  34.       if(i>=1&& i<=4){
  35.         sa.deposit(1000)
  36.         println(i+" 號存入: "+dbal+" 餘額: "+sa.currentBalance+" 剩餘免費次數 : "+sa.CurrentCount)
  37.       }else if(i>=29&&i<=31){
  38.         if(i==30)
  39.           interest=sa.earnMonthlyInterrest
  40.         sa.withdraw(100)
  41.         println(i+" 號取出: "+wbal+" 餘額: "+sa.currentBalance+" 剩餘免費次數 : "+sa.CurrentCount)
  42.  
  43.       }
  44.     }
  45.     println(" 一個月的利息爲: "+interest+" 剩餘免費次數 : "+sa.CurrentCount)
  46.   }
  47. }

運行結果:

1號存入: 1000餘額: 2000.0 剩餘免費次數: 2

2號存入: 1000餘額: 3000.0 剩餘免費次數: 1

3號存入: 1000餘額: 4000.0 剩餘免費次數: 0

4號存入: 1000餘額: 4999.0 剩餘免費次數: 0

29號取出: 100餘額: 4898.0 剩餘免費次數: 0

30號取出: 100餘額: 4944.94 剩餘免費次數: 2

31號取出: 100餘額: 4844.94 剩餘免費次數: 1

一個月的利息爲: 151.3482 剩餘免費次數: 1

3. 翻開你喜歡的Java或C++教科書,必定會找到用來說解繼承層級的示例,多是員工、寵物、圖形或相似的東西,用Scala來實現這個示例

  1. abstract class Animal{
  2.   def run
  3. }
  4. class Cat extends Animal{
  5.   override def run=println(" I can run,miao!")
  6. }
  7. class Dog extends Animal{
  8.   override def run=println(" I can run,wang!")
  9. }
  10. object AnimalTest {
  11.   def main(args: Array[String]): Unit = {
  12.     val cat= new Cat
  13.     val dog= new Dog
  14.     cat.run
  15.     dog.run
  16.   }
  17. }

運行結果:

I can run,miao!

I can run,wang!

4. 定義一個抽象類ltem,加入方法price和description。Simpleltem是一個在構造器中給出價格和描述的物件。利用val能夠重寫def這個事實。Bundle是一個能夠包含其餘物件的物件。其價格是打包中全部物件的價格之和。同時提供一個將物件添加到打包當中的機制,以及一個合適的description方法

程序代碼:

  1. abstract class Item{
  2.   def price:Double
  3.   def description:String
  4. }
  5. class SimpleItem(override val price:Double,override val description:String) extends Item{
  6. }
  7.  
  8. class Bundle() extends Item{
  9.   val itemList=scala.collection.mutable.ArrayBuffer[Item]()
  10.   def addItem(item:Item){
  11.     itemList+=item
  12.   }
  13.   override def price={
  14.     var p:Double=0
  15.     itemList.foreach(i=>p=p+i.price)
  16.     p
  17.   }
  18.   override def description={
  19.     var des=""
  20.     itemList.foreach(i=>des=des+i.description+"")
  21.     des
  22.   }
  23. }
  24. object ItemTest {
  25.   val bundle=new Bundle
  26.   def main(args: Array[String]): Unit = {
  27.     val priceArr=Array(2.5,100,3.5,40,32.5)
  28.     val desArr=Array(" 鉛筆 "," 水杯 "," 筆記本 "," 火腿腸 "," 鼠標 ")
  29.     for(i <- 0 until 5){
  30.       bundle.addItem(new SimpleItem(priceArr(i),desArr(i)))
  31.     }
  32.     println(" 購物籃信息以下: ")
  33.     bundle.itemList.foreach(item=>println(" 描述: "+item.description+" 價格 : "+item.price))
  34.     println(" 所購物品以下: "+bundle.description)
  35.     println(" 本次購物合計: "+bundle.price+" ")
  36.   }
  37. }

運行結果:

購物籃信息以下:

描述: 鉛筆價格: 2.5

描述: 水杯價格: 100.0

描述: 筆記本價格: 3.5

描述: 火腿腸價格: 40.0

描述: 鼠標價格: 32.5

所購物品以下: 鉛筆水杯筆記本火腿腸鼠標

本次購物合計: 178.5

5. 設計一個Point類,其x和y座標能夠經過構造器提供。提供一個子類LabeledPoint,其構造器接受一個標籤值和x、y座標,好比:

new LabeledPoint("Black Thursday", 1929, 230.07)

程序代碼:

  1. class Point(val x:Double,val y:Double) {
  2.   override def toString="x= "+x+" y= "+y
  3. }
  4. class LabelPoint(val label:String,override val x:Double,override val y:Double)extends Point(x,y){
  5.   override def toString ="label= "+label+"x= "+x+"y= "+y
  6. }
  7. object PointTest{
  8.   def main(args: Array[String]): Unit = {
  9.     val point=new Point(2,3)
  10.     val lpoint=new LabelPoint(" 圓形 ",2,3)
  11.     println(point)
  12.     println(lpoint)
  13.   }
  14. }

運行結果:

x= 2.0 y= 3.0

label= 圓形 x= 2.0y= 3.0

6. 定義一個抽象類Shape、一個抽象方法centerPoint,以及該抽象類的子類Rectangle和Circle。爲子類提供合適的構造器,並重寫centerPoint方法

程序代碼:

  1. abstract class Shape {
  2.   abstract def centerPoint: Point
  3. }
  4.  
  5. class Rectangle(p1: Point, p2: Point, p3: Point) extends Shape {
  6.   override def centerPoint = {
  7.     //
  8.   }
  9. }
  10.  
  11. class Circle(p1: Point, p2: Point, p3: Point) extends Shape {
  12.   override def centerPoint = {
  13.     //
  14.   }
  15. }

運行結果:

7. 提供一個Square類,擴展自java.awt.Rectangle而且有三個構造器:一個以給定的端點和寬度構造正方形,一個以(0,0)爲端點和給定的寬度構造正方形,一個以(0,0)爲端點、0爲寬度構造正方形。

程序代碼:

  1. import java.awt.Point
  2. import java.awt.Rectangle
  3.  
  4. class Squre extends Rectangle{
  5.   height=0
  6.   width=0
  7.   x=0
  8.   y=0
  9.   def this(p:Point,w:Int){
  10.     this()
  11.     this.height=w
  12.     this.width=w
  13.     this.x=p.x
  14.     this.y=p.y
  15.   }
  16.   def this(width:Int){
  17.     this(new Point(0,0),width)
  18.   }
  19. }
  20. object SqureTest {
  21.   def main(args: Array[String]): Unit = {
  22.     val rect1=new Squre()
  23.     val rect2=new Squre(2)
  24.     val rect3=new Squre(new Point(2,3),5)
  25.     println(rect1)
  26.     println(rect2)
  27.     println(rect3)
  28.   }
  29. }

運行結果:

org.hebut.yu.two.Squre[x=0,y=0,width=0,height=0]

org.hebut.yu.two.Squre[x=0,y=0,width=2,height=2]

org.hebut.yu.two.Squre[x=2,y=3,width=5,height=5]

8. 編譯的Person和SecretAgent類並使用javap分析類文件。總共有多少name的getter方法,它們分別取什麼值

程序代碼:

class Person ( val name: String ) {

override def toString=getClass.getName+"name="+ name+ "]"

}

class SecretAgent (codename: String) extends Person (codename) {

override val name = "secret" // 不想暴露真名…

override val toString = "secret" // …或類名

}

執行命令:

javap -p : 查看編譯的內容

javap -c : 查看想詳細操做指令

javap -v : 查看常量池

運行結果:Person.scala

運行結果:Person.scala

分析:能夠看到兩個類中都有name()方法,可是子類覆寫了父類的。SecretAgent和Person不同的是name設置了默認值,用-v查看,name的secrect其實是在構造函數中設置的

執行命令:javap -v org.hebut.yu.Person

執行命令:javap -v org.hebut.yu.SecretAgent

 9. 在Creature類中,將val range替換成val def。若是你在Ant子類中也用def的話會有什麼效果,若是在子類中使用val又會有什麼效果,爲何

程序代碼:

class Creature {

val range : Int=10

val env: Array[Int] = new Array[Int] ( range)

}

class Ant extends Creature {

override val range=2

}

class Ant extends {

override val range=2

} with Creature

描述:★★★★★★

def覆寫def子類的env能夠正確初始化而用val覆寫defenv會被初始化成0長度。這個跟val覆寫val的道理是同樣的。父類和子類同時存在私有的同名變量range和相同的range的getter,可是父類構造函數先被調用,卻在其中調用子類的getter。由於父類 的getter以被子類覆寫。子類的range由於此時還沒初始化,因此返回了0。父類構造函數,錯誤地使用0來初始化了env。這種行爲自己就是個坑,可是也提供了很是大的靈活性。面向對象的Template設計模式就依賴這種行爲實現的,因此仍是多多善用爲妙。

10. 文件scala/collection/immutable/Stack.scala包含l以下定義:

class Stack[A] protected ( protected val elems: List[Al )

請解釋protected關鍵字的含義

前一個protected是指主構造器的權限, 即默認狀況下,是不能已傳入elems的方式建立Stack對象的,elems的protected指的是這個參數只有子類才能訪問

若是,您認爲閱讀這篇博客讓您有些收穫,不妨點擊一下右下角的【推薦】。
若是,您但願更容易地發現個人新博客,不妨點擊一下左下角的【關注我】。
若是,您對個人博客所講述的內容有興趣,請繼續關注個人後續博客,我是【Sunddenly】。

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。

相關文章
相關標籤/搜索