Chapter 5 Class

focus on:

  1. var foo: Scala自动合成 getter 和 setter

  2. val foo: Scala 自动合成 getter

  3. 由你定义 foo and foo_= 方法

  4. 由你定义 foo 方法

5.1 简单类

class Demo {
  def doStart(name: java.lang.String) =
    println("hello Scala " + name)
}

5.2 带 getter 和 setter 属性

class Cat {
  var age = 0
}
class Person1 {
  private var privateAge = 0

  def age = privateAge
  def age_=(newValue: Int): Unit = {
    if (newValue > privateAge) { // can't become young
      privateAge = newValue
    }
  }
}

5.3 只带 getter 属性

class Message {
  val timeStamp = new java.util.Date // Scala 会生成一个 final 字段 和 一个 getter function

}

5.4 对象私有字段

class Counter {

  private var value = 0 // private[this] var value = 0 这是对象私有字段 某个对象.value 不允许

  def increment() { value += 1 } // function default is public

  def current = value  // 取值器

  def isLess(other: Counter) = value < other.value

}

5.5 主/辅 构造器

class Person2 {
  private var name = ""
  private var age = 0

  def this(name: String) { // auxiliary comstructor
    this()
    this.name = name
  }

  def this(name: String, age: Int) { // Another auxiliary constructor
    this(name)
    this.age = age
  }
}

主构造器的几种形式

主构造器 与 类定义 交织在一起, 主构造器不以 this 来命名

class Person(val name: String, val age: Int) {
  println("Just constructed another person")
  def description = name + " is " + age + " years old"
}

/** 多样化的声明 **/
class Person(val name: String, private var age: Int) {
  println("Just constructed another person")
  def description = name + " is " + age + " years old"
}

/** private[this]val 对象私有效果 **/
class Person(name: String, age: Int) {
  println("Just constructed another person")
  def description = name + " is " + age + " years old"
}

/** 主 构造器 私有 **/
class Person private(val id: Int) {
    ...
}

5.6 MainTest

package com.x.mainTest

import com.x.p5class._

/**
  * Date : 2016-04-05
  */
object SampleDemo {
  // Single Object

  def main(args: Array[String]) = {

    /** Demo **/
    val demo = new Demo
    demo doStart "my first program with scala"

    /** chapter 5 **/

    println("chap 5")
    // 5.1  sample class
    val counter1 = new Counter
    val counter2 = new Counter
    counter2.increment()
    println(counter1.current)
    println(counter1.isLess(counter2))

    // 5.2 getter and setter
    val cat = new Cat
    cat.age = 9

    val fred = new Person1
    fred.age = 9
    println(fred.age)
    fred.age = 7
    println(fred.age)

    // 5.3 only getter
    val message = new Message
    println(message.timeStamp)


    // 5.6 auxiliary constructor
    val p1 = new Person2 // primary constructor
    var p2 = new Person2("Fred")
    var p3 = new Person2("Fred", 42)

  }
}

Output

com.intellij.rt.execution.application.AppMain com.x.mainTest.SampleDemo
hello Scala my first program with scala
chap 5
0
true
9
9
Tue Apr 05 11:11:39 CST 2016

Process finished with exit code 0

Chapter 6 Object

focus on:

  1. 用对象作为单例或存放工具方法

  2. 类可以拥有一个同名的伴生对象

  3. 对象可以扩展类或特质

  4. 对象的 apply 方法通常来构造伴生类的新实例

  5. 如果不想显式定义 main 方法, 可以用扩展 App 特质的对象

  6. 你可以通过扩展 Enumeration对象 来实现枚举

 1. 单例对象、伴生对象
 2. 扩展类或特质的对象
 3. apply 方法、应用程序对象
 4. 枚举

6.1 对象

object Accounts {
  private var lastNumber = 0
  def newUniqeNumber() = {
    lastNumber += 1;
    lastNumber
  }

}

/**
  * Scala 中 Object 可作为存放 工具函数 或 常量, 高效地共享 单个不可变实例
  */

6.2 伴生对象

/**
  * Date : 2016-04-05
  */
class Account {
  val id = Account.newUniqueNumber() // Scala getter
  private var balance = 0.0          // Scala getter and setter
  def deposit(amount: Double): Unit = {
    balance += amount
  }
}
object Account { // 伴生对象
  private var lastNumber = 0

  private def newUniqueNumber() = {
    lastNumber += 1
    lastNumber
  }
}

/**
  * Account.newUniqueNumber() 非 newUniqueNumber()
  *
  * 它们必须在同一个源文件中
  */

6.3 扩展类或特质的object

abstract class UndoableAction(val desc: String) {
  def undo(): Unit
  def redo(): Unit
}
/**
  * Date : 2016-04-05
  * Desc : 一个 object 可以扩展类以及一个或多个特质 , 结果是 同时 拥有在对象定义中给出的所有特性
  *
  * DoNothing 对象可以被所有需要这个缺省行为的地方共用
  */
object DoNothingAction extends UndoableAction("Do nothing"){
  override def undo() {}
  override def redo() {}

  def main(args: Array[String]): Unit = {
    val actions = Map("open"-> DoNothingAction, "save"->DoNothingAction)

    println("open and save function is not implement.")
  }
}

6.4 apply 方法

