Kotlin学习(四)—— 类与对象(类的声明,属性初始化问题,构造器)

类的声明

类声明由类名、类头(指定其类型参数、主构造函数等)和由⼤括号包围的类体构成。类头和类体都是可选的
定义一个最简单的类

class A

这样就定义了最简单的一个类了,什么都没有的类,没有类头和类体。(没有类体,可以省略花括号)

接下来定义一个正常的类:

class Person public constructor(name: String,age: Int)/*主构造函数,和它参数*/{
    var name:String  //属性
    var age :Int
    init {  //初始化器,主构造函数的函数体,能使用主构造函数的参数
        this.name = name
        this.age = age
    }

    //成员函数
    fun say(){
        println("I am ${name} and I was ${age} years old")
    }
}

但是实际上,上面的类定义太复杂了,因为:
1. 除非构造函数有明确必要私有,一般情况,默认为公有的
2. 属性可以写在主构造函数中,除非有一些属性在创建时不要初始化,不要初始化的属相或者延迟初始化的属性写在可以写在类里
3. init 只是主构造函数的方法体,没有特殊要求也可以省略

接下来简化的类的写法如下:

class Person(var name: String ,var age: Int){

    //成员函数
    fun say(){
        println("I am ${name} and I was ${age} years old")
    }
}

类中属性初始化问题

注意类中的属性不像Java那样声明了就会有默认值,我们可以不初始化它
kotlin中,类的属性必须要初始化或者延迟初始化:
我们先不管延迟初始化,先看看我们初始化的方式有几种

1 . 定义时直接给它赋予初始值

class User{
    //属性定义方式1,直接给它初值
    var name:String = ""
    var age:Int =0
}

2 . 使用init块初始化:init相当于主构造函数的函数体,所以能用主构造函数的参数

class User(name: String){
    //属性初始化方式2,使用init
    var name:String
    var age:Int
    init {
        this.name = name
        this.age = 0
    }
}

3 . 直接调用主构造函数的参数

class Customer(name: String) {
    val customerKey = name.toUpperCase()
}

4 . 直接把属性定义在主构造函数中,这样我们创建对象的时候就直接把属性初始化了

class User(var name: String,var age: Int)

5 . 延迟初始化
延迟初始化可以把属性的初始化推迟到要访问这个属性之前,但是访问之前还没有初始化就会抛出 kotlin.UninitializedPropertyAccessException的异常,不过要注意的是延迟初始化的属性不能是原生类型(Byte,Short,Int,Long,Float,Double,char,Boolean)八种,像String类型就可以延迟初始化

class User(var name: String,var age: Int){
    lateinit var gender :String
}

fun main(args: Array<String>) {
    var user = User("huahua",11) 
    //如果在要访问这个属性之前还不初始化,那么就会抛出kotlin.UninitializedPropertyAccessException异常
    //所以访问之前一定要初始化延迟初始化属性
    println(user.gender)

}

关于属性特别注意的是:和Java不同,不要轻易的用private修饰属性,它会是属性的setter和getter也私有化,要使属性能够访问到,尽量不要加权限修饰符,这一点一定要从Java的封装性中走出来!!!!
另外:要注意属性声明的是var还是val,var是可变属性,具有getter和setter,val是只读属性,只有getter

构造函数

Kotlin 中的⼀个类可以有⼀个主构造函数和⼀个或多个次构造函数。主构造函数是类头的⼀部分:它跟在类名(和可选的类型参数)后
类也可以声明前缀有 constructor的次构造函数

class User(var name: String){
    lateinit var age :String
    constructor(name: String,age: String):this(name){  //直接委托主构造函数
    }
    constructor():this("huahua","11"){  //通过委托另一个构造函数,间接委托主构造函数
    }
}

注意:

  1. 如果主构造函数没有任何注解或者可⻅性修饰符,可以省略这个 constructor 关键字
  2. 主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块(initializer blocks)中
  3. 主构造的参数可以在初始化块中使⽤。它们也可以在类体内声明的属性初始化器中使⽤(上面属性初始化已经说过)
  4. 如果构造函数有注解或可⻅性修饰符,这个 constructor 关键字是必需的,并且这些修饰符在它前⾯
  5. 如果类有⼀个主构造函数,每个次构造函数需要委托给主构造函数,可以直接委托或者通过别的次构造函数间接委托,委托到同⼀个类的另⼀个构造函。数⽤ this 关键字即可(上面的代码已经说明了委托)
  6. 如果⼀个⾮抽象类没有声明任何(主或次)构造函数,它会有⼀个⽣成的不带参数的主构造函数。构造函数的可⻅性是 public。如果你不希望你的类有⼀个公有构造函数,你需要声明⼀个带有⾮默认可⻅性的空的主构造函数
  7. Kotlin在 JVM 上,如果主构造函数的所有的参数都有默认值,编译器会⽣成 ⼀个额外的⽆参构造函数,它将使⽤默认值。这使得 Kotlin 更易于使⽤像 Jackson 或者 JPA 这样的通过⽆参构造函数创建类的实例的库,如下:
  8. 如果没有声明主构造函数 ,就不用声明委托主构造函数了,其实是默认委托给无参构造函数了
  9. 如果没有在类名后面声明主构造函数,如果有一个无参的构造函数,那么会被当作主构造函数。
  10. init块中的代码是在创建对象以定会执行的(这里有像Java的初始化块)
class LL1{
    var name:String
    init {
        println("_主")
        this.name = ""
    }
    constructor(name: String){
        this.name=name

    }
    constructor(){
        println("_次")
    }
    constructor(name: String,age: Int)
}

fun main(args: Array<String>) {
    var l = LL1() //因为有默认的主构造函数,所以能这样创建对象
}
class User {
    lateinit var name:String
    constructor(name: String){
        this.name =name
    }
    init {
        println("lala")//调用每个构造方法之前会调用init中的代码
    }
    constructor(){
        println("主")
    }


}

创建类的对象

kotlin中并没有new关键字,创建对象是直接调用构造方法

fun main(args: Array<String>) {
    var u = User() 
}

类的成员

  1. 构造函数和初始化块
  2. 函数
  3. 属性
  4. 嵌套类和内部类
  5. 对象声明

这里小编只说了构造函数和初始化块,之后会补上其他成员的文章

结语:
此篇文章,是小编自己测试之后才发表的,所以如果有什么遗漏或者错误,还请大家用于在评论区指正。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值