Programming in Scala (Second Edition) 读书笔记18 Stateful Object

1. In previous chapters, we put the spotlight on functional (immutable) objects

在前面的章节,我们把焦点放在了函数式对象上

We did so because the idea of objects without any mutable state deserves to

be better known

函数式对象更容易被理解,它永远只有一种状态

However, it is also perfectly possible to define objects with

mutable state in Scala. Such stateful objects often come up naturally when

you want to model objects in the real world that change over time

也可以定义状态随时间变化的对象来模拟现实中状态随时间变化的事物

package chapter18

class BankAccount {
  private var bal: Int = 0
  
  def balance: Int = bal
  
  def deposit(amount: Int) = {
    require(amount > 0)
    bal += amount
  }
  
  def withdraw(amount: Int): Boolean = {
    if (amount > bal) false
    else {
      bal -= amount
      true
    }
  }

}

状态可变的对象通常和var一起出现,但这也不是绝对的

2. Getter和Setter

You can perform two fundamental operations on a reassignable variable: get

its value or set it to a new value. In libraries such as JavaBeans, these operations are often encapsulated in separate getter and setter methods, which

need to be defined explicitly. In Scala, every var that is a non-private member of some object implicitly defines a getter and a setter method with it.

These getters and setters are named differently from the Java convention,

however. The getter of a var x is just named “x”, while its setter is named

“x_=”.

对象中每一个非私有的var都隐式地定义getter和setter方法

  class Time {
    var hour = 12
    var minute = 0
  }

编译器将上面的Time类翻译为:

  class Time {
    private[this] var h = 12
    private[this] var m = 0
    def hour: Int = h
    def hour_=(x: Int) { h = x }
    def minute: Int = m
    def minute_=(x: Int) { m = x }
  }
  
  val t = new Time
  t.hour = 13  // 自动调用 hour_=  方法
  t.minute = 30  // 自动调用 minute_= 方法
  println(t.hour + ":" + t.minute)

如果需要对传入setter的值做check,可以手动定义getter和setter

  class Time {
    private[this] var h = 12
    private[this] var m = 0
    def hour: Int = h
    def hour_=(x: Int) {
      require(0 <= x && x <= 24)
      h = x
    }
    def minute: Int = m
    def minute_=(x: Int) {
      require(0 <= x && x <= 60)
      m = x 
    }
  }

It is also possible, and sometimes useful, to define a getter and a setter without an associated field

定义不与某个filed关联的getter和setter

  class Thermometer {
    var celsius: Float = _
    def fahrenheit = celsius * 9 / 5 + 32
    def fahrenheit_=(f: Float) = {
      celsius = (f - 32) * 5 / 9
    }
  }

这个例子中 celsius的getter和setter是自动产生的, fahrenheit 只有gegger和setter没有field

3. 离散事件模拟

原书406页,很有意思的例子,留到以后欣赏

时间: 2024-08-01 18:35:05

Programming in Scala (Second Edition) 读书笔记18 Stateful Object的相关文章

Programming in Scala (Second Edition) 读书笔记15 case class and pattern matching

一个算术表达式包含: 数字,变量,二元操作符,一元操作符.用下面几个类来模拟它们 package chapter15 abstract class Expr case class Var(name: String) extends Expr case class Number(num: Double) extends Expr case class UnOp(operator: String, arg: Expr) extends Expr case class BinOp(operator: 

Programming in Scala (Second Edition) 读书笔记21 隐式转化

1. There's a fundamental difference between your own code and libraries of other people: you can change or extend your own code as you wish, but if you want to use someone else's libraries, you usually have to take them as they are. 你可以改变或扩展自己的代码,但是对

Programming in Scala (Second Edition) 读书笔记7 内置控制结构

1. One thing you will notice is that almost all of Scala's control structures result in some value Scala的每种控制语句都是有值的 This is the approach taken by functional languages, in which programs are viewed as computing a value, thus the components of a progr

Programming in Scala (Second Edition) 读书笔记13 packages and import

目前,在一个包中你看到的top level的对象只有:class, trait, object.其实任何对象都可以是top level的.也就是说,没有必要把函数,value, variable等限制在class, trait, object中.它们可以在整个包范围内都是全局性的. 方法很简单,把这些东东放到package object中就行了.pakcage object的名字和包名相同 包含package object的文件放在该packag下,名字就叫package.scala chapt

Programming in Scala (Second Edition) 读书笔记12 Trais

1.什么是Trait ? Traits are a fundamental unit of code reuse in Scala. A trait encapsulatesmethod and field definitions, which can then be reused by mixing them intoclasses. Unlike class inheritance, in which each class must inherit from justone supercla

Programming in Scala (Second Edition) 读书笔记10

你肯定见过在控制台用字符打印图形的程序,这一章就从定义一个图形元素开始.我们的图形元素都是一些字符组成的矩形 abstract class Element {   def contents: Array[String]   def height: Int = contents.length   def width: Int = if (height == 0) 0 else contents(0).length } 上面定义的三个方法都没有参数,连小括号也省去了.这样的方法叫做:无参方法(par

Programming in Scala (Second Edition) 读书笔记6 函数和闭包

When programs get larger, you need some way to divide them into smaller, more manageable pieces. For dividing up control flow, Scala offers an approach familiar to all experienced programmers: divide the code into functions. In fact, Scala offers sev

Programming in Scala (Second Edition) 读书笔记26 Extractors

1. By now you have probably grown accustomed to the concise way data can be decomposed and analyzed using pattern matching. This chapter shows you how to generalize this concept further. Until now, constructor patterns were linked to case classes. Fo

Programming in Scala (Second Edition) 读书笔记3

创建并初始化一个String Array     val strArr1 = new Array[String](3)     strArr1(0) = "How"     strArr1(1) = "are"     strArr1(2) = "you!" 上述代码被transform 为     val strArr1 = new Array[String](3)     strArr1.update(0, "How")