1. 程式人生 > >Scala類的構造器與訪問器

Scala類的構造器與訪問器

1.構造器

在Scala中,每個類都有一個主構造器。主構造器與類的定義交織在一起,如下:

class Person (
    private var _name: String, 
    private var _age: Int)

主構造器會執行類定義中的所有語句。如下,println語句是主構造器的一部分,當類被例項化時,println語句會立即執行。

class Person private(
    private var _name: String, 
    private var _age: Int){
 
    println("This class is Person
") }

通過把private修飾符新增在類引數列表的前邊把主構造器隱藏起來。如:

class Person private(
    private var _name: String, 
    private var _age: Int)

這樣客戶程式碼將不能呼叫Person類的主構造器,如果需要設定主構造器中的引數,有兩種方案:一是新增輔助構造器,二是用伴生物件的apply工廠方法。
輔助構造器
在Scala類中,有一個主構造器,但可以有任意個輔助構造器。並且,輔助構造器有兩個特點:

輔助構造器的名稱是this;
每個輔助構造器都必須以一個對先前已定義的其他輔助構造器或主構造器的呼叫開始。


輔助構造器如下定義:

def this(age: Int) = this("xx", age)

伴生物件的apply工廠方法
在存放這個類的同一個原始檔中,定義它的伴生物件。伴生物件與類具有相同的訪問許可權,因此,即使Person類的構造器是私有的,物件Person的apply方法也可以建立新的Person物件。如:

object Person{
  def apply[T](name: String, age: Int) = new Person(name, age)
}

注意:輔助構造器只能訪問主構造裡定義的變數,而不能訪問類裡定義的變數。
2.訪問器
和Java一樣,Scala也有setter和getter訪問器。在Scala裡,物件的每個非私有的var型別成員變數都隱含定義了setter和getter方法。但是setter和getter方法的命名方式並沒有沿襲Java的約定。在Scala中,var變數x的getter方法命名為“y”,setter方法命名為“y_=”(一般情況下,為了程式碼的可讀性,y和x是一樣的)。如:

class Person {
  
  private var _name: String = _
  private[this] var _age: Int = _
  //類裡定義的變數,不能用構造器初始化。
  private var _address: String = _
  
  //getter
  def name: String = _name
  //setter
  def name_= (name: String): Unit = {
    _name = name
  }
  
  //getter
  def age: Int = _age
  //setter
  def age_= (age: Int): Unit = {
    _age = age
  }
}

另外,setter和getter訪問器不僅可以訪問類裡面定義的var變數,而且還可以訪問主構造器裡的var變數,而且getter方法既可以訪問var變數,也可以訪問val變數(因為val變數不可變,所以沒有setter)。如:

class Person private(
    private var _name: String,  
    private var _age: Int){
  
  //類裡定義的變數,不能用構造器初始化。
  private var _address: String = _
  
  def this(age: Int) = this("xx", age) 
  
  //getter
  def name: String = _name
  //setter
  def name_= (name: String): Unit = {
    _name = name
  }
  
  //getter
  def age: Int = _age
  //setter
  def age_= (age: Int): Unit = {
    _age = age
  }
  
  //getter
  def address: String = _address
  //setter
  def address_= (address: String): Unit = {
    _address = address
  }
}

注意:getter和setter方法獲取了原var變數的可見性。如var變數定義為public,則其getter和setter也是public;var變數定義為protected,則其getter和setter也是protected。