标签:
1. 扩展如下的BankAccount类,新类CheckingAccount对每次存款和取款都收取1美元的手续费 
class BankAccount ( initialBalance: Double) { 
private var balance = initialBalance 
def deposit (amount: Double) = { balance += amount; balance } 
def withdraw(amount: Double)={ balance -= amount; balance } 
} 
程序代码:
- 
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) 
 
- 
  } 
 
- 
} 
 
运行结果:
存入 :1000 余额: 1999.0
取出 :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】。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
Scala学习(八)练习
标签:
原文地址:http://www.cnblogs.com/sunddenly/p/4441491.html