目录
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、getlateinit var sex: Stringval sex1 by lazy {if (age > 20) "男" else "女"}//如果不加lateinit关键字,就必须被初始化赋值var race="种族"//被val初始化的属性,是无法被修改的,也就是无法被setval 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 = 0get() = fieldset(value) {field = value}var height: Int = 0set(value) {field = value + 10}val isMan:Booleanget() {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 = 0get() = fieldset(value) {field = value}
但是不能直接使用this.name会造成递归调用内存溢出的, 因为在set和get中是不允许有本身的局部变量的(例如如果你属性名是name, 在set/get里是不能有这个变量的), 因为属性的调用也涉及到了set/get会造成递归调用, 所以要解决引用自身的问题, kotlin发明了field来解决这个问题
//这样会无限的重复调用自己,导致内存溢出var weight: Int = 0get() = fieldset(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;}@Overridepublic 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;}@Overridepublic int hashCode() {int result = name != null ? name.hashCode() : 0;result = 31 * result + age;return result;}@Overridepublic String toString() {return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';}
}
- 和kotlin类的输出对比
fun main() {val person=Person();person.name = "张三"person.age = 18println(person)val person1=Person1("李四",20)println(person1)}