一、Kotlin中类的继承
在Java中,类基于Object,而在Kotlin中类基于Any,所有类都默认继承Any。kotlin中的类默认是final类型的,不可被继承,想要作为基类被继承必须使用open关键字修饰。
对于没有超类型声明的类默认超类是Any,Any类只有三个函数~
package kotlin
public open class Any {
public open operator fun equals(other: Any?): Boolean
public open fun hashCode(): Int
public open fun toString(): String
}
二、子类对构造函数的实现
1.当子类中有构造函数,则基类必须在主构造函数中立即初始化
open class S(name: String, age: Int) { //基类
}
//子类中有构造函数,则基类必须在主构造函数中立即初始化
class SS(var name: String, val age: Int, val score: Int) : S(name, age) {
}
fun main(args: Array) {
val s = SS("Tina", 20, 60)
println("学生名:${s.name}")
println("年龄:${s.age}")
println("成绩:${s.score}")
}
学生名:Tina
年龄:20
成绩:60
2.当子类中没有主构造函数时,则必须每一个次要构造函数或代理另一个构造函数中用 super 关键字初始化基类。初始化基类时,可以使用super来调用基类的不同构造函数。
open class Personal(name: String) {
constructor(name: String, age: Int) : this(name) {
//初始化
println("---基类次级构造函数-----")
}
}
class SrudentImpl : Personal {
constructor(name: String, age: Int, no: String, score: Int, likely: String) : super(name, age) {
println("----- 继承类的次级构造函数 ------")
println("学生名:${name}")
println("年龄:${age}")
println("学生号:${no}")
println("成绩:${score}")
}
}
fun main(args: Array) {
var student = SrudentImpl("Mikle", 18, "12485684", 98, "唱歌")
}
学生名:Mikle
年龄:18
学生号:12485684
成绩:98
3.方法的重写
基类中,使用fun声明函数时,该函数默认是final修饰的,不能被子类重写。如果允许该函数能被重写,则需手动添加open修饰它,子类复写使用override关键词。
open class D {
open fun study() { //允许子类重写的方法
println("基类DD中定义需被子类重写的方法")
}
}
class DD : D(), F {
override fun study() {
println("子类重写了父类的方法~~~")
super.study()
super.study()
}
}
interface F {
fun study() { //允许子类重写的方法
println("接口F中定义的方法~~")
}
}
4.属性重写:使用override关键字
interface Foo {
val count: Int
}
//属性的复写使用override关键字
class Bar1(override val count: Int) : Foo {}
class Bar2 : Foo {
override var count: Int = 0
}
三、Kotlin中接口的实现
使用关键字interface定义接口,一个类可实现一个或多个接口
interface MyInterface {
val name:String //接口中的属性只能是抽象的,不允许初始化值,实现接口,必须重写属性
fun bar()
fun foo()
}
class Child: MyInterface {
override var name:String="我是复写的name属性" //重写属性
override fun foo() {
println("调用了foo方法")
}
override fun bar() {
println("调用了bar方法")
}
}
fun main(args: Array) {
val c = Child()
c.foo()
c.bar()
println(c.name)
}
调用了foo方法
调用了bar方法
我是复写的name属性
***当实现多个接口时,可能会遇到同一方法继承多个实现的问题。
interface A {
fun foo() {
println("A")
} //有方法体,代表已经实现
fun bar() //无方法体,是抽象的,未实现,需要被子类重写
}
interface B {
fun foo() {
println("B") //已实现
}
fun bar() {
println("bar") //已实现
}
}
class C : A {
override fun bar() {
}
}
class H : A, B {
override fun bar() {
super.bar()
}
override fun foo() {
super.foo()
super.foo()
}
}
fun main(args: Array) {
val h=H()
h.foo()
h.bar()
}
调用了foo方法
调用了bar方法
我是复写的name属性