前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >最强总结 | 带你快速搞定kotlin开发(上篇)

最强总结 | 带你快速搞定kotlin开发(上篇)

作者头像
吴延宝
发布2020-11-25 11:27:06
5200
发布2020-11-25 11:27:06
举报

1.1 函数:

fun sum(a: Int, b: Int): Int { 
    return a + b
}  
// 对于只有一行的函数,kotlin可以这么简写,爽不?
fun sum(a:Int, b:Int): Int = a + b

可以看到函数的声明是通过fun关键字的,函数的参数类型和参数名的位置跟Java是相反的,中间使用 : 分隔,函数的返回类型是放在最后的,当然也是使用 : 进行分割的,如果没有返回值的时候可以省略或者使用Unit,相当于Java的void

1.2 变量:

var age:Int = 18
val name:String = "Kotlin"
val person = Person()

使用var来声明可读可写变量,使用val来声明只读变量(引用不可变)。 val可以理解为Java中的属性声明加上了final关键字(将kotlin的字节码反编译成Java一看就知道了),其实kotlin是更倾向于推荐使用val来声明变量,这是一种防御性的编码思维模式,目的是减少程序出错或者变的更加安全。 可以看到实例化Person对象时,并没有声明变量类型,这就是Kotlin的“类型推断”,会自动推断出是Person类型的变量,而且是不需要Java中的new关键字的。

1.3 继承和实现接口

class MyActivity: Activity(), View.OnClickListener {
// 省略
}

一看就懂,不用多说吧。注意加上(),如果你的kotlin类能够被继承,需要使用open关键字,因为默认是final的:

open class Person {
    constructor(age: Int)
    var age: Int = 0
}
// 当你的构造函数调用父类的构造函数时,要去掉Person后面的()
class Man: Person {
    // 使用super调用父类的构造器
    constructor(age: Int): super(age)
}

1.4 空安全设计

// 不可空类型
val person: Person

// 可空类型
val person2: Person?

那么对于可空类型的变量在调用时可以选择使用:

val person: Person? = null
// 安全调用
person?.age = 18
// 强行调用
person!!.name = "kotlin"

使用调用符,就算person是null的也不会出现空指针了,相当于Java中的判空了。当然如果你能确认person不会为空,可以使用!!强行调用符

1.5 lateinit关键字

lateinit var person: Person
person = Person()

我们总有场景在声明的时候不知道赋什么值,在后面才去赋值的场景,那么就可以使用lateinit关键字。但是只能在以下场景下使用:

  • var声明的变量
  • lateinit修饰的变量不可空、不能是基本数据类型、不能有初始值
  • 构造器中初始化的变量不需要使用lateinit关键字

1.6 类型判断

if(p is Person) {
    p.age = 20
}
val man: Man = Person()
val per: Person = man as Person

is关键字类似于Java中的instanceof,判断是否是什么类型,判断不是什么类型可用!is,可以看到kotlin有个小优化,就是p在条件成立时,不需要再强转了,直接被认为是Person的类型,进而可以使用Person的API。当你真的需要强转时可以使用asas?关键字,带?的在强转失败时并不会抛异常,而是返回一个null值

1.7 获取class对象

// Person.kt
Person::class
// Man.java
Man::class.java

区别于Java,kotlin要兼容Java,所以获取Java的class和kotlin的class略有不同,kotlin的class使用::class,而在kotlin中获取Java的class可以使用::class.java

1.8 setter和getter

class Person {
    var age: Int? = null
}
// 等价于
class Person {
    var age: Int? = null
        get() {
            return field
        }
        set(value) {
            field = value
        }
}

kotlin在声明非private的属性时,会默认生成对应的公开的set和get方法,当你在Java中访问时必须:

Person p = new Person();
p.setAge(20);

不过如果你就要直接访问age属性也是可以的,使用@JvmField注解:

// kotlin
class Person: Any {
    // kotlin构造函数使用constructor关键字
    constructor()
    // 加上这个注解,编译器只会生成一个public的属性,而不生成set和get方法
    @JvmField var age: Int = 19
}
// java
public class Test {
    private void some() {
        Person p = new Person();
        p.age = 20;
    }
}

1.9 数组

open class Person {
    constructor(age: Int)
    var age: Int = 0

    fun test() {
         // 会有装箱拆箱的操作,会影响性能
        val ages = arrayOf(14, 15, 16)
        // 基本数据类型使用对应的函数,比如intArrayOf()函数避免拆装箱的过程
        val ages2 = intArrayOf(14, 15, 16)
    }
}

可以使用arrayOf()来创建数组。对于基本数据类型优先使用对应的函数进行创建。

1.10 静态函数和属性

// 方法在类的外面【包级函数】或者叫【顶层函数】
fun getSomething(): Int {
    return 0
}

class Person {}

// 在Java中使用类名+Kt后缀直接访问
PersonKt.getSomething();

// 在kotlin文件中调用更加方便,只需要导包,不需要加类名
// 但是这种方式并不有利于阅读,会和类中的函数搞混淆
getSomething()

可以看到我们可以直接在文件里面声明函数,然后通过类名+Kt的方式直接调用。这种叫包级函数

object Person {
    fun getSomething(): Int {
           return 0
    }
}

// kotlin中调用
Person.getSomething()
// java中调用
Person.INSTANCE.getSomething();

其实使用object创建类的时候,默认会生成一个单例对象,当我们使用类名来直接调用的时候,其实是通过默认的单例对象进行调用的。本质上和我们java中的静态方法还是不同的。

class Person {
    companion object {
        fun getSomething(): Int {
            return 0
        }
    }
}

// kotlin
Person.getSomething()
// java,好麻烦,但是可以使用注解@JvmStatic来让编译器编译成静态的
Person.Companion.getSomething();
// java 使用注解后就可以在Java中直接调用了
Person.getSomething();

使用companion object(伴生对象)的方式相当于有一个内部类的单例对象,这些通过kotlin的字节码反编译成Java文件就可以看出来。看起来比直接使用static关键字麻烦多了,那kotlin为啥要去掉static这个关键字呢?那得问当初设计kotlin语言的人了,从面向对象的角度来说,这么设计的确更符合万物皆对象的理念,因为static只跟类有关,而不是和对象有关。

所以,我们可以看出来使用object貌似和创建默认对象有关系,不错,比如匿名内部类(本质上就是创建一个对象)

    var view = window.decorView
    fun test() {
        view.setOnClickListener (object : View.OnClickListener{
            override fun onClick(v: View?) {

            }
        })
    }
    // 当然可以简写成下面这样
    fun test() {
        view.setOnClickListener {

        }
    }    

1.11 小技巧

可以使用 ${} 来做字符串模板:

val age = 18
val info = "我是一个${age}岁的帅哥"

支持多行字符串,使用三个引号"""

    val info = """
        hhahha
        jaa
        sdfjdkjs
        jsafjs
    """.trimIndent()

判断数据范围和switch的使用:

// 如果年龄在10到30(包括30)
if(age in 10..30)
// 使用when取代Java中的switch,并且是支持表达式的
    when(age) {
        18->{

        }
        19->{

        }
        in 20..30-> {
        }
    }

在 Java 中通过 「 类名.this 例如 Outer.this 」 获取目标类引用 在 Kotlin中通过「this@类名 例如this@Outer」获取目标类引用

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT烂笔头 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档