目錄
1、定義
2、kotlin資料類的優勢
3、kotlin資料類的限制
4、資料類的屬性
5、by lazy
6、field關鍵字
7、傳統JavaBean
1、定義
對應于Java中的資料類(JavaBean),kotlin的資料類是需要被data關鍵字所修飾的
- 普通的資料類(進階版在第四小節)
data class Person1(var name: String, var age: Int)
2、kotlin資料類的優勢
kotlin幫我們自動添加和重寫了JavaBean中以下方法,讓我們代碼更加的簡潔
setter()
getter()
hashCode()
equals()
toString()
copy()
componentN()
3、kotlin資料類的限制
- 被data關鍵字修飾的kotlin資料類預設是public final的,是以無法被繼承,也不能用open關鍵字(變成可繼承)修飾
- 必須聲明主構造函數
- 主構造函數必須要至少有一個參數
- 主構造函數中的所有參數必須被标記為val或者var
- 資料類不能有以下修飾符:abstract,inner,open,sealed
4、資料類的屬性
上面我們說過kotlin的資料類必須聲明主構造函數,并且至少得有一個參數,那麼我們不需要寫在構造函數參數裡的屬性應該怎麼寫呢?
注意:沒有寫在主構造函數的屬性,必須被lateinit關鍵字修飾或者初始化指派
注意:沒初始化指派的屬性,也可以通過by lazy文法來延遲指派
data class Person1(var name: String, var age: Int) {
//用lateinit關鍵字修飾的屬性,可以沒有初始值,可以後期set、get
lateinit var sex: String
val sex1 by lazy {
if (age > 20) "男" else "女"
}
//如果不加lateinit關鍵字,就必須被初始化指派
var race="種族"
//被val初始化的屬性,是無法被修改的,也就是無法被set
val race1="漢族"
/**
* 1、上面的屬性,name、age、sex、race都是對set、get方法進行了省略,讓編譯器來自動添加set、get方法的
* 2、當然我們也可以重寫set、get方法。來對set的值進行一定的封裝處理
* 3、field相當于Java中的this.weight的含義,注意我們set方法中絕不不能調用自己this.weight
* 否者就會出現無限的重複調用自己的死循環
*/
var weight: Int = 0
get() = field
set(value) {
field = value
}
var height: Int = 0
set(value) {
field = value + 10
}
val isMan:Boolean
get() {
return this.sex=="男"
}
}
5、by lazy
被by lazy 修飾的變量有以下特點:
- 必須用val修飾,不能使用var修飾
- 在被首次調用的時候才會被指派,一旦被指派,後續就不能修改。
val sex1 by lazy {
if (age > 20) "男" else "女"
}
fun main() {
val person=Person1("張三",18)
println("person.sex1=${person.sex1}")
person.age=21 //------------------------隻在第一次被調用的時候指派,後續指派也不會改變sex1的值
println("person.sex2=${person.sex1}")
val person1=Person1("張三",22)
println("person.sex3=${person1.sex1}")
//person.sex1="s" ------------------------------報錯,無法二次指派
}
//輸出結果
person.sex1=女
person.sex2=女
person.sex3=男
6、field關鍵字
field類似于java裡的this.屬性名
var weight: Int = 0
get() = field
set(value) {
field = value
}
但是不能直接使用this.name會造成遞歸調用記憶體溢出的, 因為在set和get中是不允許有本身的局部變量的(例如如果你屬性名是name, 在set/get裡是不能有這個變量的), 因為屬性的調用也涉及到了set/get會造成遞歸調用, 是以要解決引用自身的問題, kotlin發明了field來解決這個問題
//這樣會無限的重複調用自己,導緻記憶體溢出
var weight: Int = 0
get() = field
set(value) {
this.weight=value
}
7、傳統JavaBean
- 首先看一下我們傳統的Java資料類(JavaBean)
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Person))
return false;
Person person = (Person) o;
if (age != person.age)
return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
- 和kotlin類的輸出對比
fun main() {
val person=Person();
person.name = "張三"
person.age = 18
println(person)
val person1=Person1("李四",20)
println(person1)
}