kotlin类

一、定义

1、kotlin中使用关键字class 声明类,如果一个类没有类体,也可以省略花括号, 默认为public 类型的:

Kotlin 复制代码
// 这段代码定义了一个公开的、不可被继承的Test类
class Test{

}
// 没有类体,可以省略花括号
class Test

底层代码:class Test{} / class Test 底层编译成java代码 如下:

Kotlin 复制代码
// final: 这个关键字说明Test类是一个最终类,意味着它不能被继承。
// 也就是说,不允许有其他类继承自Test类以扩展其功能。
public final class Test {
}

2、类中定义的变量必须初始化

Kotlin 复制代码
class Foo{
    val x:Int = 1
}

二、构造函数

1、主构造函数:

**(1)在kotlin中,一个类有一个主构造函数,并且可以有一个或者多个次构造函数。

注:所有次构造函数必须调用主构造函数。**

Kotlin 复制代码
// 下边定义类的主构造函数,且添加了2个Int类型的参数
class Test constructor(a: Int, b: Int) { 
}
// 也可以省略constructor关键字,如果主构造函数没有任何注解或可见性修饰符:
class Test (a: Int, b: Int) {
}

(2)主构造函数的参数也可以作为类的属性存在,下边ab 同时作为构造函数的参数和类的属性存在

Kotlin 复制代码
// a和 b 都是类的属性
class Test constructor(val a: Int, var b: Int) {
}
// 也可以给参数使用默认值:
class Test constructor(val a: Int = 1, var b: Int = 2) {
}
// 或者在类里边定义属性
class Test01 (a: Int, b: Int) {
    // 在类定义类属性,此时a和b作为参数传进来
    var c: Int = a // 定义类属性c
    var d: Int = b // 定义类属性d
    init {
        println("$c+$d=${c+d}")
    }
}

fun main() {
    Test01(1, 2)
}

作为参数:

在构造函数定义中,ab 接收从外界传入的具体值,允许在创建 Test01 类的实例时初始化这些值。

作为属性
val a: Int 表明 a 是一个只读属性(final变量),一旦在构造函数中初始化后,其值就不能再改变。
var b: Int 表明 b 是一个可变属性(变量),在类的实例创建后,其值仍然可以被修改。

(3)类变量初始化时机

1、参数传递,初始化类中变量。

2、使用定义的默认值,初始化类变量。

3、如果不想第一时间初始化变量,可以使用 lateinit 懒加载:

Kotlin 复制代码
class Test () {
    lateinit var a: String
    lateinit var b: String
}

注意事项:

为什么Int类型不能使用lateinit 懒加载?

原因如下:
对于基本数据类型(如 Int、Double、Boolean 等),它们不能为 null,并且在声明时必须赋予一个初始值。由于基本类型不是引用类型,它们不存在"未初始化"的状态------它们要么有一个具体的值,要么在局部作用域内如果没有初始化就会导致编译错误。因此,lateinit 机制不适用于基本数据类型,因为基本类型总是有默认值(如 Int 的默认值是 0),且不能为 null。

(4)在类里边定义变量,kotlin默认会为每个属性添加getter和setter,当然你也可以显示的定义getter和setter

Kotlin 复制代码
class Test (b:Int) {
    var a: Int = b
        // 为a变量定义getter,打印a变量时,输出2,getter优先级是最高的
        get() {
            return 2
        }
        set(value) {
            field = value
        }
    init {
        println(a) // 2
    }
}

fun main() {
    Test(1)
}

类中属性的引用,跟方法引用一样:

Kotlin 复制代码
// 方法定义
fun main() {
    // 引用Foo类中的x属性
    val r = Foo::x
    // 方式一:调用Foo类中的x属性,获取其值
    val r1 = r.get(Foo("hello"))
    println("r1 -> $r1") // r1 -> hello
    // 方式二:通过实例化的对象foo来引用Foo类中的x属性
    val foo = Foo("world")
    val r2 = foo::x
    println("r2 -> ${r2.get()}") // r2 -> world
}
class Foo(x:String) {
    val x:String = x
}

2、次构造函数:

(1)创建
Kotlin 复制代码
// 记住一点:所有的次构造函数必须要调用主构造函数。
class Test (var name:String) {
    // 次构造函数的创建如下,
    // (1)在类里边添加constructor关键字
    // (2)通过this()来调用主构造函数 Test()
    //     且this()参数必须和主构造函数的参数一致
    constructor(name:String,age:Int): this(name){}
}

三、类实例化

1、在kotlin中实例化类后,会创建一个新的对象,并且返回对象的引用,在构造函数执行完毕后,会返回一个指向新创建对象的引用,这个引用可以被存储在一个变量中,以便后续使用。

Kotlin 复制代码
class Test (var name:String)

fun main() {
    val user:Test =Test("小王")
    // 通过user变量可以访问类中的属性、函数
    println(user.name) // 小王
}

2、类方法定义及调用

Kotlin 复制代码
class Test(name: String) {
    // 定义info方法,参数为String类型
    fun info(name: String) {
        // 就近原则:所以输出 2
        println("名字为:${name}") // 2
    }
}

fun main() {
    val test = Test("1")
    test.info("2")
}

