5.class 类
5.1 class 以及没有参数的方法
a: 一个scala 源文件 有可以有多个class,每个class 的访问属性都是public
b:类的使用: val name=new className
c:方法调用 name.methodName()
方法调用风格中要不要加(),
取决与如果只是访问这个对象并不改变这个对象中字段的值:则可以将()去掉
如果访问的方法将会改变对象中字段的值,则将()加上
例如:
Java代码
- val myCounter = new Counter // Or new Counter()
- myCounter.increment()
- println(myCounter.current)
d:如果在方法定义中没有加(),则方法调用 也不能加()
5.2 getter以及setter 属性
a:在类中 不加private 修饰符的 变量var ,访问属性为public .
例如: var age =0
b:scala 编译器 为var 变量提供get 和set 方法 ,只是方法的表现形式稍微不同,表现如下:
例如:
Java代码
- class Person {
- var age = 0
- }
- 应的getter 方法为 age() ,对应的setter 方法为: age_=
通过对scala编译成的class 文件,用javap命令查看 为如下结果:
Java代码
- public class Person extends java.lang.Object implements scala.ScalaObject{
- private int age;
- public int age();
- public void age_$eq(int);
- public Person();
- }
- 其中$eq 为=的转义符
c: get以及set 方法使用如下:
Java代码
- val fred = new Person
- fred.age = 30
- fred.age = 21
- println(fred.age) // 30
d:如果是private var ,则scala 生成的getter 以及setter 方法是private
e:如果一个字段是val,则scala 只生成 getter 方法
f:如果要禁止scala编译器生成get以及 set,则将该变量定义成Private[this]
总结对象访问:
1:对于var foo ,scala 自动生成get以及set
2.对于val foo,scala 只是生成get
3.可以自己定义 foo foo_=
4.也可以定义一个foo
5.privat[this] foo,则不会生成get 以及set,
那么这个字段只能通过 类中自己定义的方法进行访问,而不能通过类对象直接访问
6:为字段加@BeanProperty,则在类中生成4个方法:
例如:
Java代码
- import scala.reflect.BeanProperty
- class Person {
- @BeanProperty var name: String = _
- }
- generates four public methods:
- 1. name: String
- 2. name_=(newValue: String): Unit
- 3. getName(): String
- 4. setName(newValue: String): Unit
- class Person(@BeanProperty var name: String)
5.3 构造函数
a:主要构造函数
a:主要构造函数的参数不是通过this加以定义,是直接跟在类名后面classname
b:调用主要构造函数,则会执行类定义中的所有语句,
这个属性对于构造函数阶段初始化数据特别有用
c:主要构造函数的参数具有如下几个定义形式:
- name: String : 如果在一个以上的方法中使用到,则变成object-private 的字段,否则据不会变成类中的字段,
- private val/varname:String 变成 private 字段以及private的getter/setter方法
- val/var name: String :变成private field以及public getter/setter
- @BeanProperty val/varname: String 变成 private field, public Scala and JavaBeans getters/setters
b:辅助构造函数
b.1 通过this加以def
b.2 每个辅助构造函数 都是以调用上一个辅助构造函数或者主要构造函数开始
例如:
Java代码
- class Person {
- private var name = ""
- private var age = 0
- def this(name: String) { // An auxiliary constructor
- this() // Calls primary constructor
- this.name = name
- }
- def this(name: String, age: Int) { // Another auxiliary constructor
- this(name) // Calls previous auxiliary constructor
- this.age = age
- }
- }
c:构造函数使用:
Java代码
- val p1 = new Person // Primary constructor
- val p2 = new Person("Fred") // First auxiliary constructor
- val p3 = new Person("Fred", 42) // Second auxiliary constructor
5.4 嵌套类
a:例如:
class Network {
class Member(val name: String) {
val contacts = new ArrayBuffer[Member]
}
private val members = new ArrayBuffer[Member]
def join(name: String) = {
val m = new Member(name)
members += m
m
}
}
内部类的生成方法: new chatter.Member
b: 静态内部类
Java代码
- object Network {
- class Member(val name: String) {
- val contacts = new ArrayBuffer[Member]
- }
- }
- class Network {
- private val members = new ArrayBuffer[Network.Member]
- ...
- }
或者
Java代码
- class Network {
- class Member(val name: String) {
- val contacts = new ArrayBuffer[Network#Member]
- }
- ...
- }
c:外部类引用别名使用
例如:
Java代码
- class Network(val name: String) { outer =>
- class Member(val name: String) {
- ...
- def description = name + " inside " + outer.name
- }
- }
- outer => 生成一个变量值将外部类this,例如:Network.this.
6.Object
6.1 singleton 单例对象
a:sacla 中没有静态方法和静态常量。 如果需要为静态方法和静态常量提供工具类,则可以将静态方法和静态常量封装载object 中
b: 在sacla中的function 可以定义在object 中
c:单例对象的构造函数 只有在第一次调用方法时触发。此后不再触发。 如果该单例对象中的每个方法都没有被调用过,则该单例对象的构造函数不会被触发
6.2 companion object
a:为了表示一个类中既有静态方法也有非静态方法,则可以使用companion object.
b: companion object 必须和class 文件在同一个源文件中
c:companion object 对象的调用也是需要限定符号,例如:
Java代码
- class Account {
- val id = Account.newUniqueNumber()
- private var balance = 0.0
- def deposit(amount: Double) { balance += amount }
- ...
- }
- object Account { // The companion object
- private var lastNumber = 0
- private def newUniqueNumber() = { lastNumber += 1; lastNumber }
- }
- 必须使用 Account.newUniqueNumber() 调用companion object 对象
6.3 object 继承class 或者traits
a:指定一个类的对象不仅继承了指定的class 和traits,而且还具有定义在object 中的所有特性
b:例如:
Java代码
- abstract class UndoableAction(val description: String) {
- def undo(): Unit
- def redo(): Unit
- }
- object DoNothingAction extends UndoableAction("Do nothing") {
- override def undo() {}
- override def redo() {}
- }
- val actions = Map("open" -> DoNothingAction, "save" -> DoNothingAction, ...)
6.4 apply 方法
a:object 具有apply方法,该方法的调用形式为: Object(arg1, ..., argN)
b:通常apply方法调用返回一个companion class 的object
c:例如:Array("Mary", "had", "a", "little", "lamb")
返回一个Array object
Array(100) :this.apply(100) 得到结果为Array[Int]
new Array(100): this(100) 得到结果为 100个类型为Nothing 的Null Element
Java代码
- class Account private (val id: Int, initialBalance: Double) {
- private var balance = initialBalance
- ...
- }
- object Account { // The companion object
- def apply(initialBalance: Double) =
- new Account(newUniqueNumber(), initialBalance)
- ...
- }
6.5 Application Objects
a: 继承App 类实现main方法
Java代码
- object Hello extends App {
- println("Hello, World!")
- }
Java代码
- object Hello extends App {
- if (args.length > 0)
- println("Hello, " + args(0))
- else
- println("Hello, World!")
- }
6.6 Enumerations 枚举类型
a:scala 没有枚举类型,但是sacla 类库提供了 Enumerations Helper 类 用与产生Enum 枚举 类型
b:定义一个Object 继承 Enumerations
c:通过调用Value 方法初始化每个值
例如:
Java代码
- object TrafficLightColor extends Enumeration {
- val Red, Yellow, Green = Value
- }
- 上述方法相当与
- val Red = Value
- val Yellow = Value
- val Green = Value
- 每个调用Value 返回一个内部类的新实例
- val Red = Value(0, "Stop")
- val Yellow = Value(10) // Name "Yellow"
- val Green = Value("Go") // ID 11
- Value 方法可以指定ID 和名字,如果不传ID ,则根据上次使用的ID +1
d:枚举类型使用
TrafficLightColor.Red,TrafficLightColor.Yellow
为Value 定义别名
Java代码
- object TrafficLightColor extends Enumeration {
- type TrafficLightColor = Value
- val Red, Yellow, Green = Value
- }
通过import 使用枚举类型
Java代码
- import TrafficLightColor._
- def doWhat(color: TrafficLightColor) = {
- if (color == Red) "stop"
- else if (color == Yellow) "hurry up"
- else "go"
- }
e:输出枚举类型中的所有值
例如: for (c <- TrafficLightColor.values) println(c.id + ": " + c)
f:根据ID 或者 Name 输出枚举对象
例如:
Java代码
- TrafficLightColor(0) // Calls Enumeration.apply
- TrafficLightColor.withName("Red")
- 都输出了 TrafficLightColor.Red 对象