首页 > 其他分享 >【解密 Kotlin 扩展函数】扩展函数的底层原理(十八)

【解密 Kotlin 扩展函数】扩展函数的底层原理(十八)

时间:2024-09-23 19:22:14浏览次数:3  
标签:Java 函数 Kotlin Button 扩展 view View

导读大纲

1.1.1 从 Java 调用扩展函数

  1. 在编译器底层下,扩展函数是一种静态方法,它接受接收器对象作为第一个参数
    • 调用它不涉及创建适配器对象任何其他运行时开销
    • 这使得从 Java 使用扩展函数变得非常简单
      1. 调用静态方法传递接收器对象实例即可
    • 与其他顶级函数一样
      1. 包含该方法的 Java 类的名称声明该函数的文件名决定
      2. 关于顶级函数和顶级属性–传送门
    • <1> 比方说,lastChar扩展函数是在 StringUtil.kt 文件中声明的
      1. 那么在Java中调用时就需要使用"StringUtilKt"类名
      2. 关于如何使用JvmName注解修改类名–传送门
/* Java */
char c = StringUtilKt.lastChar("Java");    // <1>
  1. 该扩展函数被声明为顶级函数,因此编译为静态方法
    • <1> 可以从 Java 中静态导入 lastChar 方法
      1. 从而简化使用, 只需 lastChar(“Java”) 即可
      2. 注意使用的导入方式"import static xxx"
import static strings.StringFunctions.lastChar;   // <1>
public class Example {
    public static void main(String[] args){
        System.out.println(lastChar("Java"));       // <1>
    }
}
  1. 扩展函数的静态特性还意味着子类中不能重载扩展函数

1.1.2 扩展函数无法重载

  1. 在 Kotlin 中,方法重载与成员函数一样有效,但不能重载扩展函数
    • <1> 假设有两个类: View 和 Button
      1. Button 是 View 的子类,它重载父类中的 click 函数
    • <2> 要实现这一点,可以使用 open 修饰符标记View和click, 以允许重载
      1. 使用 override 修饰符在子类中提供一个实现
open class View {
    open fun click() = println("View clicked")       // <2>
}
class Button: View() {              // <1>
    override fun click() = println("Button clicked") // <2>
}
  1. 如果你声明一个 View 类型的变量
    • <1> 那么你就可以在该变量中存储 Button 类型的值
      1. 因为 Button 是 View 的子类型
    • <2> 如果在该变量上调用常规方法(如 click)
      1. 该方法在 Button 类中被重载,则将使用 Button 类的重载实现
fun main() {
    val view: View = Button()            // <1>
    view.click()                         // <2>
    // Button clicked                     
}
  1. 但对于扩展函数来说,情况并非如此
    • 扩展函数不是类的一部分,它们是在类的外部声明
    • 比如, 在 View 和 Button 类之外
      1. 定义 View.showOff() 和 Button.showOff() 扩展函数
        title
    • 即使可以为基类及其子类定义具有相同名称和参数类型的扩展函数
    • <1> 但调用的函数取决于变量声明的静态类型, 该类型在编译时确定
      1. 在对 view 变量调用 showOff 时,即使值的实际类型是 Button
        • 也会调用View类型的showOff方法,因为view变量的编译时类型是"View"
fun View.showOff() = println("I'm a view!")
fun Button.showOff() = println("I'm a button!")
fun main() {
    val view: View = Button()
    view.showOff()                      // <1>
    // I'm a view!
}
  1. 回忆一下上面所说的扩展函数在 Java 中被编译为静态函数
    • 接收器对象是第一个参数, Java 也会以同样的方式调用指定类型的扩展函数
/* Java */
class Demo {
    public static void main(String[] args) {
        View view = new Button();
        ExtensionsKt.showOff(view);
        // I'm a view!
    }
}
  1. 综上所述,如果类中的成员函数与扩展函数的签名相同,则成员函数总是优先
    • 集成开发环境也会警告您, 扩展函数已被成员函数覆盖

标签:Java,函数,Kotlin,Button,扩展,view,View
From: https://blog.csdn.net/qq_36154755/article/details/142447565

