Kotlin官方文档学习1----类与继承

与Java类似,在Kotlin中,类通过class关键字创建

1 主构造函数 和 次构造函数

1.1 主构造函数

在Kotlin类中,可以有一个主构造函数以及1个或者多个次构造函数;
主构造函数在声明类的时候定义,就是类名后的 + 花括号{ }内的主体

class Person constructor (var name:String){        
}

这个Person类名后边的一部分就是主构造函数,在没有访问修饰符(public private…)或者注解修饰的情况下,可以把constructor去掉

class Person public constructor (var name:String){
}

通过public修饰后,constructor就必须加上

主构造函数中不能存在任何代码,所有初始化的操作可以放在init中执行,主构造函数中可以有多个init,按照声明的顺序执行。

class Person public constructor (var name:String){
		//属性初始化器
        val printName = "当前输入的$name".also { s-> println(s) }

        init {

            println("第一个init代码块")
        }

        init {

            println("第二个init代码块")
        }
        
        open fun draw(){
            println("draw 方法")
        }
    }

创建对象

 var person = Person("hello")
 println(person.name)
 
 打印输出:
 当前输入的hello
 第一个init代码块
 第二个init代码块    

1.2 次构造函数

次构造函数,通常使用constructor关键字创建,如果当前类存在主构造函数,那么次构造函数需要委托给主构造函数,通过this关键字即可

  class Student{

        constructor(name: String){
            
            println("次级构造函数")
        }
    }

因为Student没有主构造函数,因此不需要委托给主构造函数

class Student(var name: String){
	
	

   constructor(name: String,age:Int) : this(name) {

         println("次级构造函数")
     }
 }

如果存在主构造函数,那么就需要通过this关键字委托主构造函数,类似于重载

class Student(var name: String){
        
    val initPrimary = "主构造函数$name".also { s-> print(s) }
    
    init {
        println("主构造函数初始化")
    }

    constructor(name: String,age:Int) : this(name) {

        println("次级构造函数")
    }
}

调用

var student = Student("kobe", 41)

在通过次级构造函数创建对象时,首先会执行主构造函数的属性初始化器和init代码块,执行完成之后,才会执行次构造函数的内部代码

2 类的继承

2.1 继承

在Kotlin中,所有的类都有一个共同的超类,类似于Java中的Object

默认情况下,类是不能被继承的;如果该类能够被继承,那么需要使用open关键字修饰

class Student(name: String) : Person(name){

   constructor(name: String,age :Int) : this(name){

        print("Student的次级构造函数")
    }
}

如果派生类有一个主构造函数,那么基类必须使用派生类的参数就地初始化,在初始化时,首先初始化主构造函数的init代码块,然后再执行子类的主构造函数 + 次构造函数;要避免在基类的构造函数或者init块中使用open关键字

 class Student : Person {

    constructor(name: String) : super(name){

        print("派生类次级构造函数")
    }

	override fun draw() {
        super.draw()
    }
}

如果派生类没有主构造函数,需要通过super关键字在次构造函数中初始化基类

2.2 重写方法

Java中,子类重写父类的方法;Kotlin中,想要重写父类的方法,需要父类的方法为开放类型

final override fun draw() {
    super.draw()
}

如果想要禁止被再次覆盖,可以通过final关键字修饰;
对于属性的覆盖,同样可以通过override关键字实现

2.3 内部类访问外部类的超类

class Student : Person {

    constructor(name: String) : super(name){

        print("派生类次级构造函数")
    }

    final override fun draw() {
        super.draw()
    }

    val ss:String  get() =  super.printName

    inner class Ming{

        fun outerMethod(){

            super@Student.draw()
        }
    }

}

Ming是Student的一个内部类,如果Ming想要访问Person中的draw方法,那么就可以通过super@OuterClass.SuperMethod的方式调用超类的方法

调用

 var ming = Student("name").Ming()
 ming.outerMethod()

2.4 覆盖规则

如果一个类从它的直接超类继承相同成员的多个实现, 它必须覆盖这个成员并提供其自己的实现;

2.5 抽象类

同Java一样,抽象类使用abstract关键字修饰,可以有构造函数但不能具体实现某个方法

interface Car{
     fun draw()
}

abstract class Benz : Car{

   abstract override fun draw()
}

3 属性和字段

3.1 属性的声明

通过var声明可变的属性,对应get和set方法,val定义的变量为只读,只能通过get获取

3.2 编译器常量

如果当前属性在编译器已经确定,可以使用const修饰,常见的就是修饰String字符串

3.3 延迟初始化

在Kotlin中,属性声明为非空的对象必须要初始化,但是如果不想立即初始化,可以使用lateinit关键字稍后初始化,类似于Dart中的late

 lateinit var age:String
 lateinit var person:Person
 lateinit var number:Int

但是其中遇到的lateinit是不能作用在Int类型,会报错,这种情况可以使用Number代替Int

 lateinit var number:Number
 
 public fun set(i : Int) {

     number = i
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Awesome_lay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值