class Acc private (val id: Int, initialBalance: Double) {
  private var balance = initialBalance
}

object Acc {
  private var lastNumber = 0

  private def newUniqueNumber() = {
    lastNumber += 1
    lastNumber
  }

  def apply(initialBalance: Double) =
    new Acc(newUniqueNumber(), initialBalance)
}

6.5 应用程序对象

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello, World, Scala, main")
  }
}
/**
  * Date : 2016-04-05
  *
  * 扩展 App 特性, 相当于一样可以完成 main 的功能, -Dscala.time
  */
object Hello extends App {
  if (args.length > 0) {
    println("Hello, " + args(0))
  }
  else {
    println("Hello, World2")
  }

  println(TrafficLightColor.Red)

  println(TrafficLightColor.Green)

  println(TrafficLightColor.Yellow)

  println(TrafficLightColor.Blue)

  println(TrafficLightColor.values)

  println(TrafficLightColor.withName("Blue"))

  println(TrafficLightColor(10))

}

6.4 枚举

object TrafficLightColor extends Enumeration {

  type TrafficLightColor = Value // 你可以 增加了一个类型别名 TrafficLightColor.TrafficLightColor 等价 TrafficLightColor.Value

  val Blue, Green = Value  // 缺省名称为 字段名

//  val Red = Value
//  val Yellow = Value
//  val Green = Value
  val Red = Value(10)

  val Yellow = Value
}

Chapter 7 包和引入

focus on:

  1. 包可以像 内部类 那样嵌套

  2. 位于文件顶部不带花括号的包声明在整个文件范围内有效

  3. 包对象可以持有函数和变量

  4. 引入语句可以引入 包、类 和 对象

  5. java.lang、scala、Predef 总是被引入

 7.1 包 7.2 作用域规则 7.3 串联式包语句
 7.4 文件顶部标记法 7.5 包对象 7.6 包可见性
 7.7 引入 7.8 声明引入 7.9 重命名和隐藏方法 7.10 隐式引入

Chapter 8 继 承

focus on:

  1. extends、final 关键字和 Java 中相同

  2. 重写方法时必须用 override

  3. 主构造器 可以调用 超类 的 主构造器

  4. 你可以重写字段

8.1 扩展类

class Employee extends Person2 {
  var salary = 0.0

  // 重写方法
  override def toString = super.toString + "[salary=" + salary + "]"
}

8.2 重写方法

scala 中重写一个非抽象方法必须使用 override 修饰符。

class Employee extends Person2 {
  var salary = 0.0

  // 重写方法
  override def toString = super.toString + "[salary=" + salary + "]"
}

8.3 类型检查和转换

object HelloP8 extends App {

  println(new Employee().toString)

  // 类型检查和转换

  val employee = new Employee();

  if (employee.isInstanceOf[Employee]) {
    val s = employee.asInstanceOf[Employee] // s 的类型为 Employee
    println("is Employee, true")
  }
  // 8.4 受保护字段和方法, protected 成员对于 所属的包而言,是不可见的
}

8.4 受保护字段和方法

受保护字段和方法, protected 成员对于 所属的包而言,是不可见的

8.5 超类的构造

/**
  * Date : 2016-04-05
  *
  * 超类的构造
  *
  * 辅构造器 只能 调用 辅/主 构造器, 但不能调用 超构造器, 主构造器 可以 调用 超构造器
  */
class Employee02(name: String, age: Int, val salary: Double) extends Person2(name, age){
  // 重写方法
  override def toString = super.toString + "[salary=" + salary + "]"
}

8.6 重写字段

可以用 另一个 同名的 val 字段 重写一个 val (或不带参数的 def)。

子类有一个私有字段和一个公有的getter方法, 而这个 getter 方法重写了超类的 getter 方法
abstract class Person { // 关于抽象类的内容
  def id: Int  // 每个人都有一个以某种方式计算出来的 ID
}
class Student(override val id: Int) extends person

8.7 匿名子类

Person {def greeting: String}

8.8 抽象类

abstract class Person(val name: String) {
  def id: Int // 没有方法体,这是一个抽象方法
}

子类重写超类的抽象方法, 不需要使用 override 关键字

class Employee(name: String) extends Person(name) {
  def id = name.hashcode // 不需要 override 关键字
}

8.9 抽象字段

除了抽象方法,类还可以具有抽象字段

abstract class Person {
  val id: Int
    // 没有初始化--带有抽象的 getter 方法的抽象字段
  var name: String
    // 抽象字段 -- 带有抽象的 getter, setter 方法的抽象字段
class Employee(val id: Int) extends Person { // 子类有具体的 id 属性
  var name = "" // 和具体的 name 属性
}
val fred = new Person {
  val id = 1729
  var name = "Fred"
}

8.11 Scala 继承层级

AnyRef 相当于 Java 的 Object
AnyVal 和 AnyRef 都扩展自 Any, 而 Any 是整个继承层级的根节点
Any 类定义了 isInstanceOf、asInstanceOf 方法, 以及用于相等性判断和哈希吗的方法
AnyRef 类追加了来自 Object 类的监视方法 wait 和 notify / notify All. 同时提供了一个带函数参数的方法 synchronized. 这个方法等同于 Java 的 synchronized 的块。

图片描述


blair
209 声望31 粉丝

我是 Blair


引用和评论

0 条评论