快学Scala(Second Edition)第5章(类)习题详解

1. 第1题

编写类:

class Counter {
    private var value = Int.MaxValue - 5
    def increment() {
      if (value < Int.MaxValue)
        value += 1
      else println("Reaching the maximum of Int!")
    }
    def current = value
}

测试代码:

var count = new Counter
for (i <- 0 until 10) {
    count.increment()
    println(s"Current value is ${count.current}")
}

2. 第二题

编写类:

class BankAccount {
    private var balance: Double = 0 //私有字段,只有一个getter方法
    def deposit(balance: Double): Unit = {
      this.balance += balance
    }
    def withDraw(balance: Double): Unit = {
      if (balance <= this.balance) {
        this.balance -= balance
      } else {
        println(f"Current balance = ${this.balance}, The withdraw amount is beyond balance!")
      }
    }
    def currentBalance = balance
}

测试代码:

var account = new BankAccount
  print(account.currentBalance)
  account.deposit(1000)
  account.deposit(20000)
  print(account.currentBalance)
  account.withDraw(40000)
  account.withDraw(15000)
  print(account.currentBalance)

3. 第三题

编写类:

class Time(val hrs: Int, val min: Int) { //使用主构造器,字段声明为val,只带getter属性,表示只读

    // 主构造器会执行类定义中的所有语句,用此特性检验输入参数的合法性
    if (hrs < 0 || hrs > 23) throw new Exception("The hrs para is beyond the limit from 0 to 23!")
    if (min < 0 || min > 59) throw new Exception("The min para is beyond the limit from 0 to 59!")

    def before(other: Time) : Boolean = {
      hrs < other.hrs || (hrs == other.hrs && min < other.min)
    }
}

测试代码:

val time1 = new Time(8, 56)
time1.hrs
time1.min
time1.hrs = 12 //尝试调用getter属性,报错,因为是只读的
var time2 = new Time(12, 38)
time1.before(time2)
var time3 = new Time(12, 20)
time2.before(time3)
var time4 = new Time(24, 10)
var time5 = new Time(23, 60)

4. 第四题

编写代码:

class Time1(hrs: Int, min: Int) { //使用主构造器,两个字段未带val/var,表示对象私有,无getter和setter

    // 主构造器会执行类定义中的所有语句,用此特性检验输入参数的合法性
    if (hrs < 0 || hrs > 23) throw new Exception("The hrs para is beyond the limit from 0 to 23!")
    if (min < 0 || min > 59) throw new Exception("The min para is beyond the limit from 0 to 59!")

    val mins = hrs * 60 + min

    def getHrs = mins / 60
    def getMin = mins % 60
    def before(other: Time1) : Boolean = {
      mins < other.mins
    }
}

测试代码:

val time11 = new Time1(8, 56)
time11.getHrs
time11.getMin
var time12 = new Time1(12, 38)
time11.before(time12)
var time13 = new Time1(12, 20)
time12.before(time13)
var time14 = new Time1(24, 10)
var time15 = new Time1(23, 60)

5. 第五题

编写类文件 Students.scala:

import scala.beans.BeanProperty

class Students {
  @BeanProperty var name: String = _
  @BeanProperty var id: Long = _
}

打开命令行终端,cd到Students.scala所在目录,然后执行:

scalac Students.scala
javap -private Students

生成了9个方法,java风格setter和getter共4个,scala风格的getter和setter共4个,再加一个主构造器。如下图所示。


image.png

测试代码:

var stu = new Students
stu.name = "John"
stu.id = 1000000001
stu.setName("Alice")
stu.getName

6. 第六题

代码:

class Person(var age: Int) {
    if (age < 0) age = 0
}

7. 第七题

代码(因为对象不需要访问该参数,所以使用普通参数,使其对象私有):

class Person2(name: String) {
    def firstName = name.split(" ")(1)
    def lastName = name.split(" ")(0)
}

测试代码:class

var per = new Person2("John Xu")
per.firstName
per.lastName

8. 第八题

8.1 法1

代码:

class Car(val manufacture: String, val typeName: String) { //主构造器,通过val设置两个字段(制造商、型号名称)只读

    //设置另外两个字段(型号年份、车牌号)的默认值
    private var typeYear = -1 //通过 private 和 getter 设置只读
    var number = ""

    def this(manufacture: String, typeName: String, typeYear: Int) {
      this(manufacture, typeName)
      this.typeYear = typeYear
    }

    def this(manufacture: String, typeName: String, number: String) {
      this(manufacture, typeName)
      this.number = number
    }

    def this(manufacture: String, typeName: String, typeYear: Int, number: String) {
      this(manufacture, typeName, typeYear)
      this.number = number
    }

    def getTypeYear = typeYear

    def description = manufacture + " | " + typeName + " | " + typeYear + " | " + number
}

测试代码:

var car1 = new Car("BYD", "Qin")
print("car1: " + car1.description)
var car2 = new Car("BYD", "Qin", 2018)
print("car2: " + car2.description)
car2.typeName //只读
car2.number //读
car2.number = "K3W86J" //写
car2.manufacture //只读
car2.getTypeYear //只读
var car3 = new Car("BYD", "Qin", "Q2W80")
print("car3: " + car3.description)
var car4 = new Car("BYD", "Qin", 2017, "B88K0")
print("car4: " + car4.description)

8.2 法2 (更scala风格、代码更精简)

代码:

class Car2(val manufacture: String, val typeName: String, val typeYear: Int, var number: String) {

    def this(manufacture: String, typeName: String, typeYear: Int) {
      this(manufacture, typeName, typeYear, "")
    }

    def this(manufacture: String, typeName: String, number: String) {
      this(manufacture, typeName, -1, number)
    }

    def this(manufacture: String, typeName: String) {
      this(manufacture, typeName, -1, "")
    }

    def description = manufacture + " | " + typeName + " | " + typeYear + " | " + number
}

测试代码:

var car21 = new Car2("BYD", "Qin")
print("car21: " + car21.description)
var car22 = new Car2("BYD", "Qin", 2018)
print("car22: " + car2.description)
car22.typeName //只读
car22.number //读
car22.number = "K3W86J" //写
car22.manufacture //只读
car22.typeYear //只读
var car23 = new Car2("BYD", "Qin", "Q2W80")
print("car23: " + car23.description)
var car24 = new Car2("BYD", "Qin", 2017, "B88K0")
print("car24: " + car24.description)

10. 第十题

10.1 自定义主构造器

题中代码:

class Employee(val name: String, var salary: Double) { // 自定义主构造器,name只读,salary可读写
    def this() { this("John Q. Public", 0.0)}
}

测试代码:

var em = new Employee()
em.name
em.salary
em.salary = 20000

10.2 字段显示定义,使用默认主构造器:

代码:

class Employee2 {

    //字段显示定义
    private var name: String = "John Q. Public"
    var salary = 0.0

    def this(name: String, salary: Double) {
      this() //默认主构造器
      this.name = name
      this.salary = salary
    }

    //显示定义只读字段时,除了声明字段为private var,还需要自定义getter
    def getName = this.name
}

测试代码:

var em2 = new Employee2()
em2.getName
em2.salary
em2.salary = 30000

10.3 总结

更倾向于第一种,将只读字段放进自定义主构造器中,让代码更精简

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容