美文网首页
Kotlin-----方法进阶

Kotlin-----方法进阶

作者: 会写代码的小猿猴 | 来源:发表于2022-01-08 17:25 被阅读0次

在kotlin中我们将函数作为参数或者返回值的函数叫做高阶函数,也就是使用方法体作为参数的方法叫做高阶方法。

  • 函数作为参数

我们通过一个实战来了解它的定义
实战:需求-----实现一个可以对集合元素进行求和的高阶函数,并且每遍历一个元素都要有回调。

fun List<Int>.sum(callback:(Int) ->Unit):Int{
    var result=0
    for (v in this){
        result+=v
        callback(v)
    }
    return result
}

这个方法用到了扩展,直接使用List的扩展创建方法,在方法内部使用this关键字访问该集合,关于扩展可能有很多兄弟不清楚,所以我列出了它不用扩展的方法,如下:

fun test6(list: List<Int>,callback: (Int) -> Unit):Int{
    var result=0
    for (v in list){
        result+=v
        callback(v)
    }
    return result
}

方法中的第二个参数是一个回调,callback: (Int) -> Unit这句代码表示返回一个int型数据,Unit表示默认返回为空。再来看一下它的调用。

val list = listOf(1, 2, 3, 4)
  val sum = test6(list,{
        println(it)
    } )
    println(sum)

这里我分别打印了这个集合的每一项和所有元素的和,我们可以看到在第二个参数的地方我们实现了callback函数,所以test6方法的第二个参数是callback方法,callback方法等同于

fun callback(it:Int){
        println(it)
    }

这就是将函数作为参数的高阶函数。

  • 函数作为返回值

同样的先来做一个小实战
需求-----实现一个高阶函数,并且返回一个声明为(scale:Int)->Float的函数,返回的函数可以求取集合元素所有和的scale倍。
注:scale:Int)->Float的意思可以用lambda来理解:该函数接收一个scale的Int型参数,返回一个Float的参数。

fun test7(list: List<Int>): (scale: Int) -> Float {
    println("这是方法的第一层")
    return fun(scale): Float {
        var result = 0F
        for (v in list) {
            result += v * scale
        }
        return result
    }
}

调用:

  val list = listOf(1, 2, 3, 4)
    val result=test7(list)(2)
    println(result)

注意调用的格式就好了,第二个(2)是表示向返回的函数传递的参数,其实可以理解为它是一个两层函数,调用时第一个括号(list)表示向test7方法传递list参数,第二个括号(2)表示向test7的返回函数传递参数2.

  • 方法中的闭包(closure)

闭包可以理解为能够读取其他方法内部变量的方法,所以说闭包是将方法内部与方法外部连接起来的桥梁。
闭包的特性

  • 方法可以作为另一个方法的返回值或参数,还可以作为一个变量的值。
  • 方法可以嵌套定义,即在一个方法内部可以定义另一个方法。
    闭包的好处:
  • 加强模块化
  • 抽象
  • 灵活
  • 简化代码
    说再多也没用,来个实战。
    实战:
    ◆需求:实现一个testClosure方法 ,该方法要接收一个Int类型的v1参数,同时能够返回一个声明为(v2: Int, (Int)-> Unit)的函数,并且这个函数能够计算v1与v2的和。
fun testClosure(v1:Int):(v2:Int,(Int)->Unit)->Unit{
    return fun (v2:Int,printer:(Int)->Unit){
        printer(v1+v2)
    }
}

调用

testClosure(2)(3){
        println(it)
    }

这个例子有点复杂,要用心去理解一下,这个testClosure()接收一个参数v1,它的返回值类型是一个函数,我们暂时把它叫做f1,f1的构造是v2:Int,(Int)->Unit)这样的,表示f1接收两个参数,第一个参数是一个int型数据v2,第二个参数暂时叫做f2,f1没有返回值,f2是返回一个int型数据,后面加Unit让它暂时返回为空,最后一个Unit是表示整个testClosure()方法暂时返回为空。
调用时第一个参数2是传递给方法testClosure()的参数v1,第二哥参数3是传递给函数f1的参数v2,it表示f2返回的值。
上面这个例子是函数作为参数和返回值的一个复杂嵌套使用,要配合lambda表达式来理解。

  • Kotlin数据类的解构

