kotlin中级---kotlin类之的继承.md

Hankkin_Coding Hankkin_Coding     2022-12-08     315

关键词:

Kotlin继承类

1.超类(Any)

在Kotlin中,所有的类都是继承自Any类,这是一个没有父类型的类。即当我们定义各类时,它默认是继承于Any类的

例如:

class Person

因为Any这个类只是给我们提供了equals、hashcode、toString三个方法,我们可以看看Any这个类的源码实现

package kotlin

/**
 * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass.
 * 看这个源码注释:意思是任何一个Kotlin的类都继承与这个[Any]类
 */
public open class Any 
    
    // 比较: 在平时的使用中经常用到的equals()函数的源码就在这里额
    public open operator fun equals(other: Any?): Boolean
    
    // hashCode()方法:其作用是返回该对象的哈希值
    public open fun hashCode(): Int
    
    // toString()方法
    public open fun toString(): String


从源码中我们看出,它直接属于Kotlin这个包下。并且只定义了上面所示的三个方法。在Java中,所有的类默认都是继承于Object类的。而Object类除了比Any多了几个方法和属性外,没有太大区别。但是它们并不是同一个类

从源码中所产生的疑惑:类与函数前面都加了open这个修饰符,既然Any是所有类的父类,那么我们自己要定义一个继承类,跟着Any类的语法与结构就能定义一个继承类,所以open修饰符是我们定义继承类的修饰符

2.定义

####2.1 继承类的基础使用

定义继承类的关键字为open。不管是类、还是成员都需要使用到open关键字

open class Person
    open var name = "Hankkin"
    open fun println()

例:这里定义一个继承类Demo,并实现两个属性与方法,并且定义一个DemoTest去继承自Demo

open class Demo

    open var num = 3

    open fun foo() = "foo"

    open fun bar() = "bar"



class DemoTest : Demo()
    // 这里值得注意的是:Kotlin使用继承是使用`:`符号,而Java是使用extends关键字


fun main(args: Array<String>) 

    println(DemoTest().num)
    DemoTest().foo()
    DemoTest().bar()



输入结果为:

3
foo
bar

分析:从上面的代码可以看出,DemoTest类只是继承了Demo类,并没有实现任何的代码结构。一样可以使用Demo类中的属性与函数。这就是继承的好处。

2.2继承类的构造函数

  • 无主构造函数

当实现类无主构造函数时,则每个辅助构造函数必须使用super关键字初始化基类型,或者委托给另一个构造函数。请注意,在这种情况下,不同的辅助构造函数可以调用基类型的不同构造函数

例如:

class MyView : View()

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int)
        : super(context, attrs, defStyleAttr)

可以看出,当实现类无主构造函数时,分别使用了super去实现了基类的三个构造函数

  • 存在主构造函数

当存在主构造函数时,主构造函数一般实现基类型中参数最多的构造函数,参数少的构造函数则用this关键字引用即可

class MyView(context: Context?, attrs: AttributeSet?, defStyleAttr: Int)
    : View(context, attrs, defStyleAttr) 

    constructor(context: Context?) : this(context,null,0)
    
    constructor(context: Context?,attrs: AttributeSet?) : this(context,attrs,0)

2.3函数的重载与重写

在Kotlin中关于函数的重载与重写和Java中几乎是一样的,但是这里还是举例说明一下

  • 重写函数中的量点特殊用法
    不管是Java还是Kotlin,重写基类型里面的方法,则称为重写,或者是覆盖基类型方法

1.当基类中的函数,没有用到open修饰符修饰的时候,实现类中出现的函数的函数名不能与基类中没有用open修饰符修饰的函数名相同,不管实现类中的函数有没有override修饰符

例如:

open class Demo
    fun test()   // 注意,这个函数没有用open修饰符修饰


class DemoTest : Demo()
    
    // 这里声明一个和基类型无open修饰符修饰的函数,且函数名一致的函数
    // fun test()   编辑器直接报红,根本无法运行程序
    // override fun test()   同样报红

2.当一个类不是用open修饰符修饰时,这个类默认就是final的

class A

//等价于

final class A   // 注意,则的`final`修饰符在编辑器中是灰色的,因为Kotlin中默认的类默认是final的