相关文章

  • `std::optional` 函数返回值
    std::optional是C++17中引入的一个模板类,用于表示一个值可能存在也可能不存在的情况。它可以存储一个值,或者表示没有值的状态,类似于其他编程语言中的“可选”类型。std::optional主要特性:值的存在性:可以使用has_value()方法检查std::optional是否包含一个有效的值。访......
  • LeCun谢赛宁首发全新视觉多模态模型,等效1000张A100干翻GPT-4V,AI视频长度扩展调优技术:E
    LeCun谢赛宁首发全新视觉多模态模型,等效1000张A100干翻GPT-4V,AI视频长度扩展调优技术:ExVideo帮你轻松生成更长、更优质的视频,EVTexture:提升视频分辨率的新方法!利用AI将模糊视频变清晰!近日,LeCun和谢赛宁等大佬,共同提出了这一种全新的SOTAMLLM——Cambrian-1。开创了以视觉为中心的......
  • 欧拉函数φ
    欧拉函数欧拉函数,即\(\varphi(n)\),表示的是小于等于\(n\)和\(n\)互质的数的个数,详细定义看wiki。欧拉函数其实就是容斥原理的应用,举个例子:如\(n=6\),\(1,2,3,4,5,6\)是整个序列,我们将\(6\)的质因子\(2\),\(3\)取出,减去小于等于\(6\)的\(2\)的倍数和\(3\)的倍数,......
  • 用递归函数实现汉诺塔游戏
    1.是什么        汉诺塔(HanoiTower)是一个经典的递归问题,描述了将一个由三根柱子组成的塔上的n个大小不一的圆盘从一个柱子移动到另一个柱子上的过程。每次移动只能移动一个圆盘,并且大圆盘不能放在小圆盘上面。思路分析:        当圆盘总数是5时,要将最底层......
  • AWTK fscript 中的 value 扩展函数
    fscript是AWTK内置的脚本引擎,开发者可以在UIXML文件中直接嵌入fscript脚本,提高开发效率。本文介绍一下fscript中的**value扩展函数**value扩展函数value相关的辅助函数。1.value_is_valid判断value是否有效。原型value_is_valid(v)=>bool示例vara=object_c......
  • AWTK fscript 中的 CRC函数
    fscript是AWTK内置的脚本引擎,开发者可以在UIXML文件中直接嵌入fscript脚本,提高开发效率。本文介绍一下fscript中的**CRC函数**CRC函数Cyclicredundancycheck1.crc16crc16函数。原型crc16(str)=>uint16_tcrc16(data,size)=>uint16_tcrc16(binary)=>uint16......
  • 7-41 PAT排名汇总 (25 分)(详解 思路 重写sort函数)兄弟们冲呀呀呀呀呀呀呀
    二:思路===================================================================利用结构体存储学号成绩总排名考点号本考点的排名;然后在输入的时候要记得将j设置成一个变量,这样就能挨个把所有的值都输入到结构体数组当中。再然后就是,向结构体里的变量进行赋值。三:上码......
  • fastapi-events fastapi 异步事件分发处理扩展
    fastapi-eventsfastapi异步事件分发处理扩展,提供了本地,以及远程消息处理能力,同时包含了一些内置的handler,对于自定义handler也是比较灵活的参考使用app.pyfromfastapiimportFastAPIfromfastapi.requestsimportRequestfromfastapi.responsesimportJSONResponsefrom......
  • [oeasy]python035_根据序号得到字符_chr函数_字符_character_
    字符(character)回忆上次内容上次了解了ord函数ord的意思是ordinal(序号)ord函数可以根据字符得到序号那么可以反过来吗?根据序号得到字符可以吗?......
  • swap分区扩展
    1.查看当前swap分区情况 2.使用dd创建一个4g大小的swap文件 3.将这个swap文件变成swap分区格式 4.启动交换分区,建议将swap文件权限设置为0600 5.检验 6.配置持久化,编辑/etc/fstab文件/home/swapswapswapdefaults00附删除分区步骤:1.swapoff /home/sw......