这是一个解析数据的小技巧,刚好用到就在这里分享一下,用完你就知道kotlin有多好了。

data class Result(var message:String,var code:Int)
fun test0(){
    var result1=Result("成功",1)
    var (msg,code)=result1
    println("message:$msg  code:$code")
}

仅作为分享,不多解释,平时接收后台接口数据可以用这种方式反解拿到接口中的某项数据。

  • 方法的字面值

将方法定义为变量,可以作为变量去调用;

fun test11(){
    var temp: ((Int) -> Boolean)? =null
    temp={num ->(num>10)}
    println(temp(11))
}

仅作为学习记录,大家好好看前面的内容这里应该不难理解。

  • kotlin中的构造方法

kotlin在构造方法方面也比Java要方便许多,我们先来看最基本的构造方法怎么写:

class KotlinClass (name:String){
}

kotlin中类的构造方法可以直接在类的声明时创建参数,比如上面例子就是直接实现了类KotlinClass 的主构造方法,该构造方法接收一个String类型的参数name,那我们都知道类的构造方法可以有多个,怎么声明多个构造方法呢?
可以在类的内部声明多个构造方法,上面例子的叫做主构造方法,类中声明的都叫次构造方法,次构造方法在声明时都要调用主构造方法。

class KotlinClass (name:String){
    constructor(age:Int,name: String):this(name){
        println("name:$name")
    }
    constructor(age: Int,name: String,phone:Long):this(name){
        println("phone:$phone")
    }
}

如上所示,我们在类的内部定义了两个次构造方法,都通过this关键字调用了它的主构造方法。
下面是对每个构造方法的调用:

 /*调用类的主构造方法*/
    var name="zzp"
    KotlinClass(name)
    /*调用类的第一个次构造方法*/
    KotlinClass(20,"zzp")
    /*调用类的第二个次构造方法*/
    KotlinClass(20,"zzp",110)

kotlin的构造方法大致如上所示,接下来我说一点在开发中经常会用到的,上面的例子以主构造方法为例,我们可以在主构造方法传入一个name的字符串,假如我们需要在类里面的某个方法操作这个name,怎么拿到它呢?按照Java的办法也可以拿到,代码如下:

 var name1:String=""
    constructor(age: Int, name: String) : this(name) {
        name1=name
        println("name:$name")
    }

我们需要再定义一个变量name1,在构造方法中将构造方法的参数name赋值给name1,这样才能拿到构造方法的参数,kotlin还有一个更简单的方法,在构造方法参数列表就对该参数进行声明。

class KotlinClass(val name: String) {
    fun println(){
        println(name)
    }
}

在参数前面加了个val声明name,然后就可以直接在下面的方法体内直接调用name变量。这也算是一个小技巧了。当然不加var/val也是可以直接使用构造方法参数的,就要用到初始代码块init了

init {
        println(name)
    }

这样也是可以的,我们只需要把所有方法在init内部调用就可以了。

  • kotlin继承如何写子类构造方法

这个非常简单,只需要记住一点,子类的构造方法必须先调用父类构造方法,这点和Java是一样的,还不清楚继承的可以先看我的另一篇文章Java-----继承

open class Animal(val age: Int)
class Dog(age: Int) :Animal(age)

如上所示,kotlin继承使用冒号,在后面跟上父类构造方法就可以了。父类需要用open关键字修饰才能被继承,类似于Java的public。

扩展:kotlin继承子类如何重写父类构造方法、如何覆盖父类成员变量
open class Animal(val age: Int) {
    open var foot: Int = 0
    open fun printM(){
        println("动物有很多脚")
    }
}

class Dog(age: Int) : Animal(age) {
    //覆盖父类成员对象
    override var foot=4
    //重写父类成员方法
     override fun printM(){
        println("狗有四只脚")
     }
}

重写父类的成员方法或者覆盖它的成员变量都需要先使用open关键字将父类的成员变量和成员方法打开,在子类中重写时加上override修饰。

相关文章

网友评论

      本文标题:Kotlin-----方法进阶

      本文链接:https://www.haomeiwen.com/subject/gwmecrtx.html