那么当一个基类去继承另外一个基类时,第二个基类不想去覆盖掉第一个基类的方法时,第二个基类的该方法使用final修饰符修饰。

open class A
    open fun foo()


// B这个类继承类A,并且类B同样使用open修饰符修饰了的
open class B : Demo()
   
    // 这里使用final修饰符修饰该方法,禁止覆盖掉类A的foo()函数
    final override fun foo()

  • 方法重载
open class Demo
    open fun foo() = "foo"


class DemoTest : Demo()

    fun foo(str: String) : String
        return str
    

    override fun foo(): String 
        return super.foo()
    
    

fun main(args: Array<String>) 
    println(DemoTest().foo())
    DemoTest().foo("foo的重载函数")

2.3重写属性

-重写属性和重写方法大致是相同的,但是属性不能被重载
重写属性即指:在基类中声明的属性,然后在其基类的实现类中重写该属性,该属性必须以override关键字修饰,并且其属性具有和基类中一样的类型。且可以重写该属性的值(getter)

open class Demo
    open var num = 3


class DemoTest : Demo()
    override var num: Int = 10

  • 重写属性中,val和var的区别
    这里可以看出重写了num这个属性,并且为这个属性重写了其值为10,但是,还有一点值得我们去注意:当基类中属性的变量修饰符为val的使用,其实现类可以重写属性可以用var去修饰。反之则不能
open class Demo
    open val valStr = "我是用val修饰的属性"


class DemoTest : Demo()

    /*
     * 这里用val、或者var重写都是可以的。
     * 不过当用val修饰的时候不能有setter()函数,编辑器直接会报红的
     */
    
    // override val valStr: String
    //   get() = super.valStr

    // override var valStr: String = ""
    //   get() = super.valStr

    // override val valStr: String = ""

    override var valStr: String = "abc"
        set(value)field = value


fun main(arge: Array<String>>)
    println(DemoTest().valStr)

    val demo = DemoTest()
    demo.valStr = "1212121212"
    println(demo.valStr)

  • getter方法慎用super关键字

在这里值得注意的是,在实际的项目中在重写属性的时候不用get() = super.xxx,因为这样的话,不管你是否重新为该属性赋了新值,还是支持setter(),在使用的时候都调用的是基类中的属性值。

kotlin中级---kotlin类之抽象类重载和重写.md

1.抽象类抽象类是不可直接被实例化的,因为它有一部分属性和方法没有被完整的赋值和体现。也就是说,抽象类是在告诉要继承的类:我有一些方法和属性没有具体实现,我命令你去把它们弄完整abstract其中值得... 查看详情

kotlin中级---初识kotlin中的对象.md

万物皆对象对象就是类的实例化用Kotlin描述对象classFriendvarname:String=""varhairColor:String="".....愉快的构造1.主构造函数:classFriendconstructor(valname:String,valage:Int)主构造二下面这种构造纯粹的传值,并不在这 查看详情

kotlin学习之路:继承(代码片段)

...承二.继承中的构造函数2.1继承中Java的构造函数2.2继承中Kotlin的构造函数2.3Kotlin多个构造函数的情况三.重写和重载3.1方法的重写3.2属性的重写四.super关键字4.1简单用法4.2复杂情况下的用法4.2.1子类重写方法中使用super4.2.2子类选择... 查看详情

kotlin继承

Kotlin中所有类都继承该Any类,它是所有类的超类,对于没有超类型声明的类是默认超类:classExample//从Any隐式继承Any默认提供了三个函数:equals()hashCode()toString()注意:Any不是java.lang.Object。如果一个类要被继承,可以使用open关键... 查看详情

Kotlin(Android) MD5 使用 PHP 签名检查

】Kotlin(Android)MD5使用PHP签名检查【英文标题】:Kotlin(Android)MD5checkingwithPHPSignature【发布时间】:2019-08-0711:56:57【问题描述】:我已经为此工作了好几天。我们的后端有一个使用PHP完成的签名检查:private$HMAC_ALGO=\'md5\';publicfunctionde... 查看详情

如何在 Kotlin 中用继承的类覆盖方法?

