【KtAndroid - 7】继承、抽象类、接口

书接上篇……

之所以将这三个写在一起而不与类写在一起,大概是因为这三者惺惺相惜吧。(类写完了才发现,如果一个开一篇文章的话……有划水的赶脚!嘿嘿)

在面向对象中这继承、抽象类、接口三者可是占着不弱的低位哈,可以说有了它们,面向对象才具备了灵魂。

在上篇文章我说了类的定义,对象的创建,其实都没什么,但是!!构造方法的定义与使用一定要摸清楚。因为,在用惯了java后对于接下来的继承、抽象类、接口难免会觉得

1. 继承

一. 基本继承

首先来说说继承!

来一段代码:

package cn.xinidi.java;

/**
 * @author Gang
 * @Date 2020/4/29
 * @Version 1.0
 */
public class JavaFile {
    public static void main(String[] args) {
        Man man = new Man();
        System.out.println(man.head);
    }
}


class Person{
    String head = "头";
}

class Man extends Person{
    public Man() {
        this.head = "男人的头";
    }
}
1.png

这是java中的继承。

来看kotlin中的继承:

package cn.xinidi.kotlin

/**
 * @author Gang
 * @Date 2020/4/29
 * @Version 1.0
 */
class KtFile {
    companion object{
        @JvmStatic
        fun main(args: Array<String>) {
            println("kt:${Man().head}")
        }
    }
}

open class Person {
    var head = "头"
}

class Man : Person() {
    init {
        head = "男人的头"
    }
}
2.png

好了,这就是基本的继承了。

要点:java没什么可说的。然鹅,对于kotlin来说,父类 Person 使用了一个open关键字,以达到子类可以继承它。(你也可以试试去掉open)

子类继承的关键字并不是extends而是一个:,其实这个:在kotlin中还有其他用法,不要急,马上会说。

接下来说方法的继承,子类重写父类方法:

open class Person {
    var head = "头"
    open fun jump() {
        println("跳!")
    }
}

class Man : Person() {
    init {
        head = "男人的头"
    }

    override fun jump(){
        println("男人在跳!")
    }
}

父类方法jump也是用了open来声明,该方法可以被继承重新,但是在子类中我们在jump前加了一个override。说起override,我相信在java中没少见它吧。

在java中随你自己的心情写或者是不写它,编译器不会提醒你的代码有问题。

但是在kotlin中,你必须写它,不写就报错,不给糖就捣蛋。

同样的,重写父类字段也是通过override

open class Person {
    open var head = "头"
    open fun jump() {
        println("跳!")
    }
}

class Man : Person() {
    override var head = "男人的头"
    /*init {
        head = "男人的头"
    }*/

    override fun jump() {
        println("男人在跳!")
    }
}

二. 父类的构造函数

如果继承的父类带有参数构造函数,那么该怎么继承呢?

open class Animal(var type: String) {
    ……
}

class Dog(name: String, type: String) : Animal(type) {
    ……
}

这是在子类拥有主构造函数的情况下,如果没有主构造函数,那么次构造函数怎么写呢?

open class Animal(var type: String) {
    ……
}

class Cat : Animal {
    constructor(name: String, type: String) : super(type) {
        ……
    }

    constructor(name: String, age: Int, type: String) : super(type) {
        ……
    }
}

子类中可使用super调用父类的方法。

与java一样,kotlin只支持单继承

3.png

这里又一点要注意:

子类继承父类时,不能有跟父类同名的变量,除非父类中该变量为 private,或者在父类中该变量为 open 并且子类是用 override 关键字重写的。

2. 抽象类

类的继承说完了,那么接下来就是今天的第二个猪脚。

与java一样,抽象类的声明也是使用abstract

abstract class AbsKtPerson {
    open abstract fun run()
    open abstract fun jump()
}

继承实现:

4.png

3. 接口

kotlin中的接口也是用interface来定义

interface InterfacePerson{
    open fun eat()
    open fun speak(){
        println("说话!")
    }
}

interface InterfaceTool{
    open fun knife()
}

class Impl : AbsKtPerson(),InterfacePerson,InterfaceTool{
    override fun run() {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun jump() {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun eat() {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun knife() {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}

同时在kotlin中,接口中支持写方法体,实现了方法体的方法,子类可以选择性实现。

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

如果多个上级中存在了相同的已实现的方法,如:

abstract class AbsKtPerson {
    open abstract fun run()
    open abstract fun jump()
    //在抽象类中实现了
    open fun speak(){
        println("AbsKtPerson说话!")
    }
}

interface InterfacePerson{
    open fun eat()
    //在接口中实现了
    open fun speak(){
        println("InterfacePerson说话!")
    }
}

将会出现以下错误

5.png

你可以通过泛型指定使用其中一个的super(但是,该super除了某些特定情况下必须由子类调用父类,其他情况下并不是必须的)。

也就是你可以这样:

6.png

但是遇到必要调用的时候:

7.png

这里我要来说一个容易混淆的地方

也就是上文提到的:

在子类中 无论是实现接口,还是继承父类都是使用的:

那么区别在于

8.png

对,就是这个()。如果是继承类,只需要在后面加一个括号(别傻啊,这括号是干嘛的?继承哪块已经说了,负责将父类需要的参数传过去,如果父类有一个参数构造函数,那就不能直接打括号了)

另外还有一种写法,可以稍微记一下

9.png

好了就到这,这些东西我只讲了个大概,并不是我讲了,你看了,就完了。

要自己多写多练,另外kotlin中的多态与java中是一样的!

4. 关于“::”引用的说明

在java中我们可以通过接口实现方法回调,特别是在android这一块使用得较多。

在kotlin有一种写法,就是将方法作为参数传给需要被调函数。

……是不是听起来有点绕?没关系,看代码就是了

12.png

上图中首先创建了一个名为t的KtTest对象,然后通过t::func传给了show方法

show方法中的参数是一个名为funcM的参数名,类型为()->Unit

()->Unit表示一个返回空的方法。

如果不好理解,可以这么看

13.png

运行结果:

14.png

*注意:如果对象没有创建(new),那么不能直接传方法,至于为什么?对象都没有创建,虚拟机怎么知道该调用谁的方法。

5. 总结

  1. kotlin中,继承需要父类使用open关键字,子类实现则需要以override关键字,不能省略
  2. kotlin中,抽象类与java中几乎一样。
  3. kotlin中,接口与抽像类一样可以有方法实现,子类继承可以选择性覆写已经实现的方法
  4. kotlin中,如果子类的上级存在两个已经实现的相同方法可以通过super<泛型>.方法名指定使用上级的方法,但不是必须要写。
  5. kotlin中,继承与接口的实现都是用的:表达式,区分的方式就是(),也就是子类继承父类相当于创建了一个父类对象,然而接口则不需要。
  6. kotlin中,支持函数(方法)作为参数传递,使用::表达式
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342