Scala编程指南:面向对象编程(二)

2014-11-24 01:03:37 · 作者: · 浏览: 1
give the appearance of clicking a physical button ... clickedCallbacks.foreach(f => f()) } } 类ButtonWithCallbacks 表示了图形用户界面上的一个按钮。它有一个标签和一个回调函数的列表,这些函数会在按钮被点击的时候被调用。每一个回调函数都不接受参数,并且返回Unit。方法click 会遍历回调函数的列表,然后一个个地调用它们。

ButtonWithCallbacks 定义了3个构造函数。主构造函数,类的主题,有一个参数列表来接受标签字符串和回调函数的列表。因为每一个参数都被声明为val, 编译器为每一个参数都生成一个私有字段(会使用一个不同的内部名称),以及名字和参数一致的公有读取方法。“私有”和“公有”在这里的意思和在大多数面向对象语言里一样。我们会在下面的“可见性规则”章节讨论不同的可见性规则和控制它们的关键字。

如果参数有一个var 关键字,一个公有的写方法会被自动生成,并且名字为参数名加下划线等号(_=)。例如,如果label 被声明为var, 对应的写方法则为label_=,而且它会接受一个字符串作为参数。

有时候你可能不希望自动生成这些访问器方法。换句话说,你希望字段是私有的。在val 或者var 之前加上private 关键字,访问器方法就不会被生成。(参见“可见性规则”章节获取更多细节信息。)

注意

对于Java 程序员,Scala 没有遵循s [JavaBeanSpec] 约定 - 字段读取、写方法分别对应get 和set 的前缀,紧接着是第一个字母大写的字段名。我们会在“当方法和字段存取器无法区分时:唯一存取的原则”章节中讨论唯一存取原则时看到原因。不过,你可以在需要时通过scala.reflect.BeanProperty 来获得JavaBeans 风格的访问器,我们会在《第14章 - Scala 工具,库和IDE 支持》中的“JavaBean 属性”章节来讨论这个问题。

当类的一个实例被创建时,每一个参数对应的字段都会被参数自动初始化。初始化这些字段不需要逻辑上的构造函数,这和很多面向对象语言不同。

ButtonWithCallbacks 类主体(换言之,构造函数)的第一个指令是一个保证被传入构造函数的参数列表是一个非空列表的测试。(不过它确实允许一个空的Nil 列表。)它使用了方便的require 函数,这个函数是被自动导入到当前的作用域中的(正如我们将在《第7章 - Scala 对象系统》的“预定义对象”章节所要讨论的)。如果这个列表是null, require 会抛出一个异常。require 函数和它对应的假设对于设计契约式程序非常有用,我们会在《第13章 - 应用程序设计》的“用契约式设计方式构造更佳的设计”章节中讨论这个问题。

这里是ButtonWithCallbacks 的完整Specification(规格)的一部分,它展示了require 指令的作用。

// code-examples/Traits/ui/button-callbacks-spec.scala package ui import org.specs._ object ButtonWithCallbacksSpec extends Specification { "A ButtonWithCallbacks" should { // ... "not be constructable with a null callback list" in { val nullList:List[() => Unit] = null val errorMessage = "requirement failed: Callback list cant be null!