• Scala学习(八)练习


    Scala中继承&练习

    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 }

    }

    程序代码:

    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. }

    运行结果:

    存入 :1000 余额: 1999.0

    取出 :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(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】。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    eclipse fail to create java virtual machine
    sas软件连接Oracle数据库的办法
    JAVA中数据的读取与写入,不同类型数据的转换
    二维数组的在函数中的传递
    【转】值传递与引用传递
    【转】深拷贝与浅拷贝
    (转)JS报表控件highcharts应用
    highstocks.js使用指南
    (转)Highcharts使用指南(出处:http://liuhaorain.cnblogs.com )
    jQuery实现checkbox全选,反选
  • 原文地址:https://www.cnblogs.com/sunddenly/p/4441491.html
Copyright © 2020-2023  润新知