1. 幾點(diǎn)說明
先來個例子
class Person {
var age = 0 // 必須初始化
private var privateName = "zmz" // private修改,getter和setter都為private
val sex = "M" // val修飾淑倾,只有g(shù)etter,沒有setter
def name = privateName
def name_=(newName: String): Unit={ // 自定義setter
name = newName;
}
def increment(): Unit ={ // 方法默認(rèn)為public
age += 1
}
def current = age
def current2() = age
}
使用javap
命令進(jìn)行反編譯撑帖,查看上述Person
類的字節(jié)碼:
public class class_chapter.Person {
private int age;
private java.lang.String privateName;
private final java.lang.String sex;
public int age();
public void age_$eq(int);
private java.lang.String privateName();
private void privateName_$eq(java.lang.String);
public java.lang.String sex();
public java.lang.String name();
public void name_$eq(java.lang.String);
public void increment();
public int current();
public int current2();
public class_chapter.Person();
}
定義類時的幾點(diǎn)說明:
- 字段必須初始化筐眷,默認(rèn)為私有的
- 對于字段xxx,scala默認(rèn)添加
getter
和setter
方法垒手,名稱分別為:xxx()
和xxx_$eq(SomeType)
蒜焊,這時字段稱為屬性,默認(rèn)為public; 如果字段定義時加上private科贬,則getter
和setter
方法為private -
val
類型的字段只有getter
- 在代碼中定義setter時泳梆,方法名為:
xxx_=(SomeType)
- 對于無參方法,如果定義時帶上了圓括號()榜掌,則調(diào)用時可帶可不帶优妙;但是,如果定義時沒有帶圓括號()憎账,則調(diào)用時也不能帶
- 對于無參方法,建議:如果方法改變字段的取值套硼,帶上(),否則不帶
2. 私有字段
在scala中胞皱,方法可以訪問該類的所有對象的私有字段邪意,例如下面的sayHello
方法,
class Person {
var age = 0 // 必須初始化
private var privateName = "zmz"
val sex = "M"
def name = privateName
def name_=(newName: String): Unit={
name = newName;
}
def increment(): Unit ={ // 方法默認(rèn)為public
age += 1
}
def current = age
def current2() = age
def sayHello(other: Person): String = {
"Hello " + other.privateName
}
}
雖然privateName
是private的朴恳,但是仍然可以訪問other的privateName
抄罕。
那有沒有限定只能在本對象中訪問的方法呢?當(dāng)然有于颖。
private[this] var privateName = "zmz"
如果想上面這種定義方法呆贿,則不能跨對象訪問私有變量。
3. 構(gòu)造器
3.1 輔助構(gòu)造器
關(guān)于輔助構(gòu)造有兩點(diǎn)說明:
- 輔助構(gòu)造器的名稱為
this
- 輔助構(gòu)造器必須首先調(diào)用主構(gòu)造器或者另一個已經(jīng)定義的輔助構(gòu)造器
class Person {
var age = 0 // 必須初始化
private var privateName = "zmz"
val sex = "M"
def this(age: Int){
this() // 主構(gòu)造器
this.age = age
this.privateName = "zmz"
}
def this(name: String){
this(20) // 調(diào)用上一個輔助構(gòu)造器
this.privateName = name
}
}
object Main extends App{
val p1 = new Person //主構(gòu)造器
val p2 = new Person(3) // 第一個輔助構(gòu)造器
val p3 = new Person("zmz") // 第二個輔助構(gòu)造器
}
3.2 主構(gòu)造器
class Person (var name: String, private val age: Int){
println("Person is defining...") // 屬于主構(gòu)造器
def this(name: String){
this(name, 20)
}
}
object Main extends App{
val p1 = new Person("zmz", 28) // 主構(gòu)造函數(shù)
}
執(zhí)行上述代碼的輸出為:
Person is defining...
使用javap
對Person
類進(jìn)行反編譯:
public class class_chapter.Person {
private java.lang.String name;
private final int age;
public java.lang.String name();
public void name_$eq(java.lang.String);
private int age();
public class_chapter.Person(java.lang.String, int);
public class_chapter.Person(java.lang.String);
}
主構(gòu)造器的定義與類定義交織在一起森渐,關(guān)于主構(gòu)造器做入,有幾點(diǎn)說明:
- 主構(gòu)造器的參數(shù)直接放在類名后
- 主構(gòu)造器會執(zhí)行類中定義的所有語句,例如例子中的
println
方法 - 在主構(gòu)造器的參數(shù)中同衣,
val
竟块、var
、private
的作用方式與在類中定義的字段時相同
另外耐齐,我們也可以將主構(gòu)造器聲明為private
浪秘,這時蒋情,必須使用輔助構(gòu)造器來定義對象了,例如:
class Person private(val id: Int){...}