继承
声明一个person类
class Person() {
}
声明一个Student类
class Student() {
}
现在Person和Student两个类并没有任何关系 在java中使用继承使用extends kotlin中使用':' 冒号来继承 open关键字修饰要被继承的类
例:现在要Student类继承Person类
Person类修改如下
open class Person() {
}
Student类修改如下
class Student() : Person() {
}
Student类继承Person 后在后面加上了小括号,java中并没有 这就到了kotlin中的构造函数了
kotlin中分为主构造函数和次构造函数
主构造函数
先看一下示例代码
class Student(val name:String,val age:Int) : Person() {
var name = ""
var age = 0
}
这样就声明了一个主构造函数
新建Student的时候就必须要传入name和age参数
val student = Student("张三",20)
一般在主构造函数中做一些初始化操作要怎么办呢
class Student(val name:String,val age:Int) :Person() {
init {
println("name is" + name)
println("age is" + age)
}
}
kotlin中提供了init结构体 初始化的逻辑可以写在init结构体里面
根据继承的特性来说,子类必须实现父类的构造方法 但是没有具体的函数体 可以写在init结构体里面 当然这并不是一种好的办法
下面修改一下Person类
open class Person(val className:String,val classId:Int) {
...
}
如果这样修改 Student类必然会报错
Student类报错的原因是Person后面的空括号表示要调用Person类中的无参构造
但是现在的无参构造没有了 所以报错了
解决这个问题的办法就是在Person后面加上className和classId参数
但是发现Student类中并没有className和classId字段 那我们现在加上
但是加上之后突然发现出问题了 如下图:
注意如果给className和classId加上val修饰符就导致了以上错误 因为与Person类中的className和classId字段重复了,所以不用加上val修饰符了
className和classId字段设置为只在主构造函数作用域中就好了
现在新建一个Student类
val student = Student("张三",20,"初三",2)
传入的参数为姓名张三,年龄20,初三,2班
现在主构造函数大概就是这样
次构造函数
次构造函数必须调用主构造函数
class Student(val name: String, val age: Int, className: String, classId: Int) :
Person(className, classId) {
init {
println("name is" + name)
println("age is" + age)
}
constructor(name: String, age: Int) : this(name, age, "", 0) {
}
constructor() : this("", 0) {
}
}
次构造函数通过constructor关键字来声明
第一个构造函数接收了name和age参数然后又通过this调用了主构造函数给className和classId设置成了初始值
第二个调用了第一个构造函数,传了空参数,给name和age参数设置成了初始值
现在就有三种方法进行初始化Student类了
val student = Student("张三",20,"初三",2)
val student1 = Student("张三",20)
val student2 = Student()
还有一种特殊的情况
函数中没有主构造函数 只有次构造函数
class Student2 : Person{
constructor(name: String, age: Int) : super(name, age) {
}
}
这种情况十分的少见 首先Student并没有定义主函数,而是声明了一个次函数,所以这里就不用再给person加上小括号了
这种情况十分的少见 所以可以暂时不用了解太多,到后面写的多了 就明白了 我也不明白
(昨天科目三挂了 妈的)