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

Kotlin之扩展

作者头像
大话swift
发布2019-09-25 11:50:45
4450
发布2019-09-25 11:50:45
举报
文章被收录于专栏:大话swift大话swift

目前大多说的高级语言在对已有的class进行扩展大多采用继承或者装饰器的方式,但是这些方式大都会破坏原类,对整个项目来说是一种侵入式极强的方式……Kotlin在function这方面吸取了一些动态语言(OC)仿照姊妹篇swift的方式可以对已有的class进行方法扩展达到了可以在不重新已有类修改代码或者使用子类的方式对类进行功能的扩展……

声明一个扩展方法

对于一个方法可定是有接收者,因此在方法扩展需要添加class的声明啦,我们看如下代码:

代码语言:javascript
复制
class Animal{}
fun Animal.move() {
    
}

我们首先声明了一个class叫做Animal,然后扩展一个move的能力,那么怎么使用这个能力呢?

代码语言:javascript
复制
val animal = Animal()
 animal.move()

可以看出它与成员方法并没有什么不同之处。其实本质还是有区别的,我们对上栗进行修改,class内部添加一个move方法

代码语言:javascript
复制
class Animal {
    fun move() {

    }
}

fun Animal.move() {

}

这时候假如调用move的时候如何呢,使用的是扩展方法还是成员方法呢?

如果一个类定义有一个成员函数与一个扩展函数,而这两个函数又有相同的接收者类型、 相同的名字,并且都适用给定的参数,这种情况总是取成员函数

扩展为静态解析

扩展不是原有类进行修改来实现扩展的,它仅仅是可以通过类的实例化之后通过点语法调用的一个函数而非是类实例的一个成员方法。更确切的说它是根据代码声明处的那个类型来决定怎么调用分发的而不是由动态运行时所属的类型决定怎么分发的

上面的描述整体有点绕,但是整体就是说调用时有程序走到哪里爵溪成代码代码声明的是什么类型就通过这个类型去搜寻对应的类对应的方法扩展

我们修改代码如下:

代码语言:javascript
复制
open class Animal {
 
}
//子类
class Dog: Animal() {

}
//子类

class Duck : Animal() {

}
//扩展
fun Dog.move() {

}
//扩展
fun Duck.move() {

}
fun Animal.move() {

}

//调用
    var animal: Animal = Dog()
    animal.move()

当我们调用move时会调用哪个的move扩展呢?下面我们复盘一下

1 声明变量为Animal类型

2 动态实例化Dog实例

3 变量调用move

根据扩展的静态解析规则来说调用时回溯到变量声明之处为Animal因此调用Animal申明的扩展方法move

扩展属性

扩展属性与扩展方法类似

代码语言:javascript
复制
val <T> List<T>.lastIndex: Int
    get() = size - 1

扩展作用域

杜宇扩展要想挎包访问,需要在包内import扩展出的方法

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大话swift 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档