Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Kotlin中级(6)- - - Kotlin类之的继承.md

Kotlin中级(6)- - - Kotlin类之的继承.md

作者头像
Hankkin
发布于 2018-09-30 02:46:04
发布于 2018-09-30 02:46:04
61000
代码可运行
举报
文章被收录于专栏:Android干货园Android干货园
运行总次数:0
代码可运行

Kotlin继承类

1.超类(Any)

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

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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关键字

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
open class Person{
    open var name = "Hankkin"
    open fun println()
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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()

}

输入结果为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
3
foo
bar

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

2.2继承类的构造函数
  • 无主构造函数

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

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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关键字引用即可

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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修饰符

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
open class Demo{
    fun test(){}   // 注意,这个函数没有用open修饰符修饰
}

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class A{}

//等价于

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
open class A{
    open fun foo(){}
}

// B这个类继承类A,并且类B同样使用open修饰符修饰了的
open class B : Demo(){
   
    // 这里使用final修饰符修饰该方法,禁止覆盖掉类A的foo()函数
    final override fun foo(){}
}
  • 方法重载
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
open class Demo{
    open var num = 3
}

class DemoTest : Demo(){
    override var num: Int = 10
}
  • 重写属性中,val和var的区别 这里可以看出重写了num这个属性,并且为这个属性重写了其值为10,但是,还有一点值得我们去注意:当基类中属性的变量修饰符为val的使用,其实现类可以重写属性可以用var去修饰。反之则不能
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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(),在使用的时候都调用的是基类中的属性值。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年09月21日,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Swift vs. Kotlin 漫谈系列之类与继承
Kotlin 君和 Swift 君在一个团队一起开发已经很久了,由于平台的差异性,他们经常会进行一些技术上的交流(PK),《Kotlin vs. Swift漫谈》系列就是他们在互相切磋是的语录。内容会
用户1907613
2018/07/20
3.7K0
Kotlin语法基础之继承
Kotlin中所有的类都有一个公有的超类:Any,这是所有没有声明超类的类的默认父类。 class Example //隐式继承自Any Any!=Java.lang.Object。尤其,除了equals()、hashCode()和toString()三个方法外,没有任何成员。为了显式地声明超类,语法如下: open class Base(p:Int) class Derived(p:Int):Base(p) 如果类具有主构造器,则可以使用主构造器的参数(并且必须)初始化父类。 如果类没有主
xiangzhihong
2018/02/06
8770
Kotlin For Android 笔记(三)
使用 @JvmOverloads 可以极大的简化构造函数的模板代码 Java 版本
code_horse
2019/03/04
5630
Kotlin入门(14)继承的那些事儿
上一篇文章介绍了类对成员的声明方式与使用过程,从而初步了解了类的成员及其运用。不过早在《Kotlin入门(12)类的概貌与构造》中,提到MainActivity继承自AppCompatActivity,而Kotlin对于类继承的写法是“class MainActivity : AppCompatActivity() {}”,这跟Java对比有明显差异,那么Kotlin究竟是如何定义基类并由基类派生出子类呢?为廓清这些迷雾,本篇文章就对类继承的相关用法进行深入探讨。 博文《Kotlin入门(13)类成员的众生相》在演示类成员时多次重写了WildAnimal类,这下你兴冲冲地准备按照MainActivity的继承方式,从WildAnimal派生出一个子类Tiger,写好构造函数的两个输入参数,补上基类的完整声明,敲了以下代码不禁窃喜这么快就大功告成了:
aqi00
2019/01/18
1.6K0
kotlin基础语法
最近在学kotlin,这是本人看菜鸟教程后所做的笔记,很多会内容和菜鸟教程重复,仅供参考
HelloJack
2018/10/25
2.1K0
About Kotlin-Kotlin中的类1About Kotlin(1)
因为是从Java的角度来学习Kotlin,在Java中,类作为第一等公民。故学习Kotlin,也先从其的类开始。
deep_sadness
2018/08/30
1.2K0
Kotlin | 4.类、对象和接口
本章内容包括: 类和接口 非默认属性和构造方法 数据类 类委托 使用 object 关键字 1、定义类继承结构 /*--------------- 4.1.1 kotlin 中的接口-------------*/ // 代码清单 1 声明一个简单的接口 // interface Clickable { // fun click() // } // 代码清单 2 实现一个简单的接口 cla
Jingbin
2021/02/22
9650
Kotlin学习日志(五)类与对象
通过上述的代码比较,Kotlin对类的写法与Java之间有以下几点区别: (1)Kotlin省略了关键字public,因为Kotlin默认类是开放的,所以不需要这个关键字。 (2)Kotlin用冒号“:”代替extends,也就是通过冒号表示继承关系。 (3)Kotlin进行继承时,父类后面多了括号“()”。
晨曦_LLW
2020/09/25
1.2K0
《Kotlin极简教程》第五章 Kotlin面向对象编程(OOP)一个OOP版本的HelloWorld构造函数传参Data Class定义接口&实现之写pojo bean定一个Rectangle对象封
We frequently create a class to do nothing but hold data. In such a class some standard functionality is often mechanically derivable from the data. In Kotlin, this is called a data class and is marked as data
一个会写诗的程序员
2018/08/20
1.5K0
《Kotlin 程序设计》第五章 Kotlin 面向对象编程(OOP)第五章 Kotlin 面向对象编程(OOP)1. 面向对象的HelloWorld 2. 面向对象编程思想简述3.Kotlin 面向
Kotlin 同Java、 Scala、Groovy 一样,都使用关键字class 来定义类。
一个会写诗的程序员
2018/08/20
1.5K0
【Kotlin】接口 ( 声明 | 实现 | 接口方法 | 接口属性 | 接口覆盖冲突 | 接口继承 )
① 声明与实现 : 使用 interface 关键字声明接口 , 实现时需要重写所有的抽象成员 ( 属性 / 方法 ) ;
韩曙亮
2023/03/27
1.4K0
Kotlin 学习笔记(一)
基本类型 var age: Int = 123 // 标准语法,声明一个可变变量 age val name: String = "Tom" // 标准语法,声明一个不可变
修之竹
2022/08/19
6510
Kotlin 学习笔记(一)
解毒 Kotlin Koans: 03 函数参数、重载
哦,不,不能这样,据说最近各方大佬们都已经开始不怎么关注 Kotlin 了,原因嘛,估计也是工(wu)作(li)太(ke)忙(tu)吧,所以我要挺住。。。
bennyhuo
2020/02/20
8980
【Kotlin】Kotlin 自定义组件 ( 自定义 View | 自定义 SurfaceView )
文章目录 一、自定义 View 组件 ( Kotlin ) 二、自定义 SurfaceView 组件 ( Kotlin ) 自定义组件构造函数统一在 constructor(context: Cont
韩曙亮
2023/03/28
1.6K0
Kotlin 类和对象介绍
介绍:在Kotlin中类可以包含:构造函数和初始化代码块,函数,属性,内部类,对象声明. 使用的关键字和java是一样的使用class进行声明
zinyan.com
2023/07/13
2130
Kotlin 类和对象介绍
About Kotlin-Kotlin中的类2About Kotlin(2)
使用sealed修饰符修饰。其实是一组类的集合。可以用来表示受限的类的继承结构。 其也可以有子类,所有子类也必须在相同的文件中声明。 密封类从某种意义上说,它们是枚举类的扩展:枚举类型的值集也受到限制,但每个枚举常量仅作为单个实例存在,而密封类的子类可以包含多个实例并包含状态。这样又具备了枚举不具备的灵活性。
deep_sadness
2018/08/30
2.6K0
转向Kotlin——类和接口
和Java没有什么两样,Kotlin中,类的声明也使用class关键字,如果只是声明一个空类,Kotlin和Java没有任何区别,不过定义类的其他成员,区别就很大了。
蜻蜓队长
2018/08/03
9350
Kotlin:这是一份全面 & 详细的 类使用 的语法学习指南
对于构造函数,Kotlin中类可有一个主构造函数 & 多个次构造函数,下面将详细说明。
Carson.Ho
2020/04/09
9470
Kotlin:这是一份全面 & 详细的 类使用 的语法学习指南
Kotlin安卓开发学习(2)
这里还有一个语法糖,在使用Kotlin时,我们不需要像Java那样定义 get/set 方法,在调用对象的属性时也不需要调用get/set方法来使用属性。使用Kotlin时,我们是直接对属性进行赋值和读取,因为Kotlin会自动将赋值、读取语句转换成get/set方法,方便开发者使用。
摸鱼的G
2023/02/22
3900
Android:这是一份全面 & 详细的Kotlin入门学习指南
点击Android Studio Preference -> Plugins -> 搜索Kotlin Languages插件
Carson.Ho
2020/01/13
2.9K0
Android:这是一份全面 & 详细的Kotlin入门学习指南
推荐阅读
相关推荐
Swift vs. Kotlin 漫谈系列之类与继承
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文