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
程序代碼:設計
-
class BankAccount(initialBalance:Double){
-
private var balance=initialBalance
-
def deposit(amount:Double)={
-
balance+=amount
-
balance
-
}
-
def withdraw(amount:Double)={
-
balance-=amount
-
balance
-
}
-
def currentBalance=balance
-
}
-
//一種實現
-
class checkingAccount (initialBalance:Double) extends BankAccount(initialBalance){
-
override def deposit(amount:Double)={
-
super.deposit(amount-1)
-
}
-
override def withdraw(amount:Double)={
-
super.withdraw(amount+1)
-
}
-
}
-
object checkingAccount{
-
val cha=new checkingAccount(1000)
-
val dbal=1000
-
val wbal=800
-
def main(args: Array[String]): Unit = {
-
cha.deposit(dbal)
-
println("
存入 :
"+dbal+"
餘額
: "+cha.currentBalance)
-
cha.withdraw(wbal)
-
println("
取出 :
"+wbal+"
餘額
: "+cha.currentBalance)
-
}
-
}
運行結果:rest
存入 :1000 餘額: 1999.0code
取出 :800 餘額: 1198.0
2. 擴展前一個練習的BankAccount類,新類SavingsAccount每月都有利息產生( earnMonthlylnterest方法被調用 ),而且有每個月三次免手續費的存款或取款。在eamMonthlylnterest方法中重置交易計數
程序代碼:
-
class SavingsAccount(initialBalance:Double) extends BankAccount(initialBalance){
-
private var freeCount=3
-
private val interestRate=0.03
-
def CurrentCount = freeCount
-
def earnMonthlyInterrest:Double={
-
freeCount=3
-
super.deposit(super.deposit(0)*interestRate)
-
super.deposit(0)*interestRate
-
}
-
override def deposit(amount:Double):Double={
-
if(freeCount>0){
-
freeCount-=1
-
super.deposit(amount)
-
}else{
-
super.deposit(amount-1)
-
}
-
}
-
override def withdraw(amount:Double):Double={
-
if(freeCount>0){
-
freeCount-=1
-
super.withdraw(amount)
-
}else{
-
super.withdraw(amount+1)
-
}
-
}
-
}
-
object SaveTest{
-
val dbal=1000
-
val wbal=100
-
var interest=0.0
-
val sa=new SavingsAccount(1000)
-
def main(args: Array[String]): Unit = {
-
for(i<- 1 to 32){
-
if(i>=1&& i<=4){
-
sa.deposit(1000)
-
println(i+"
號存入:
"+dbal+"
餘額:
"+sa.currentBalance+"
剩餘免費次數
: "+sa.CurrentCount)
-
}else if(i>=29&&i<=31){
-
if(i==30)
-
interest=sa.earnMonthlyInterrest
-
sa.withdraw(100)
-
println(i+"
號取出:
"+wbal+"
餘額:
"+sa.currentBalance+"
剩餘免費次數
: "+sa.CurrentCount)
-
-
}
-
}
-
println("
一個月的利息爲:
"+interest+"
剩餘免費次數
: "+sa.CurrentCount)
-
}
-
}
運行結果:
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來實現這個示例
-
abstract
class Animal{
-
def run
-
}
-
class Cat
extends Animal{
-
override def run=println("
I can run,miao!")
-
}
-
class Dog
extends Animal{
-
override def run=println("
I can run,wang!")
-
}
-
object AnimalTest {
-
def main(args: Array[String]): Unit = {
-
val cat=
new Cat
-
val dog=
new Dog
-
cat.run
-
dog.run
-
}
-
}
運行結果:
I can run,miao!
I can run,wang!
4. 定義一個抽象類ltem,加入方法price和description。Simpleltem是一個在構造器中給出價格和描述的物件。利用val能夠重寫def這個事實。Bundle是一個能夠包含其餘物件的物件。其價格是打包中全部物件的價格之和。同時提供一個將物件添加到打包當中的機制,以及一個合適的description方法
程序代碼:
-
abstract class Item{
-
def price:Double
-
def description:String
-
}
-
class SimpleItem(override val price:Double,override val description:String) extends Item{
-
}
-
-
class Bundle() extends Item{
-
val itemList=scala.collection.mutable.ArrayBuffer[Item]()
-
def addItem(item:Item){
-
itemList+=item
-
}
-
override def price={
-
var p:Double=0
-
itemList.foreach(i=>p=p+i.price)
-
p
-
}
-
override def description={
-
var des=""
-
itemList.foreach(i=>des=des+i.description+"")
-
des
-
}
-
}
-
object ItemTest {
-
val bundle=new Bundle
-
def main(args: Array[String]): Unit = {
-
val priceArr=Array(2.5,100,3.5,40,32.5)
-
val desArr=Array("
鉛筆
","
水杯
","
筆記本
","
火腿腸
","
鼠標
")
-
for(i <- 0 until 5){
-
bundle.addItem(new SimpleItem(priceArr(i),desArr(i)))
-
}
-
println("
購物籃信息以下:
")
-
bundle.itemList.foreach(item=>println("
描述:
"+item.description+"
價格
: "+item.price))
-
println("
所購物品以下:
"+bundle.description)
-
println("
本次購物合計:
"+bundle.price+"
¥
")
-
}
-
}
運行結果:
購物籃信息以下:
描述: 鉛筆價格: 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)
程序代碼:
-
class Point(val x:Double,val y:Double) {
-
override def toString="x= "+x+" y= "+y
-
}
-
class LabelPoint(val label:String,override val x:Double,override val y:Double)extends Point(x,y){
-
override def toString ="label= "+label+"x= "+x+"y= "+y
-
}
-
object PointTest{
-
def main(args: Array[String]): Unit = {
-
val point=new Point(2,3)
-
val lpoint=new LabelPoint("
圓形
",2,3)
-
println(point)
-
println(lpoint)
-
}
-
}
運行結果:
x= 2.0 y= 3.0
label= 圓形 x= 2.0y= 3.0
6. 定義一個抽象類Shape、一個抽象方法centerPoint,以及該抽象類的子類Rectangle和Circle。爲子類提供合適的構造器,並重寫centerPoint方法
程序代碼:
-
abstract class Shape {
-
abstract def centerPoint: Point
-
}
-
-
class Rectangle(p1: Point, p2: Point, p3: Point) extends Shape {
-
override def centerPoint = {
-
//
略
-
}
-
}
-
-
class Circle(p1: Point, p2: Point, p3: Point) extends Shape {
-
override def centerPoint = {
-
//
略
-
}
-
}
運行結果:
7. 提供一個Square類,擴展自java.awt.Rectangle而且有三個構造器:一個以給定的端點和寬度構造正方形,一個以(0,0)爲端點和給定的寬度構造正方形,一個以(0,0)爲端點、0爲寬度構造正方形。
程序代碼:
-
import java.awt.Point
-
import java.awt.Rectangle
-
-
class Squre extends Rectangle{
-
height=0
-
width=0
-
x=0
-
y=0
-
def this(p:Point,w:Int){
-
this()
-
this.height=w
-
this.width=w
-
this.x=p.x
-
this.y=p.y
-
}
-
def this(width:Int){
-
this(new Point(0,0),width)
-
}
-
}
-
object SqureTest {
-
def main(args: Array[String]): Unit = {
-
val rect1=new Squre()
-
val rect2=new Squre(2)
-
val rect3=new Squre(new Point(2,3),5)
-
println(rect1)
-
println(rect2)
-
println(rect3)
-
}
-
}
運行結果:
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覆寫def,env會被初始化成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】。
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。