您的位置:首页 > 移动开发 > Android开发

Kotlin学习笔记(三)类和继承

2017-06-12 16:25 183 查看
提示:本文为作者阅读Kotlin中文站学习笔记,建议读者移步Kotlin中文站完整学习。



Kotlin中,使用class关键字生命一个类。类声明由类名,类头(指定其类型参数,主构造函数等)和大括号括起来的类体组成。

class A public constructor(arg1:String){

}


Kotlin中,一个类可以有一个主构造函数或和一个或多个次构造函数。主构造函数是类头的一部分,跟在类名(和可选的类型参数)后面,如果主构造函数没有任何注解或可见性修饰符,可以省略constructor关键字。

class A (arg1:String){

}


主构造函数不包含任何的代码,初始化代码可以放到init关键字修饰的初始化块中:

class A (arg1:String){

//初始化块
init {
//...
}

}


主构造函数中的参数可以在初始化块,或类体内声明的属性初始化器中使用:

class(arg1:String){

var s tr:String=arg1

//初始化块
init {
print(arg1)
}

}


也可以以下方式,声明属性及在主构造函数中初始化属性:

class A (var arg1:String){
}


类也可以声明前缀有constructor的次构造函数,如果类有主构造函数,每个次构造函数都要委托给主构造函数,可以直接委托,也可以通过别的次构造函数间接委托。委托到同一个类中的另一个构造函数,用this关键字即可。

class A (var arg1:String){

constructor():this("")//次构造函数

}


如果一个非抽象类没有声明任何(主,次)构造函数,Kotlin会生成一个不带任何参数的默认构造函数,可见性为public。

在 JVM 上,如果主构造函数的所有的参数都有默认值,编译器会生成 一个额外的无参构造函数,它将使用默认值。

class A (var arg1:String=""){

}


在Kotlin中,没有new关键字,要创建一个类的实例,只需像调用普通函数一样,调用类的构造函数:

var a:A=A()//创建一个A的实例


继承

Kotlin中所有的类都有一个共同的超累类Any,对于没有超类型声明的类是默认超类。Any类不是java.lang.Object类,它只有equals,hashCode(),toString()3个成员方法。

要显式声明一个超类,可以把类型放到类头的冒号之后,如果该基类有一个主构造函数,则其基类必须用主构造函数的参数就地初始化:

class B constructor(arg: String):A(arg){

}


如果类没有主构造函数,那么每个次构造函数必须使用 super 关键字初始化其基类型,或委托给另一个构造函数做到这一点。 注意,在这种情况下,不同的次构造函数可以调用基类型的不同的构造函数:

class MyView : View {
constructor(ctx: Context) : super(ctx)

constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}


类上的 open 标注与 Java 中 final 相反,它允许其他类从这个类继承。默认情况下,在 Kotlin 中所有的类都是 final。

Kotlin力求清晰,需要显式标注可以覆盖的成员及覆盖后的成员。

open class A constructor(arg1:String){

open fun f():Unit{

}
}

class B :A(){

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


B.f()函数必须加上override标注,否则会编译出错。如果A.f()没有加open标注,则子类中不允许定义相同签名的函数,不论加不加override。在一个final类(没有open标注的类),开放成员是禁止的。Kotlin中默认类是final的。

标记为override的成员本身是开放的,可以在子类中覆盖。如果你想禁止其在子类中继续被覆盖,可以加final关键字。

class B :A(){

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


属性覆盖与方法覆盖类似,在超类中声明然后在派生类中重新声明的属性必须以override开头,并且必须具有兼容的类型。每个声明的属性可以由具有初始化器的属性或getter方法的属性覆盖。

open class C {
open val str: String get() = "Hello World!"
}

class D : C() {
override var str: String
get() = super.str
set(value) {
str = value
}
}


我们可以用一个 var 属性覆盖一个 val 属性,但反之则不行。这是允许的,因为一个 val 属性本质上声明了一个 getter 方法,而将其覆盖为 var 只是在子类中额外声明一个 setter 方法。

我们也可以在主构造函数中使用 override 关键字作为属性声明的一部分。

open class C {
open val str: String get() = "Hello World!"
}

class D constructor(override val str: String): C() {

}


在 Kotlin 中,实现继承由下述规则规定:如果一个类从它的直接超类继承相同成员的多个实现, 它必须覆盖这个成员并提供其自己的实现(也许用继承来的其中之一)。 为了表示采用从哪个超类型继承的实现,我们使用由尖括号中超类型名限定的 super,如
super<E>


interface E{
fun f():Unit{
print("f in E")
}
}

interface F{
fun f():Unit{
print("f in F")
}
}

class D:E,F{

override fun f() {
super<E>.f()
super<F>.f()
}

}


我们可以用abstract关键字定义抽象类和抽象方法,抽象方法不需要在本类实现,并且不需要用open关键字标注一个抽象类或抽象方法-因为这不言而喻。

//抽象类
abstract class G{
abstract fun g()//抽象方法
}

class H: G() {
override fun g() {
TODO("not implemented")
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android kotlin 继承