《Kotlin核心编程》阅读笔记
第七章 多态和扩展
Kotlin的扩展其实多态的一种表现形式。
多态的不同方式
多态是面向对象程序设计 的一个重要特性。当用一个子类继承一个父类的时候,这就是子类型多态(Subtype polymorphism)。另一种熟悉的多态是参数多态(Parametric polymorphism)。
子类型多态
用子类型替换超类型实例的行为,就是子类型多态。
参数多态
理解起来像是把参数抽成一个类型,类似泛型的感觉。
对第三方进行扩展
即扩展函数。
扩展属性和扩展方法的实现是运行在类的实例上,不会修改类本身。
特设多态和运算符重载
特设多态:一个多态函数是有多个不同的实现,依赖于其实参而调用相应版本。
operator : 将一个函数标记为重载一个操作符或者和实现一个约定。
data class Area(val value:Double)
operator fun Area.plus(that:Area):Area{
return Area(this.value+that.value)
}
fun main(){
println(Area(1.0)+Area(2.0))
}
还可以重载减法minus 、乘法times、除法div等
扩展:为别的类添加方法、属性
扩展与开放封闭原则
软件实体应该是可扩展,而不可修改的。
开放封闭原则
开放封闭原则(OCP:Open Closed Principle)是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化、降低耦合,而开放封闭原则正是对这一目标的最直接体现。其他的设计原则,很多时候是为了实现这一目标服务的,例如以替代原则实现最佳、正确的继承层次,就能保证不会违背开放封闭原则。
使用扩展函数、属性
fun MutableList<Int>.exchange(fromIndex:Int,toIndex:Int){
val tmp = this[fromIndex]
this[fromIndex] = this[toIndex]
this[toIndex] = tmp
}
这里扩展函数体里的this代表的是接收者类型的对象。
标准库中的扩展函数:run、let、also、takeIf
-
run
run方法的定义:public inline fun<T,R> T.run(block:T.() -> R):R = block()
run 是任何类型T的通用扩展函数,run中执行了一个返回值类型为R 的扩展函数block,最终返回扩展函数的结果。 -
let
定义:public inline fun <T,R> T.let (block:(T) -> R):R = block(this)
let 返回的是闭包里面的值。
data class Student(age:Int)
class Kot{
val student:Student? = getStu()
fun dealStu(){
val result = student?.let{
println(it.age)
it.age
}
}
}
- also
定义:
public inline fun <T> T.also(block:(T) -> Unit):T{
block(this)
return this
}
函数的返回值是该函数的接收者。
class Kot{
val student:Student? = getStu()
fun dealStu(){
val result = student?.also{ stu ->
this.age += stu.age
println(this.age)
println(stu.age)
this.age
}
}
}
- takeIf
如果我们不仅仅只想判断空,还想加入条件,这是let 可能显得有点不足。
定义:
public inline fun <T> T.takeIf(predicate :(T) -> Boolean):T? = if(predicate(this)) this else null
当接收器满足某些条件才会执行。
把之前的也写一下:
with 和 apply
with的定义:inline fun <T,R> with(receiver :T ,block:T.() -> R):R
with的第一个参数为接收者类型,然后通过第二个参数创建这个类型的block方法。
apply的定义:inline fun <T> T.apply(block:T.() -> Unit):T
看这些定义还是有点晕的。写代码时,在编译器的提示感觉会好点。