1、声明

class关键字声明类

类声明类名类头(指定其类型参数、主构造函数等)以及由花括号包围的类体构成;类头与类体都是可选的; 如果一个类没有类体省略花括号

class Person { /*……*/ }// 没有声明任何(主或次)构造函数,它会有一个生成的不带参数的主构造函数// 构造函数的可见性是 publicclass Empty
2、主构造函数

一个类一个主构造函数并可能有一个或多个次构造函数主构造函数类头中声明,它跟类名与可选的类型参数

class Person constructor(firstName: String) { /*……*/ }

主构造函数没有任何注解或者可见性修饰符,可以省略这个constructor关键字

// 单参数,firstName 属于主构造函数局部变量class Person(firstName: String) { /*……*/ }// 多个参数,firstName firstName 属于类只读属性,age 属于类可读写属性class Person(val firstName: String, val firstName: String, var age: Int)// 具有默认参数,firstName firstName 属于类只读属性,var 属于带默认值的类可读写属性class Person(val firstName: String, val lastName: String, var isEmployed: Boolean = true)

如果构造函数有注解或可见性修饰符,这个constructor关键字是必需的,并且这些修饰符在它前面

class Customer public @Inject constructor(name: String) { /*……*/ }
3、次构造函数

类体内使用 constructor 前缀声明次构造函数

class Person(val pets: MutableList = mutableListOf())class Pet { // 声明次构造函数constructor(owner: Person) {owner.pets.add(this)}}

一个主构造函数,每个次构造函数需要委托主构造函数, 直接委托或者通过别的次构造函数间接委托委托到同一个类的另一个构造函数this关键字即可

class Person(val name: String) {val children: MutableList = mutableListOf()constructor(name: String, parent: Person) : this(name) {parent.children.add(this)}}
4、初始化块

类体内init 关键字花括号 { } ,为变量赋值 , 执行一些检查相关的代码

class Constructors {init {println("Init block")}constructor(i: Int) {println("Constructor $i")}}
5、类成员

类可以包含:

  • 构造函数与初始化块
  • 函数
  • 属性
  • 嵌套类与内部类
  • 对象声明
6、类实例化

创建一个类的实例只需像普通函数一样调用构造函数

val invoice = Invoice()val customer = Customer("Joe Smith")

实例化执行顺序

  • 主构造函数中属性赋值
  • 类中的属性赋值init 初始化块 同一个层级,按出现的顺序执行
  • 次构造函数中的代码执行
class InitOrderDemo(// 主构造函数value: Int, // 临时变量, 为secondProperty属性赋值var mainProperty: String // 在主构造函数中定义类属性mainProperty) {// 类属性var firstProperty = "第一个属性: $value".also(::println)var secondProperty: Int = value// 初始化块1init {println("执行第一个初始化块, mainProperty: $mainProperty")println("执行第一个初始化块, firstProperty: $firstProperty")println("执行第一个初始化块, secondProperty: $secondProperty")// 位于 thirdProperty 属性前,所以无法访问 thirdProperty//println("执行第一个初始化块, thirdProperty: $thirdProperty")}// 次构造函数constructor(_value: Int): this(_value, "次构造函数") {thirdProperty = "构造函数赋值"println("执行次构造函数, mainProperty: $mainProperty")println("执行次构造函数, firstProperty: $firstProperty")println("执行次构造函数, secondProperty: $secondProperty")println("执行次构造函数, thirdProperty: $thirdProperty")}// 类属性var thirdProperty = "第三个属性"// 初始化块2init {println("执行第一个初始化块, mainProperty: $mainProperty")println("执行第二个初始化块, firstProperty: $firstProperty")println("执行第二个初始化块, secondProperty: $secondProperty")// thirdProperty 属性已经存在,可以访问println("执行第二个初始化块, thirdProperty: $thirdProperty")}}
fun main() {InitOrderDemo(123, "测试顺序")/*第一个属性: 123执行第一个初始化块, mainProperty: 测试顺序执行第一个初始化块, firstProperty: 第一个属性: 123执行第一个初始化块, secondProperty: 123执行第一个初始化块, mainProperty: 测试顺序执行第二个初始化块, firstProperty: 第一个属性: 123执行第二个初始化块, secondProperty: 123执行第二个初始化块, thirdProperty: 第三个属性*/InitOrderDemo(456)/*第一个属性: 456执行第一个初始化块, mainProperty: 次构造函数执行第一个初始化块, firstProperty: 第一个属性: 456执行第一个初始化块, secondProperty: 456执行第一个初始化块, mainProperty: 次构造函数执行第二个初始化块, firstProperty: 第一个属性: 456执行第二个初始化块, secondProperty: 456执行第二个初始化块, thirdProperty: 第三个属性执行次构造函数, mainProperty: 次构造函数执行次构造函数, firstProperty: 第一个属性: 456执行次构造函数, secondProperty: 456执行次构造函数, thirdProperty: 构造函数赋值*/}