open class AnimBase {
open fun test(a: Int, b: Int = 1, c: String = “666”) = println(“ a a ab$c”)
}
class AnimDog: AnimBase() {
override fun test(a: Int, b: Int, c: String) {
super.test(a, b, c)
}
//重写方法不允许为参数值指定默认值,无论这里 a 或者 b 都不行
//编译报错 An overriding function is not allowed to specify default values for its parameters
//override fun test(a: Int = 1, b: Int = 1, c: String) {
// super.test(a, b, c)
//}
}
/**
调用结果:
121666
*/
fun testRun() {
val anim = AnimDog()
anim.test(a = 12)
}
kotlin 中 lambada 表达式整体和 java 很像,但也有自己的特殊。kotlin lambada 表达式格式要求如下:
-
一个 lambada 表达式总是被一个花括号所包围。
-
其参数(如果存在)位于
->
之前,参数类型是可以省略掉的。 -
执行体位于
->
之后。
默认情况下,lambada 表达式中最后一个表达式的值会隐式作为该 lambada 表达式的返回值。我们可以通过全限定的语法来限定从 lambada 表达式返回值。如下案例:
//【工匠若水 加微信 yanbo373131686 联系我,关注微信公众号:码农每日一题 未经允许严禁转载 https://blog.csdn.net/yanbober】
//compute 是定义的一个 lambada 表达式参数
fun testLambada(i: Int = 1, j: Int = 1, compute: (x: Int, y: Int) -> Unit) {
compute(i, j)
}
fun callBack(a: Int, b: Int): Unit {
println(“a= a , b = a, b= a,b=b”)
}
/**
调用结果:
1 - 1 = 0
2 + 4 = 6
a=2, b=6
*/
fun testRun() {
testLambada { x, y -> println(“$x - $y = ${x - y}”) }
testLambada(2, 4) { x, y -> println(“$x + $y = ${x + y}”) }
testLambada(2, 6, ::callBack)
}
再来看一个例子:
fun test1(num: Int, exec: () -> Unit) {
exec()
}
fun test2(num: Int, exec: (i: Int) -> Unit) {
exec(num)
}
fun test3(num: Int, exec: (i: Int, j: Int) -> Unit) {
exec(num, 3)
}
fun main() {
test1(2) {
//这里没有 $it
println(“666”)
}
//当只有一个参数时此时会隐式传递 it 参数
test2(3) {
println(“777 $it”)
}
//多个参数时必须显式指定
test3(4) { _, _ ->
println(“888”)
}
}
一个方法中只允许一个有一个可变参数定义,且通常位于参数列表最后一个。如果可变参数不是最后一个参数,那么其后的参数都需要通过具名参数形式传递,如果其后的参数是函数类型,还可以在圆括号外传递 lambada 表达式来实现而不用指定具名。如下案例:
//【工匠若水 加微信 yanbo373131686 联系我,关注微信公众号:码农每日一题 未经允许严禁转载 https://blog.csdn.net/yanbober】
//可变参数定义使用 vararg
fun testArgs(vararg strs: String) {
println(strs.javaClass) //字符串数组类型
strs.forEach { println(it) }
}
/**
调用结果:
class [Ljava.lang.String;
666
777
class [Ljava.lang.String;
11
22
*/
fun testRun() {
testArgs(“666”, “777”)
println(“------------”)
val args1 = arrayOf(“11”, “22”)
//编译报错 Type mismatch. Required: String Found: kotlin.collections.ArrayList /* = java.util.ArrayList */
//testArgs(args1)
//使用分散运算符*才可以
testArgs(*args1)
}
kotlin 的函数还可以通过中缀符号来调用,需要满足如下三个条件:
-
是成员函数或者扩展函数。
-
拥有单个参数。
-
声明时使用 infix 关键字。
如下是一个案例:
class InfixT (private var age: Int) {
infix fun add(num: Int) = this.age + num
}
/**
调用结果:
24
33
*/
fun testRun() {
val test = InfixT(12)
//如下两种调用等价,常出现在 kotlin 底层库中
println(test.add(12)) //普通调用
println(test add 21) //中缀调用
}
内联提升调用效率,但是增大了字节码体积,其优缺点及机制原理同其他语言的内联函数等价。如下案例:
inline fun add(a: Int, b: Int) = a + b
关于内联函数原理其实很简单,建议直接 javap -c 去看下字节码区别就能理解优缺点了。
在一个函数参数中可以传递另一个函数作为参数,则这个函数就是高阶函数,经常使用 lambada 表达式达到这个目的,常见的 lambada 表达式定义:
//【工匠若水 加微信 yanbo373131686 联系我,关注微信公众号:码农每日一题 未经允许严禁转载 https://blog.csdn.net/yanbober】
//add变量是一个函数类型,其值等于一个 lambada 函数
val add: (Int, Int) -> Int = { a: Int, b: Int -> a + b }
//简写
val add: (Int, Int) -> Int = { a, b -> a + b }
//自动类型推断写法
val sub = { a: Int, b: Int -> a - b }
//print 变量也是一个 lambada 表达式,没有参数而已
val print = { println(“666”) }
//_ 表示是一个参数,但是参数在函数体中不会被用到
val mayNull: (Int, Int) -> Int? = { _, _ -> null }
//表示这个 lambada 表达式函数类型的变量可以为 null,这里赋值了 null
val functionMayNull: (Int, Int) -> Int)? = null
下面定义一个高阶函数及使用:
//高阶函数定义
fun funcHeight(a: Int, b: Int, calculate: (Int, Int) -> Int): Int {
return calculate(a, b)
}
/**
调用结果:
22
2
*/
fun testRun() {
val add = { a: Int, b: Int -> a + b }
println(funcHeight(12, 10, add))
println(funcHeight(12, 10) { x, y -> x - y })
}
kotlin 的匿名函数主要用在 lambada 表达式中。如下案例:
fun funcHeight(a: Int, b: Int, calculate: (Int, Int) -> Int): Int {
return calculate(a, b)
}
//编译报错,匿名函数不能定义在外部 Function declaration must have a name
//fun (x: Int, y: Int) = x + y
/**
调用结果:
7
7
*/
fun testRun() {
//匿名函数
fun (x: Int, y: Int) = x + y
//lambada表达式方式
var ret = funcHeight(3, 4, { x, y -> x + y })
println(ret)
//匿名函数用在 lambada 表达式中
ret = funcHeight(3, 4, fun (x, y): Int = x + y)
println(ret)
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
最后
都说三年是程序员的一个坎,能否晋升或者提高自己的核心竞争力,这几年就十分关键。
技术发展的这么快,从哪些方面开始学习,才能达到高级工程师水平,最后进阶到Android架构师/技术专家?我总结了这 5大块;
我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 PDF(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。
Java语言与原理;
大厂,小厂。Android面试先看你熟不熟悉Java语言
高级UI与自定义view;
自定义view,Android开发的基本功。
性能调优;
数据结构算法,设计模式。都是这里面的关键基础和重点需要熟练的。
NDK开发;
未来的方向,高薪必会。
前沿技术;
组件化,热升级,热修复,框架设计
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
我在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多
当然,想要深入学习并掌握这些能力,并不简单。关于如何学习,做程序员这一行什么工作强度大家都懂,但是不管工作多忙,每周也要雷打不动的抽出 2 小时用来学习。
不出半年,你就能看出变化!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
数据结构算法,设计模式。都是这里面的关键基础和重点需要熟练的。
[外链图片转存中…(img-qDyuzMWV-1712285046854)]
NDK开发;
未来的方向,高薪必会。
[外链图片转存中…(img-dq6fV0F5-1712285046855)]
前沿技术;
组件化,热升级,热修复,框架设计
[外链图片转存中…(img-Bs1olV2j-1712285046855)]
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
我在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多
当然,想要深入学习并掌握这些能力,并不简单。关于如何学习,做程序员这一行什么工作强度大家都懂,但是不管工作多忙,每周也要雷打不动的抽出 2 小时用来学习。
不出半年,你就能看出变化!