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

运行结果:

号存入: 1000余额: 2000.0 剩余免费次数: 2

号存入: 1000余额: 3000.0 剩余免费次数: 1

号存入: 1000余额: 4000.0 剩余免费次数: 0

号存入: 1000余额: 4999.0 剩余免费次数: 0

号取出: 100余额: 4898.0 剩余免费次数: 0

号取出: 100余额: 4944.94 剩余免费次数: 2

号取出: 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覆写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学习(八)练习的更多相关文章

  1. Scala学习八——继承

    一.本章要点 extends,final关键字和Java一样 重写方法时必须使用override 只有主构造器可以调用超类的构造器 可以重写字段 二.扩展类 Scala扩展类和Java一样(使用ext ...

  2. Scala学习(八)---Scala继承

    Scala继承 摘要: 在本篇中,你将了解到Scala的继承与Java和C++最显著的不同.要点包括: 1. extends.final关键字和Java中相同 2. 重写方法时必须用override ...

  3. Scala学习资源

    Scala学习资源: Scala官方网站:http://www.scala-lang.org/ Scala github:https://github.com/scala/scala Twitter ...

  4. 【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

    下了这本<大数据Spark企业级实战版>, 另外还有一本<Spark大数据处理:技术.应用与性能优化(全)> 先看前一篇. 根据书里的前言里面,对于阅读顺序的建议.先看最后的S ...

  5. Python Tutorial 学习(八)--Errors and Exceptions

    Python Tutorial 学习(八)--Errors and Exceptions恢复 Errors and Exceptions 错误与异常 此前,我们还没有开始着眼于错误信息.不过如果你是一 ...

  6. 机器学习(三)--- scala学习笔记

    Scala是一门多范式的编程语言,一种类似Java的编程语言,设计初衷是实现可伸缩的语言.并集成面向对象编程和函数式编程的各种特性. Spark是UC Berkeley AMP lab所开源的类Had ...

  7. SVG 学习<八> SVG的路径——path(2)贝塞尔曲线命令、光滑贝塞尔曲线命令

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  8. 【Scala】Scala学习资料

    Scala学习资料 java 树形 分类器_百度搜索 决策树分类器-Java实现 - CSDN博客 KNN分类器-Java实现 - CSDN博客 学习:java设计模式—分类 - 飞翔荷兰人 - 博客 ...

  9. Scala学习网址

    scala学习网址为:https://twitter.github.io/scala_school/zh_cn https://www.zhihu.com/question/26707124

随机推荐

  1. Foundry feats. MultiverseStudio

    https://www.foundry.com/news-awards/foundry-jcube-announcement 经过这么多年的过程,本周本产品终于发布了PR,这次是由Foundry独家代 ...

  2. XRecyclerView上拉刷新下拉加载

    效果图: 首先要添加依赖: //xrecyclerviewimplementation 'com.jcodecraeer:xrecyclerview:1.3.2'//Gsonimplementatio ...

  3. 更新 Anaconda 库文件

    查看库 Anaconda Navigator中 启动Anaconda Prompt(或Anaconda Navigator中Environment->(base)root->Open te ...

  4. 性能测试 查看Android APP 帧数FPS的方法

    (下述需要先安装eclipse,不然无法抓包) 1.保证手机与PC连接是正常的 2.打开手机“设置”→“开发者选项”(没有开发者选项就点击“关于手机”“版本号”连续点击就会出现开发者选项了).找到监控 ...

  5. c++函数集锦

    1.标准C++库字符串类std::string的用法 begin       得到指向字符串开头的Iterator end       得到指向字符串结尾的Iterator rbegin        ...

  6. git 入门教程之里程碑式标签

    "春风得意马蹄疾,一日看尽长安花",对于项目也是如此,最值得期待的恐怕就要数新版本发布的时刻了吧?每当发布新版本时要么是版本号命名(比如v0.0.1)或者代号命名(比如Chelse ...

  7. IPD咨询如何才能真正落地?

    文/资深顾问 杨学明 IPD作为先进的产品开发理念,思想起源于PRTM公司,PACE,培思的力量,首先在IBM和波音公司迅速完善,中国是深圳华为公司. 1992年IBM公司利润停止增长,财务困难,IB ...

  8. EasyUI动画效果

    1.jQuery动画效果 a)基本效果 >show(speed),显示 >hide(speed),隐藏 >toggle(speed),切换 b)滑动的效果 >slideUp(s ...

  9. java国际化

    import java.util.Locale; import org.junit.Test; /** * 使用指定的国际化文件 */ public class Demo { @Test public ...

  10. Jetbrains Idea连接TFS时配置的坑

    #Team Explorer Everywherehttps://www.microsoft.com/en-us/search/result.aspx?q=team+explorer+everywhe ...