快学scala 第五章 读书笔记及习题答案代码

chapter 5 类

标签:快学scala


一、笔记

  1. scala类方法默认是公有的,
 
 
  1. class Counter{
  2. private val value = 0
  3. def increment() { value += 1}
  4. def current() = value
  5. }
  6. val = myCounter = new Counter //或new Counter()
  7. myCounter.current //ok
  8. println(myCounter.current)

对于改值器方法使用(),对于取值器则去掉()。 
2. java中getter和setter方法比公有字段更好。scala生成面向JVM的类。实现属性时有四个选择: 
a. var foo:Scala自动合成一个getter和一个setter. 
b. var foo:Scala自动合成一个getter 
c. 由你来定义foo和foo_=方法 
d. 由你来定义foo方法 
所以scala中不能只写属性(只带有settter没有gettter的属性)。 
3. 辅助构造器的名称为this,每个辅助构造器都必须以一个对先前已定义的其他辅助构造器或主构造器调用开始。

 
 
  1. class Person{
  2. private var name = ""
  3. private vat age = 0
  4. def this(name: String){ //辅助构造器
  5. this() //调用主构造器
  6. this.name = name
  7. }
  8. def this(name: String, age: Int){ //另一个辅助...
  9. this(name) //调用前一个辅助构造器
  10. this.age = age
  11. }
  12. }

class Persion(val name: String, val age: Int){ 
... 

主构造器被编译成字段,其值被初始化为构造时传入的参数。

 
 
  1. class Persion(val name: String, val age: Int){
  2. println("Just constructed another person")
  3. def description = name + " is " + age + " years old"
  4. }

二、习题答案

5.1 改进5.1节的Counter类,让它不要在Int.MaxValue时变成负数

 
 
  1. class Count{
  2. private var value = 0
  3. def increment(){if(value < Int.MaxValue) value + 1 else value }
  4. def current = value
  5. }

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

 
 
  1. class BankCount(val balance: Int = 0){
  2. def deposit(){}
  3. def withdraw(){}
  4. }

5.3 编写一个Time类,加入只读属性hours和minutes,和一个检查某一时刻是否早于另一时刻的方法before(other:Time):Boolean。Time对象应该以new Time(hrs,min)方式构建。其中hrs以军用时间格式呈现(介于0和23之间)

 
 
  1. class Time(private[this] val hrs: Int, private[this] val min: Int){
  2. val hours = hrs
  3. val minutes = min
  4. def before(other: Time):Boolean= {
  5. if(hours < other.hours)
  6. true
  7. if(hours == other.hours)
  8. if(minutes< other.minutes)
  9. true
  10. false
  11. }
  12. override def toString():String={
  13. hours + " : " + minutes
  14. }
  15. }

5.4 重新实现前一个类中的Time类,将内部呈现改成午夜起的分钟数(介于0到24*60-1之间)。不要改变公有接口。也就是说,客户端代码不应因你的修改而受影响

 
 
  1. class Time(private[this] val hrs: Int, private[this] val min: Int){
  2. val minutesInDay = hrs * 24+min
  3. def before(other: Time):Boolean= {
  4. if(minutesInDay < other.minutesInDay)
  5. true
  6. false
  7. }
  8. override def toString():String={
  9. (minutesInDay/60) + " : " + (minutesInDay&60)
  10. }
  11. }

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

 
 
  1. import scala.beans.BeanProperty
  2. class Student{
  3. @BeanProperty var name: String = _
  4. @BeanProperty var id: String = _
  5. }
  6. #scalac student.scala
  7. #javap -c Student
  8. Compiled from "student.scala"
  9. public class Student {
  10. public java.lang.String name();
  11. Code:
  12. 0: aload_0
  13. 1: getfield #14 // Field name:Ljava/lang/String;
  14. 4: areturn
  15. public void name_$eq(java.lang.String);
  16. Code:
  17. 0: aload_0
  18. 1: aload_1
  19. 2: putfield #14 // Field name:Ljava/lang/String;
  20. 5: return
  21. public void setName(java.lang.String);
  22. Code:
  23. 0: aload_0
  24. 1: aload_1
  25. 2: putfield #14 // Field name:Ljava/lang/String;
  26. 5: return
  27. public java.lang.String id();
  28. Code:
  29. 0: aload_0
  30. 1: getfield #22 // Field id:Ljava/lang/String;
  31. 4: areturn
  32. public void id_$eq(java.lang.String);
  33. Code:
  34. 0: aload_0
  35. 1: aload_1
  36. 2: putfield #22 // Field id:Ljava/lang/String;
  37. 5: return
  38. public void setId(java.lang.String);
  39. Code:
  40. 0: aload_0
  41. 1: aload_1
  42. 2: putfield #22 // Field id:Ljava/lang/String;
  43. 5: return
  44. public java.lang.String getName();
  45. Code:
  46. 0: aload_0
  47. 1: invokevirtual #27 // Method name:()Ljava/lang/String;
  48. 4: areturn
  49. public java.lang.String getId();
  50. Code:
  51. 0: aload_0
  52. 1: invokevirtual #30 // Method id:()Ljava/lang/String;
  53. 4: areturn
  54. public Student();
  55. Code:
  56. 0: aload_0
  57. 1: invokespecial #34 // Method java/lang/Object."<init>":()V
  58. 4: return
  59. }

5.6 在5.2节的Person类中提供一个主构造器,将负年龄转换为0

 
 
  1. class Person(val age: Int){
  2. age = if(age < 0) 0 else age
  3. }

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

 
 
  1. class Person{private[this] val name: String}{
  2. private[this] val tmp = name.split("\\s+")
  3. val firstName = tmp(0)
  4. val lastName = tmp(1)
  5. }
  6. //因为firstName和lastName为只读,所以用val

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

 
 
  1. class Car(val manufactuer: String, val model: String, val year: Int = -1, val license: String = ""){
  2. }

5.10 考虑如下的类 
class Employ(val name:String,var salary:Double){ 
def this(){this(“John Q. Public”,0.0)} 

重写该类,使用显示的字段定义,和一个缺省主构造器。你更倾向于使用哪种形式?为什么?

 
 
  1. class Employ(){
  2. val name: String = "John Q. Public"
  3. val salary: Double = 0.0
  4. }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值