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 对象