open
- 类要被继承需使用
open
关键字进行修饰
Kotlin中类在默认情况下是无法被继承的,也就是说类在默认情况下都是final
的。如果才能让类被继承,Kotlin提供了open
关键字,只有被open
修饰的类才可以被继承,否则编译器报错。
class Base(var id:Int)
//Error:(2, 21) Kotlin: This type is final, so it cannot be inherited from
class Child(id:Int):Base(id)
fun main(args:Array<String>) {
val c = Child(1)
}
Any超类
Kotlin中所有类型都继承Any
类,是所有类的超类,对于没有超类声明的类是默认超类。简单来说,Kotlin中所有类都拥有一个共同的超类Any
,对于没有超类声明的类的默认超类。
Any不是java.lang.Object
,Any类默认仅提供了三个函数
equals()
hashCode()
toString()
构造函数
- 子类有主构造函数
- 子类没有主构造函数
如果子类有主构造函数则父类必须在主构造函数中立即初始化
//定义基类
open class User(var id:Int)
//定义子类
class Member(id:Int, var name:String):User(id)
fun main(args:Array<String>) {
val m:Member = Member(1, "junchow")
println(m.id)
println(m.name)
}
如果子类没有主构造函数则必须在每个次构造函数中使用super
关键字来初始化基类
//定义基类
open class User(var id:Int){
constructor(id:Int, name:String):this(id){
println("user: id=$id name=$name")
}
}
//定义子类
class Member:User{
constructor(id:Int, name:String, nick:String):super(id){
println("member: id=$id name=$name nick=$nick")
}
}
fun main(args:Array<String>) {
//member: id=1 name=junchow nick=jc
val m:Member = Member(1, "junchow", "jc")
}
如果子类没有主构造函数,则子类的每个次构造函数必须通过super
关键字来初始化父类或通过其他子类构造函数来完成,不同的次构造函数可以调用父类不同的构造函数。
重写属性
- 子类重写父类属性,父类属性必须使用
open
关键字进行修饰。 - 子类重写父类属性,子类属性必须使用
override
关键字修饰。 - 父类中可重写的属性必须具有兼容类型
- 父类中声明的属性可以通过初始化或
getter
函数被重写 - 子类
var
可变属性可重写父类val
只读属性,反之不行。因为val
只读属性本身定义了getter
方法,重写为var
可变属性时会在衍生类中额外声明一个setter
函数。 - 可在主构造函数中使用
override
关键字作为属性声明的一部分
open class Base{
//父类中声明的属性可以通过getter`函数被重写
open val id:Int get(){
return 0
}
//父类中声明的属性可以通过初始化被重写
open var name:String = ""
open fun run(){
println("base run")
}
}
class Child:Base(){
//子类可以使用var属性重写父类val属性,但反知则不行。
override var id:Int = 1
override fun run(){
println("child run")
}
}
fun main(args:Array<String>) {
val c = Child()
println(c.id)//1
}
重写函数
- 父类使用
fun
声明函数时,默认是以final
修饰,即不能被子类重写。 - 子类重写父类函数时,父类需手动添加
open
关键字进行修饰。 - 子类重写父类函数时,子类需使用
override
关键字进行修饰。
open class Base{
open fun run(){
println("base run")
}
}
class Child:Base(){
override fun run(){
println("child run")
}
}
fun main(args:Array<String>) {
val c = Child()
c.run()//child run
}