《快学Scala》习题详解 第5章 类

1 改进Counter类,让它不要在大于Int.maxValue时变为负数
增加一个判断语句

  private var value = 0
  def increment() { if (value < Int.MaxValue) value += 1 }
  def current() = value

2 写一个BankAccount类,加入deposit和withdraw方法,和一个只读的balance属性

  //val 只有getter,没有setter,depotit/withdraw报错,访问不到
  val balance: Double = 0
  def deposit(money: Double) { balance += money }
  def withdraw(money: Double) { balance -= money }

3 定义一个Time类,加入只读属性hours和minutes
另外还有一个检测时间是否早于另一个时间的方法,before(other:Time):Boolean
Time对象以new Time(hrs,min)方式构建,其中0

class Time {
  var hours: Int = 0
  var mintues: Int = 0
  def getHours = hours
  def getMinutes = mintues
  def this(hrs: Int, min: Int) {
    this()
    if (hrs <= 23 && hrs >= 0) {
      hours = hrs; mintues = min
    }
  }
  def before(other: Time): Boolean = {
    if (other.getHours == hours) other.getMinutes > mintues
    else other.getHours > hours
  }
}

4 重新实现Timer类,内部呈现改成字午夜起的分钟数(介于1-24*60) ,不改变公有接口,也就是说,客户端不因你的修改而受到影响

  var hours: Int = 0
  var mintues: Int = 0
  var mins = 0
  //  def getHours = hours
  //  def getMinutes = mintues
  def getMins = mins
  def this(hrs: Int, min: Int) {
    this()
    if (hrs <= 23 && hrs >= 0) {
      //      hours = hrs; mintues = min
      mins = hrs * 60 + min
    }
  }
  def before(other: Time): Boolean = {
    getMins > other.getMins
  }
}

5 创建一个Student类,加入可读写的JavaBeans属性name(类型为String)和id(类型为Long)。有哪些方法被生产?(用javap查看。)你可以在Scala中调用JavaBeans的getter和setter方法吗?应该这样做吗?

class Student(@BeanProperty var name: String, @BeanProperty var id: Long) {
}
object se {
  def main(args: Array[String]): Unit = {
    var s1 = new Student("Tom", 200)
    println(s1.getName())
    println(s1.getId())
  }
}

共生成9个方法,主构造器+每个字段两对setter/getter(scala+javabean)
输出:Tom,200,证明可调用
6 在5.2节的Person类中加一个主构造器,将负年龄换为0

class Person(var privateage: Int) {
  //主构造器的范围:类体中除了方法,构造器,字段均为
  if (privateage < 0) privateage = 0
}

7 编写一个Person类,其主构造器接受一个字符串,该字符串包含名字,空格和姓,如new Person(“Fred Smith”)。提供只读属性firstName和lastName。主构造器参数应该是var,val还是普通参数?为什么?
使用普通参数,不属于Person要求的字段

class Person(name: String) {
  val firstName: String = name.split(" ")(0)
  val lastName: String = name.split(" ")(1)
  def getFirst = firstName
  def getLast = lastName
} 

8 创建一个Car类,以只读属性对应制造商,型号名称,型号年份以及一个可读写的属性用于车牌。提供四组构造器。每个构造器fc都要求制造商和型号为必填。型号年份和车牌可选,如果未填,则型号年份为-1,车牌为空串。你会选择哪一个作为你的主构造器?为什么?

//主构造器包括所有字段
//通过val控制属性为只读
//车牌为可读写,因此主构造器中可有可无,不过设在主构造器中代码量要少
class Car(val Producter: String, val types: String, val year: Int, var num: String) {
  def this(Producter: String, types: String) {
    this(Producter, types, -1, "")
  }
  def this(Producter: String, types: String, num: String) {
    this(Producter, types, -1, num)
  }
  def this(Producter: String, types: String, year: Int) {
    this(Producter, types, year, "")
  }
}

9 在Java,C#或C++重做前一个练习。Scala相比之下精简多少?

public class Car2 {
    private String Producter;
    private String types;
    private String num = "";
    private int year = -1;
    public Car2(String producter, String types, String num, int year) {
        super();
        this.Producter = producter;
        this.types = types;
        this.num = num;
        this.year = year;
    }
}

Java中只定义字段与主构造器,代码量就已经接近
如果加上其它三个构造器,getter/setter,代码量会加大3倍左右,scala确实很简便

10 考虑如下的类
class Employ(val name:String,var salary:Double){
def this(){this(“John Q. Public”,0.0)}
}
重写该类,使用显示的字段定义,和一个缺省主构造器。你更倾向于使用哪种形式?为什么?

class Employee {
  //字段显示定义,个人认为就是直接定义在类体
  val name: String = ""
  var salary = 0.0
  def this(name: String, salary: Double) {
    this()
    this.salary = salary
    //    this.name=name //报错
    // 如果想给name赋值,只能将name设置为var,但设置为var,就会变为可读写
    // 因此,设立主构造器时,尽量把只读的放进主构造器中
  }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值