目录
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)
}