】如何在Kotlin中用继承的类覆盖方法?【英文标题】:HowtooverridemethodwithinheritedclassinKotlin?【发布时间】:2022-01-1209:16:14【问题描述】:我正在探索并积极在Kotlin的生产环境中使用泛型。Kotlin+泛型对我来说是一个很大的难题,所... 查看详情

kotlin初级---空安全.md

...安全为了解决类似NPE这类的问题,现代编程语言包括Kotlin解决这类问题的方法就是把运行时的错误转变成编译期的错误。通过支持作为类型系统的一部分的可空性,编译器就能在编译期发现很多潜在的错误,从而减少... 查看详情

kotlin小悟-这个继承有点不一样(代码片段)

今天聊聊kotlin中关于构造函数的一个话题。我们知道,在kotlin中构造函数分为主构造函数和从构造函数,关于详细的内容,可以点击下面的文章链接了解。Kotlin系列之主构造方法和初始化语句块Kotlin系列之从构造方法... 查看详情

kotlin初级---空安全.md

空类型、空安全变量的定义Kotlin中的变量修饰符只有两个val修饰的变量不能重新被赋值var修饰的变量可以被重新赋值var修饰的变量不可为null,val修饰的可为nullvala:Int?=nullvarb:Int变量a在使用的时候需要判断改变量是否为null&... 查看详情

kotlin初级---空安全.md

空类型、空安全变量的定义Kotlin中的变量修饰符只有两个val修饰的变量不能重新被赋值var修饰的变量可以被重新赋值var修饰的变量不可为null,val修饰的可为nullvala:Int?=nullvarb:Int变量a在使用的时候需要判断改变量是否为null&... 查看详情

kotlin初级---字符串和字符.md

字符串Kotlin中字符串是有序的字符的集合常用方法1.isEmpty()用来判断字符串为空2.count()或者length获取字符串中的字符数目3.get(i)或者[i]获取指定位置的字符4.substring()截取某一段字符串5.index索引indexOf()、lastIndexOf()、indices索引范围6... 查看详情

从 Kotlin Native 继承 UIView

】从KotlinNative继承UIView【英文标题】:SubclassingUIViewfromKotlinNative【发布时间】:2021-11-1420:34:13【问题描述】:UIKit旨在通过子类和重写方法使用。通常,UIView的drawRectobjective-C方法在SWIFT中是这样实现的:importUIKitimportFoundationclassSm... 查看详情

在 Kotlin 中扩展 Java 类时继承的平台声明冲突

】在Kotlin中扩展Java类时继承的平台声明冲突【英文标题】:Inheritedplatformdeclarations***whenextendingaJavaclassinKotlin【发布时间】:2018-02-0900:52:05【问题描述】:我正在尝试使用Kotlin扩展第三方Java类,但我收到以下编译器消息:继承的... 查看详情

kotlin语言中的继承与构造函数(详解)(代码片段)

        学习kotlin时,有很多小伙伴无法理解为何有的继承结构父类后面需要加括号,有时候却不用加括号,本篇文章小编将为你们解除这个困惑!顺便为大家详解一下kotlin中的主构造函数和次构造函数。   ... 查看详情

kotlin开发基础(代码片段)

...一时间获取我的最新文章,请关注公众号:技术特工队Kotlin开发基础(一)Kotlin开发基础(二)Kotlin开发基础(三)类本篇文章主要介绍类的继承,接口,复写,单例,以及object属性的介... 查看详情

kotlin类与继承

类Kotlin使用class关键字声明类,类声明由类名、类头(指定其类型参数、主构造函数等)和由大括号包围的类体组成。类头和类体都是可选的,如果一个类没有类体大括号可省略class NoBody类的构造函数一类可以有一个主构造... 查看详情

kotlin初学者继承(extend)(代码片段)

Kotlin继承(extend)        Kotlin允许一个类继承自另一个类        Kotlin中所有类都继承自Any类        Any类是所有类的超类,对于没有超类型声明的类是默认超类        Kotlin类默认都是封闭的,要让某个类... 查看详情

kotlin开发基础(代码片段)

...一时间获取我的最新文章,请关注公众号:技术特工队Kotlin开发基础(一)Kotlin开发基础(二)Kotlin开发基础(三)类本篇文章主要介绍类的继承,接口,复写,单例,以及object属性的介... 查看详情