当前位置:网站首页>有趣的 Kotlin 0x09:Extensions are resolved statically
有趣的 Kotlin 0x09:Extensions are resolved statically
2022-07-28 15:42:00 【AndroidKt】
最近在 http://portal.kotlin-academy.com/#/ 上看到很多关于 Kotlin 的有趣的题目。个人觉得很适合 Kotlin 爱好者,感兴趣的小伙伴可自行查阅。
【有趣的 Kotlin 】系列记录自己对每一题的理解。
0x09:Extensions are resolved statically
open class C
class D: C()
fun C.foo() = "c"
fun D.foo() = "d"
fun printFoo(c: C) {
println(c.foo())
}
fun main(args: Array<String>) {
printFoo(D())
}
以上代码,运行结果是什么?可选项:
- Doesn’t Compile
- Rutime error
- "c"
- "d"
思考一下,记录下你心中的答案。
分析
基本情况

类
C是 类D的父类,且各自有一个名为foo的扩展函数。类C的扩展函数返回字符串 “c” , 类D的扩展函数返回字符串 “d”;定义了一个顶层函数
printFoo(),参数类型为C;main函数内调用printFoo函数,且传入参数为D的实例。
惯性思维
main() 函数中 printFoo() 传入参数为 D 对象,自然是调用 D 的扩展函数 D.foo() ,所以本题答案为——选项4:“d”。
这种分析对吗?
如果 Kotlin 扩展函数的本质是成员函数,这个分析是没有问题的,但是扩展函数的本质是成员函数吗?
Kotlin 扩展函数本质是什么?
遇事不明就举例
定义一个扩展函数,receiver 为 String。
fun String.suffix(suffix: String) = this + suffix
遇事不明反编译
- 字节码

- Decompile Java 代码

- Kotlin 扩展函数 在 Java 使用
public class Test {
public static void main(String[] args) {
// 两个参数且为类成员函数
String result =
Extensions_are_resolved_staticallyKt.suffix("Hello", " OpenCV or Android");
System.out.println(result);
}
}
综上, Kotlin 扩展函数的本质是静态函数,且 receiver 是字节码中对应静态函数的第一个参数。所以 Java 中调用 Kotlin 定义的扩展函数时,需要传入 receiver作为第一个参数。
解题
回到题目
fun printFoo(c: C) {
println(c.foo())
}
由于参数类型为 C,所以代码中 c.foo() 对应的是 fun C.foo() = "c" 编译成的静态函数。虽然运行时传入的是 D(),但是依然会被强转成 C 然后执行 fun C.foo() = "c" 对应的静态方法。所以,题中,正确答案为 :
选项 3 :"c"

延伸
我们给类 C 和 类 D 分别添加成员函数 foo()
package puzzlers
open class C {
open fun foo() = "cc" // 类 C 成员函数 foo
}
class D : C() {
override fun foo() = "dd" // 类 D 成员函数 foo
}
fun C.foo() = "c"
fun D.foo() = "d"
fun printFoo(c: C) {
println(c.foo())
}
fun main(args: Array<String>) {
printFoo(D())
}
运行结果又该为何 ?友情提示 member always win.
边栏推荐
- QML signal and handler event system
- Automatically pack compressed backup download and delete bat script commands
- 遭MQ连连干翻后的醒悟!含恨码出这份MQ手册助力秋招之旅
- Wei Jianjun couldn't catch up with Li Shufu by riding a BMW
- Curl returns blank or null without output. Solve the problem
- 一大早支付宝来短信说你中“奖”了?处理服务器挖矿病毒 - kthreaddi
- Sort 5-count sort
- El input limit can only input the specified number
- PHP mb_ Substr Chinese garbled code
- 500million users, four years earlier than wechat... This app, which has been in operation for 15 years, will be permanently discontinued
猜你喜欢

IM即时通讯开发优化提升连接成功率、速度等

Abaqus GUI界面解决中文乱码问题(插件中文乱码也适用)

优化Hypermesh脚本性能的几点建议

LwIP development | realize TCP server through socket

Two of C language programming!! Role of

About standard IO buffers

Several methods of HyperMesh running script files

排序2-冒泡排序与快速排序(递归加非递归讲解)

遭MQ连连干翻后的醒悟!含恨码出这份MQ手册助力秋招之旅

Fx3 development board and schematic diagram
随机推荐
SCI scientific paper writing Growth Camp (full version)
学会使用MySQL的Explain执行计划,SQL性能调优从此不再困难
PHP about problems such as memory overflow timeout caused by large amount of data exporting or traversing data
LwIP development | realize TCP server through socket
FX3开发板 及 原理图
遭MQ连连干翻后的醒悟!含恨码出这份MQ手册助力秋招之旅
Ansa secondary development - build ansa secondary development environment on Visual Studio code
Using pyqt to design gui in ABAQUS
排序1-插入排序与希尔排序
ANSYS二次开发 - MFC界面调用ADPL文件
Some suggestions on optimizing HyperMesh script performance
C language exception handling mechanism: jump function jump function setjmp/sigsetjmp and longjmp/siglongjmp
Record doc
后台弹出layer提示
Sort 3-select sort and merge sort (recursive implementation + non recursive implementation)
"Weilai Cup" 2022 Niuke summer multi school training camp 3 h.hacker sam+ segment tree /dp/ divide and conquer (without the largest sub segment and of the inspection interval)
PHP mb_substr 中文乱码
Qt学习之信号和槽机制
Early in the morning, pay Bora SMS to say that you won the "prize"? Dealing with server mining virus - kthreaddi
每一个账号对应所有密码,再每一个密码对应所有账号暴力破解代码怎么写?...