在方法中,如果想调用主构造函数参数,需要使用 **this.**的方式,且主构造函数参数必须是属性。

Kotlin 复制代码
class Test(var name: String) {
    fun info(name: String) {
        // this 就是Test 实例化的对象
        println("名字为:${this.name}") // 1
    }
}

fun main() {
    val test = Test("1")
    test.info("2")
}

四、接口

1、定义

Kotlin 复制代码
// Foo类 实现 FooInterface接口
class Foo(val x: String):FooInterface{
    // 重写接口中foo方法
    override fun foo() {
        TODO("Not yet implemented")
    }
}
// 定义接口
interface FooInterface {
    // 定义接口中的方法
    fun foo()
}

2、实现接口

接口的实现,需要在实现类后边加上**:** ,后边写上接口类名即可

Kotlin 复制代码
// Foo类实现 FooInterface接口
class Foo(val x: String):FooInterface{
}

注意事项:

(1)接口的定义,不需要添加关键字 class。
(2)实现类继承某个接口,后边添加 : 然后填写接口名即可 class T( ): AInterface{ }
(3)重写接口中的方法,在实现类中 需要添加 关键字 override

五、抽象类

1、定义

Kotlin 复制代码
// 定义抽象类
abstract class FooAbstract {
    // 定义抽象类中的方法
    abstract fun foo()
}

2、抽象类中,如果没定义abstract 关键字, 那么该方法默认是不可被重写的;如果需要重写,必须加上关键字 open :

Kotlin 复制代码
// 定义抽象类
abstract class FooAbstract {
    // 定义抽象方法,可以被重写
    abstract fun gar()
    // 不可被重写的方法
    fun foo(){}
    // 可被重写的方法
    open fun bar(){}
}

3、类实现抽象类,重写里边的方法:

Kotlin 复制代码
// Foo类 实现 FooAbstract抽象类
class Foo(val x: String):FooAbstract(){
    // 重写接口中foo方法
    override fun bar() {
        println("Foo:$x")
    }
    override fun gar() {
        println("Foo:$x")
    }
}
// 定义抽象类
abstract class FooAbstract {
    // 定义抽象方法,可以被重写
    abstract fun gar()
    // 不可被重写的方法
    fun foo(){}
    // 可被重写的方法
    open fun bar(){}
}

注意事项:

(1)定义抽象类,前边加上 abstract 关键字。
(2)抽象类中的方法(注意不是抽象方法),默认是不可被重写的,必须显示的加上关键字 open,才可以被重写。
(3)抽象类中的所有方法,有关键字 abstract 和open的方法,在实现类里边,必须全部被重写,否则不会被编译通过。
(4)继承抽象类写法 class T( ): Aabstract( ) { } ,抽象类后边必须添加括号。
(5)重写抽象类中的方法,跟接口实现一样,在实现类中 也需要添加 关键字 override。

六、同时继承接口及抽象类

Kotlin 复制代码
// Foo类 实现 FooAbstract抽象类、FooInterface接口
class Foo(val x: String):FooAbstract(), FooInterface{
    // 重写了抽象类中 foo方法
    override fun foo() {
        TODO("Not yet implemented")
    }
    // 重写了接口中 bar方法
    override fun bar() {
        TODO("Not yet implemented")
    }
}
// 定义抽象类
abstract class FooAbstract {
    abstract fun foo()
}
// 定义接口
interface FooInterface{
    fun bar()
}

六、普通类的继承

1、继承普通类,普通类前边必须添加 open 关键字,才能被别的类继承:

Kotlin 复制代码
// Foo类 实现 FooAbstract抽象类、FooInterface接口
open class Foo(val x: String):FooAbstract(), FooInterface{
    override fun foo() {
        TODO("Not yet implemented")
    }

    override fun bar() {
        TODO("Not yet implemented")
    }
}
// Foo2 继承 Foo 类,Foo类前边必须添加关键字 open
class Foo2(val y: String):Foo(y){
}
// 定义抽象类
abstract class FooAbstract {
    abstract fun foo()
}
// 定义接口
interface FooInterface{
    fun bar()
}
fun main(){
    Foo2("hello")
}

2、被继承类中的方法,如果不想被别的类复写某个方法,可以在方法卡那边加上关键字 final

Kotlin 复制代码
open class Foo(a:String): FooInterface, FooAbstractClass(){
    override fun foo() {
        TODO("Not yet implemented")
    }
    // bar 方法不可被别的类重写
    final override fun bar() {
        TODO("Not yet implemented")
    }
}
class Foo2(val a: String):Foo(a){
    override fun foo() {
    }
    // 编译不会通过,因为Foo类中的bar方法,前边有关键字 final
    override fun bar() {
    }
}
abstract class FooAbstractClass {
    abstract fun foo()
}
interface FooInterface {
    fun bar()
}
相关推荐
猷咪8 分钟前
C++基础
开发语言·c++
IT·小灰灰10 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧11 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q12 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳012 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾12 分钟前
php 对接deepseek
android·开发语言·php
2601_9498683616 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
星火开发设计30 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
qq_1777673742 分钟前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos
一匹电信狗44 分钟前
【LeetCode_21】合并两个有序链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl