前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kotlin语法基础之继承

Kotlin语法基础之继承

作者头像
xiangzhihong
发布2018-02-06 19:48:44
8050
发布2018-02-06 19:48:44
举报
文章被收录于专栏:向治洪向治洪

Kotlin中所有的类都有一个公有的超类:Any,这是所有没有声明超类的类的默认父类。

代码语言:javascript
复制
class Example   //隐式继承自Any

Any!=Java.lang.Object。尤其,除了equals()、hashCode()和toString()三个方法外,没有任何成员。为了显式地声明超类,语法如下:

代码语言:javascript
复制
open class Base(p:Int)  

class Derived(p:Int):Base(p) 

如果类具有主构造器,则可以使用主构造器的参数(并且必须)初始化父类。 如果类没有主构造器,那么每个辅助构造器初始化时需要使用super关键字,或者将其委托给其他构造器。需要注意的是,在这种情况下,不同的辅助构造器可以调用基类的不同构造器。

代码语言:javascript
复制
class MyView:View{
    constructor(ctx:Context):super(ctx)  
    constructor(ctx:Context,attrs:AttributeSet):super(ctx,attrs)
}

open注解和Java的final相反:它允许其他类继承自该类。默认的,Kotlin中所有的类是final的,也就是说不能继承的。

覆写方法

Kotlin总是做一些明确的事情,不像Java,Kotlin要求复写方法时需要显式的注解和重写。

代码语言:javascript
复制
open class Base {
    open fun v() {
        println("Base.v()")
    }

    fun nv() {
        println("Base.nv")
    }

}

class Derived() : Base() {

    override fun v() {
        println("Derived.v()")
    }

}

复写Derived的v()时,ovverride注解是必须的,否则编译器会报错。如果没有open注解,比如Base的nv(),那么在子类中是不能覆写该方法的。在一个final类中(没有open注解声明),open成员是禁止的。也就是说final类的每个成员也都是final的。 一个标记为override的成员自身就是open的,子类仍然可以覆写它。如果你想禁止覆写,那么使用final关键字。

代码语言:javascript
复制
open class AnotherDerived() : Base() {
    final override fun v() {
        println("AnotherDerived.v")
    }
}

最后,main()验证多态性。

代码语言:javascript
复制
fun main(args: Array<String>) {

    var base1: Base = Base()
    var base2: Base = Derived()
    var base3: Base = AnotherDerived()

    base1.v()
    base2.v()
    base3.v()

}

覆写属性

覆写属性和覆写方法基本类似;如果子类要重新声明父类中已经声明过的属性,那么需要使用override,并且类型要兼容。每个声明的属性可以被具有初始化器的属性或具有getter方法的属性覆盖。

代码语言:javascript
复制
open class Foo {
    open val x: Int
        get() {
            println("Foo")
            return 3
        }
}

class Bar1 : Foo() {
    override val x: Int = 2
}

可以使用var属性覆盖val属性,反之不可以。因为val属性基本上声明一个getter方法,并将其替换为var,另外在派生类中声明一个setter方法。 可以在主构造器使用override覆盖属性:

代码语言:javascript
复制
interface Aoo {
    val count: Int
}

class Aoo1(override val count: Int) : Aoo

class Aoo2 : Aoo {
    override var count: Int = 0
}

覆写准则

在Kotlin中,实现继承由以下规则控制:如果类从其直接超类继承同一成员的多个实现,则它必须覆盖该成员并提供自己的实现(可能使用其中一个继承)。 要表示从其继承的实现的超类型,可在尖括号中使用超类型名称超级限定,例如,super。

代码语言:javascript
复制
open class A {
    open fun f() {
        println("A")
    }

    fun a() {
        println("a")
    }

}

//接口的方法默认open
interface B {
    fun f() {
        println("B")
    }

    fun b() {
        println("b")
    }

}

class C() : A(), B {
    override fun f() {
        super<A>.f()
        super<B>.f()
        println("C")
    }
}

上面的代码继承自A和B是没有问题的,a()和b()因为C知道继承自哪一个类。但是对于f(),我们有两个继承,所以我们需要覆写f(),并且需要提供我们的实现来消除歧义。

总结

  1. Kotlin中的类默认是final的,如果需要子类继承,需要使用open修饰;
  2. Kotlin中的方法默认是不允许复写的,只有用open修饰时,子类才可以进行覆写,并且需要使用override进行显示标注
  3. 属性也支持覆写
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-12-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 覆写方法
  • 覆写属性
  • 覆写准则
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档