Kotlin手记-(10)类

189 阅读4分钟

Kotlin中使⽤关键字 class 声明类

class Fruit {
    //定义一个水果Fruit类
}

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

class Fruit

构造函数

在 Kotlin 中的⼀个类可以有1个主构造函数以及N(N>=0)个次构造函数。主构造函数是类头的⼀部分:它跟在类名后面,并可携带参数(也可没有)如下

class Fruit constructor(var name:String){
    //定义带有主构造函数的类
}

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

class Fruit(var name:String){
    //定义一个水果Fruit类
}

主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块(initializer blocks)中。

class Fruit (var name:String){
    //定义一个水果Fruit类
    init {
           println("初始化的代码可以放在init代码块中$name")
    }
}

主构造函数的参数可以在初始化块init{}中使用,也可以在类体内声明的属性初始化器中使用:比如我们定义一个name属性,把主函数的参数值赋值给他

class Fruit (var name:String){
    //定义一个水果Fruit类
    init {
        println("初始化的代码可以放在init代码块中$name")
    }
    var mName = name //主构造函数值赋值给属性mName
}

事实上,声明属性以及从主构造函数初始化属性,Kotlin 有简洁的语法:

class Fruit (val name:String,var age:Int){
  
}

与普通属性⼀样,主构造函数中声明的属性可以是可变的(var)或只读的(val)。

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

class Fruit @xxx constructor(val name:String,var age:Int){

}

次构造

类也可以声明前缀有 constructor的次构造函数:

次构造函数在类内部

class Fruit (val name:String,var age:Int){
    //定义一个水果Fruit类
    constructor( name:String, age:Int, address:String) : this(name,age)
}

当类中有主构造函数的时候,我们定义的次构造函数需要委托给主构造函数,可以直接委托,也可以通过别的次构造函数间接委托,委托到同一个类的其他构造函数用this关键字即可:如上代码示例

主构造函数是没有函数体的,初始化块init{}实际上就是主构造函数的一部分,可以被当成主构造函数的函数体的。如果没有主构造函数,这种委托会隐式发生,并且也会执行初始化块的。

class Fruit{
    init {
        println("我是初始化块,虽然我没有主构造函数,在初始化的时候我也会执行的")
    }
    constructor( name:String, age:Int)  {
    }
}
fun main() {
    var  fruit = Fruit("Kotlin",18)
}

控制台输入:
我是初始化块,虽然我没有主构造函数,在初始化的时候我也会执行的

执行上面的代码,通过次构造函数我们创建了Fruit的一个实例,在创建的时候,也执行了init{}代码块

如果一个非抽象类没有任何构造函数,他会有一个不带参数的主 构造函数,构造函数的默认可见性是public,你可以用private声明一个非可见性的主构造函数

class Fruit private constructor(){
    init {
        println("我是初始化块,虽然我没有主构造函数,在初始化的时候我也会执行的")
    }
}

如果主构造函数的所有的参数都有默认值,编译器会⽣成 ⼀个额外的⽆参构造函数,它将使⽤默 认值。这使得 Kotlin 更易于使⽤像 Jackson 或者 JPA 这样的通过⽆参构造函数创建类的实例的库。

class Fruit (val name: String = "xx")

实例创建

要创建⼀个类的实例,我们就像普通函数⼀样调⽤构造函数:不需要使用new关键字 比如我们创建上面的水果类的实例

    var  fruit = Fruit("Kotlin")

类成员

一个完整的类可以包含如下N个成员

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

抽象类

在一个的类的签名使用abstract修饰,这个类就被定义成了抽象类了,抽象成员在抽象类中可以不用实现。需要注意的是,我们并不需要⽤ open 标注⼀个抽象类或者函数⸺因为这不⾔⽽喻。

我们可以用一个抽象成员覆盖一个非抽象的开放成员

比如类A有一个a方法,抽象类B继承了A,在B中也定义了方法a进行覆盖,我们可以把a用abstract修饰

abstract class  B :A{
   abstract override fun  a(){
   
    }
}

在这里插入图片描述