Kotlin类与对象
类的定义与对象创建
类的创建是比较简单的,主要是看一下注意点:
1.如果主构造函数没有任何注释或可见性修饰符,则可以省略constructor关键字,如果类中没有其他内容要写,可以直接省略花括号,最后就变成下面这样:
class Student(name: String,age: Int)
但是,这里仅仅是定义了构造函数的参数,这还不是类的属性,我们可以为这些属性添加var或val关键字来表示这个属性是可变还是不可变的:
class Student(var name: String,val age: Int)
这样才算是定义了类的属性,我们也可以给这些属性设置初始值:
class Student(var name: String, val age: Int = 18)
除了将属性添加到构造函数中,我们也可以将这些属性值直接作为类的成员变量写到类中,但是这种情况必须要配一个默认值,否则无法通过编译:
class Student{
var name: String = "" //必须配一个默认值
var age: Int = 0
}
这样我们就可以不编写主构造函数也能定义属性,但是这里仍然会隐式生成一个无参的构造函数,为了构造函数能够方便地传值初始化,也可以像这样写:
class Student(name: String,age: Int){
var name: String = name //通过构造函数传递过来
var age: Int = age
}
当然,如果不希望这些属性在一开始就有初始值,而是之后某一个时刻去设定初始值,我们也可以为其添加懒加载:
class Student{
lateinit var name: String //懒加载的属性可以不用在一开始赋值,但是在下一次使用之前一定要先完成赋值,否则报错
var age: Int = 0
}
对象的创建和使用
fun main(){
var stu = Student("aaa",18) //stu存放的是对象的引用,而不是本体,我们可以通过对象的引用来间接操作对象
println(stu.name)
}
class Student(var name: String,val age: Int)
次构造函数的对象使用
fun main(){
var stu = Student("aaa") //这里就会调用次构造函数
println(stu.name)
}
class Student(var name: String,val age: Int){
constructor(name: String): this(name,18)
}
详解如下:
对象的初始化
在对象创建时,我们可能需要做一些初始化工作,我们可以使用初始化代码块来完成,初始化代码块使用init关键字来完成。假如我们希望对象在创建的时候,如果年龄不足18,岁,那么就设定为18岁:
class Student(var name: String, var age: Int){ //由于主构造函数无法编写函数体,因此我们可以在init的花括号中编写初始化代码
//注意这段初始化代码初,是在上面的类属性被赋值之后才执行的,所以说能拿到已经赋值的age属性
init {
println("我是初始化操作")
if(age < 18) age = 18
println("初始化操作结束")
}
}
这样我们再创建对象的时候,就会在创建的时候自动执行初始化代码块里面的代码:
fun main() {
val stu = Student("小米",15)
println(stu.age)
}
/*打印结果:
我是初始化操作
初始化操作结束
18
*/
init代码块也可以定义多个,执行是按照顺序从上往下执行。如果既有主构造函数的初始化代码块,又有次构造函数的函数体,那么执行顺序也是先主后次。
类的成员函数
调用类中的成员方法,同样使用.运算符即可。
fun main() {
val stu = Student("小米",15)
stu.hello()
}
在类的成员函数中,可以直接访问当前类对象中的一些属性,比如这里的用户名和年龄:
class Student(var name: String, var age: Int){
fun hello(){
println("大家好,我叫$name,今年${age}岁了") //这里的name 可以写成this.name,代表的就是类的成员变量
}
}
空值和空类型
所有的变量除了引用一个具体的值之外,还有一种特殊的值可以使用,那就是null,它代表空值,也就是不引用任何对象。
在其他语言中,比如Java中null是一个非常常见的值,因为在某些情况下,引用类型的变量默认值就是null,这就经常会导致程序中出现一些空指针导致的异常,在Kotlin中,对于空值处理是非常严格的,正常情况下,我们的变量是不能直接复制为null的,否则会报错。无法编译通过:
这是因为所有的类型默认都是非空类型,非空类型的变量是不允许被赋值为null的,这个直接在编译阶段就避免了其他语言中经常存在的空指针问题。
那么,如果我们希望某个变量在初始化的情况下使用null而不去引用某一个具体对象,该怎么做呢,此时我们需要将变量的类型修改为可空类型,只需要在类型名称的后面添加一个?即可:
fun main(){
var str: String? = null
}
既然现在是可空类型,那么很多问题就会出现了,比如当一个变量为 null时,此时如果使用类中的一些成员方法或是获取成员属性时,会出现一些问题:
Kotlin为我们提供了一种更安全的空类型操作,更安全地访问可能包含null值的对象属性,需要使用安全调用运算符?.,如果对象的属性为null,则安全调用运算符返回null,像下面这样:
fun main(){
var str: String? = null
println(str?.length)
}
这里的调用结果存在两种情况:
1.如果str为null,那么这里得到的结果就是null,并且不会正常执行后面的操作
2.如果str不为null,那就正常返回这里本应该得到的结果。
因此,使用安全调用运算后,如果遇到null的情况,那么这里不会正常进行原本的操作,而是直接返回null作为结果,这在有些时候非常好用,比如我们希望一个学生类型的变量在为null时就不执行对象的语句:
fun main(){
val stu: Student? = null
stu?.hello()
}
不过在有些时候,可能我们希望如果变量为null,在使用安全调用运算符时,返回一个我们自定义的结果,而不是null,我们可以使用Elvis运算符:
fun main(){
val str: String? = null
//Elvis运算符 ?: 左侧为空值检测目标,右侧为检测到null时返回的结果
val len: Int = str?.length ?: 0
}
这里我们使用了Elvis运算符来判断左侧是否为null,如果左侧为null,那么这里直接得到右侧的自定义值,这个运算符长得巨像Java语言里面的三元运算符。
解构声明
as关键字可以起别名:
原文地址:https://blog.csdn.net/qq_34966875/article/details/143464594
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!