Kotlin Primer · 第一章 · 基础语法与面向对象思想

简介: Kotlin Primer · 第一章 · 基础语法与面向对象思想

image.png

改不完的 Bug,写不完的矫情。公众号 小木箱成长营 现在专注移动基础平台开发 ,涵盖音视频, APM和信息安全等各个知识领域;只做全网最 Geek 的公众号,欢迎您的关注!精彩内容不容错过~

一. kotlin简介

Kotlin 拥有强大的生态,因为Kotlin是一门跑在Java虚拟机上的函数式语言,完全符合JVM的设计规范,如: 类型擦除,装箱和拆箱等等。所以也可以像Java一样支持 Android原生环境开发,服务端,甚至大前端方向。那么Kotlin和Java有什么共同点呢?

二. kotlin和java8的相同点

kotlin和java8的相同点我总结了三个,第一个是: 它们都是面向对象和函数式编程语言,第二个是: 它们都是强类型静态语言,最后一个就是它们都符合JVM设计规范

image.png

三. kotlin和java8的不同点

kotlin和java8的不同挺多的,我简单的归纳了一下:

  1. Kotlin可以用操作符简洁的判空
  2. Kotlin 不需要 findViewById
  3. Kotlin 默认给你写好 setter 和 getter方法了
  4. Kotlin 去掉了 static 关键字
  5. Kotlin 进行 自动强制类型转换
  6. Kotlin 省去了 类型推断
  7. Kotlin 不支持类型检查
  8. Kotlin 有协程支持
  9. image.png

四. kotlin 和 java 互转

4.1 kotlin 转 java

image.png

image.png

4.2 java 转 kotlin

image.png

查看Kotlin字节码

image.png

五. Kotlin 基础语法

5.1 kotlin方法

5.1.1 kotlin方法声明

Kotlin 定义方式比较简单,括号中是参数,格式: "函数名(参数名称: 参数): 返回类型",返回类型定义在括号外 如:T

    fun <T> reflectField(instance: Any?, name: String): T? {
        if (instance == null) return null
        try {
            val field = instance.javaClass.getDeclaredField(name)
            field.isAccessible = true
            return field.get(instance) as T
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }
5.1.2 kotlin方法调用

image.png

5.1.3 kotlin方法自动传参

Kotlin 可以在 构造方法或者相关函数大括号里面设置默认参数,这样传参就可以使用默认参数了,我们具体看看怎么使用的吧

image.png

第二个参数可以省略,此时会使用默认值

image.png

不省略时跟Java无异

image.png

5.1.4 kotlin named argument

named argument 的中文含义是 可以根据 参数名 进行传递参数,传参顺序不需要严格按照函数定义顺序,这样就可以避免参数误传的问题了

image.png

5.2 kotlin 变量和常量

varible(变量) 通过 var 关键字来声明,格式为 var 变量名[:类型] = [初始值]

    private var mConfig = RabbitConfig()
    lateinit var application: Application
    private var isInit = false
  • val 声明的变量是只读变量,它的引用不可更改,事实上我们依然可以更改其中引用对象的可变成员
  • const 相当于 java里面的 final,表示一旦初始化便立即被主内存看到,不能被二次赋值

当然 kotlin 也有自动拆箱和装箱将Int翻译成Java的int或Integer以提高性能

    private var Int = 8

Kotlin 会自动给属性加上 setter 和 getter 方法

class RabbitConfig(
    var enable: Boolean = true,
    var enableLog: Boolean = true,
    @Transient var uiConfig: RabbitUiConfig = RabbitUiConfig(),
    var storageConfig: RabbitStorageConfig = RabbitStorageConfig(),
    var monitorConfig: RabbitMonitorConfig = RabbitMonitorConfig(),
    var reportConfig: RabbitReportConfig = RabbitReportConfig()
)

用Show Kotlin Bytecode 翻译一下结果如下:

image.png

如果想重写 set() 或 get() 方法 可以这么做

data class RabbitConfig(
    var enable: Boolean = true,
    var enableLog: Boolean = true,
    @Transient var uiConfig: RabbitUiConfig = RabbitUiConfig(),
    var storageConfig: RabbitStorageConfig = RabbitStorageConfig(),
    var monitorConfig: RabbitMonitorConfig = RabbitMonitorConfig(),
    var reportConfig: RabbitReportConfig = RabbitReportConfig()
) {
    var age: Int = 10
        set(value) {
            println("setter $value")
            field = value
        }
    val createTimeShow: () -> String
        get() = { this.toString() }
}

5.3 kotlin null 判断

以上声明的变量皆为非空变量,即不允许为空值。如果需要声明一个变量可为空,仅需在变量类型后面加上?

val n: String?=null

声明一个变量可为空,仅需在变量类型后面加上?

// 在使用n的时候,由于n可能为null,直接使用编译器会报错
n.length  
// 正确的使用方式是,在使用前,做判空处理
// 如果变量为空,只需在变量类型后面加上?,这样就不会访问length属性了
n?.length  
// 如果确定一个可空变量不为空
// 可以加!!告诉编译器它不为空
n!!.length  

5.4 kotlin 字符串模板

val i=10
val s="i=$i"//求值结果为:“i=10”
val s="adb"
val str="$s.length is ${s.length}"//执行结果为“adb.length is 3” 

5.5 kotlin 双冒号操作符

双冒号操作符 表示把一个方法(变量)当做一个参数,传递到另一个方法(变量)中进行使用,和Java8类似

   /**
    * 把功能的名字转换为对应存储数据对象
    * */
   fun nameToInfoClass(name: String): Class<*> {
       return when (name) {
           RabbitMonitorProtocol.BLOCK.name -> RabbitBlockFrameInfo::class.java
           RabbitMonitorProtocol.APP_SPEED.name -> RabbitAppStartSpeedInfo::class.java
           RabbitMonitorProtocol.FPS.name -> RabbitFPSInfo::class.java
           RabbitMonitorProtocol.MEMORY.name -> RabbitMemoryInfo::class.java
           RabbitMonitorProtocol.EXCEPTION.name -> RabbitExceptionInfo::class.java
           RabbitMonitorProtocol.NET.name -> RabbitHttpLogInfo::class.java
           RabbitMonitorProtocol.SLOW_METHOD.name -> RabbitSlowMethodInfo::class.java
           RabbitMonitorProtocol.BLOCK_CALL.name -> RabbitBlockFrameInfo::class.java
           RabbitMonitorProtocol.GLOBAL_MONITOR.name -> RabbitAppPerformanceInfo::class.java
           RabbitMonitorProtocol.ANR.name -> RabbitAnrInfo::class.java
           else -> RabbitFPSInfo::class.java
       }
   }

5.6 kotlin 匿名函数

kotlin 正常函数

//---------------------案例一--------------------------
a(fun b(param: Int): String {
  return param.toString()
});
val d = fun b(param: Int): String {
  return param.toString()
}
//---------------------案例二--------------------------
view.setOnClickListener(new OnClickListener() {
  @Override
  void onClick(View v) {
    switchToNextPage();
  }
});

kotlin 匿名函数

//-----------------------案例一------------------------
a(fun(param: Int): String {
  return param.toString()
});
val d = fun(param: Int): String {
  return param.toString()
}
//-----------------------案例二------------------------
fun setOnClickListener(onClick: (View) -> Unit) {
  this.onClick = onClick
}
view.setOnClickListener(fun(v: View): Unit) {
  switchToNextPage()
})

5.7 kotlin lambda 语法糖

view.setOnClickListener() { v: View ->
  switchToNextPage()
}
//-----------------------------------------------
view.setOnClickListener { v: View ->
  switchToNextPage()
}
//-----------------------------------------------
mSimpleListRv.setOnClickListener {
            startActivity(Intent(this, SimpleListActivity::class.java))
        }
//-----------------------------------------------
view.setOnClickListener {
  switchToNextPage()
  it.setVisibility(GONE)
}

5.8 kotlin 表达式

5.8.1 kotlin for循环 和 范围 表达式

5.8.1.1 kotlin for循环
// -----------------------正序遍历-----------------------
for (index in 1..100){
            print(index)
        }
5.8.1.2 范围 表达式
// -----------------------倒序遍历-----------------------
for (index in 100 downTo 1){
            print(index)
        }
// -----------------------不使用1作为遍历的步长-----------------------
 for (index in 1..100 step 2){
            print(index)//会输出1..3..5......
        }
// -----------------------创建一个不包含末尾元素的区间-----------------------
for (index in 1 until 10){
            println(index)//输出1..9
        }
// -----------------------遍历一个数组/列表,想同时取出下标和元素-----------------------
val array = arrayOf("a", "b", "c")
        for ((index,e) in array.withIndex()){
            println("下标=$index----元素=$e")
        }
        // -----------------------遍历一个数组/列表,只取出下标-----------------------
        val array = arrayOf("a", "b", "c")
        for (index in array.indices){
            println("index=$index")//输出0,1,2
        }
        // -----------------------遍历取元素-----------------------
        val array = arrayOf("a", "b", "c")
        for (element in array){
            println("element=$element")//输出a,b,c
        }

5.8.2 kotlin 枚举和 when 表达式

5.8.2.1 kotlin 枚举

Kotlin中,枚举类型以类的形式存在,因此叫做枚举类,详细代码如下:

enum class Color {
    RED, GREEN, BLUE
}
//---------------使用-------------------
var color: Color = Color.BLUE
var color2 = Color.GREEN
// 比较两个枚举类型变量
var bool: Boolean = color == color2
//---------------为枚举值指定数值-------------------
enum class Direction private constructor(var value: Int) {
    NORTH(1), WEST(2), EAST(3), SOUTH(4)
}
5.8.2.2 kotlin when 表达式

when 表达式 可以支持自动转型(Auto-casting),详细代码如下:

when (view) {
     is TextView -> toast(view.text)
     is RecyclerView -> toast("Item count = ${view.adapter.itemCount}")
     is SearchView -> toast("Current query: ${view.query}")
     else -> toast("View type not supported")
}

5.8.3 kotlin 中缀表达式

kotlin 中缀表达式只有一个参数,且用infix修饰的函数,这就是我们所说的自定义运算符的中缀表达式,详细代码如下:

// 书
class Book{
   // 传入任意类型,返回一个Boolean类型的参数
    infix fun on(any: Any): Boolean{
        return true
    }
}
// 桌子
class Desk
fun main(args: Array<String>) {
    if(Book() on Desk()){
        println("书在桌上")
    }
}

5.8.3 kotlin 复合表达式

5.8.3.1 '?.'

image.png

?.表示,如果foo这时候是一个空的,则返回null,否则就返回foo.bar(),详细代码如下:

if (foo != null){
   return foo.bar()
}else{
   return null
}
5.8.3.2 '?:'

image.png

?: 作用是当数据非空时,直接返回数据,而当数据为空时,返回合并到的数据。利用该运算符,可以很容易的把可空类型转换为非空类型,详细代码如下:

 if(foo!=null)
{
    foo
}
else
{
    bar
}
foo?.length?:-1
5.8.3.3 '!!'

image.png

Kotlin 中 !! 表示非空断言运算符,详细代码如下:

if(foo!=null)
{
   foo
}else
{
   return NullPointerException
} 
5.8.3.4 'as?'

image.png

Kotlin 可以使用安全转换操作符as?,它可以在失败时返回null,详细代码如下:

foo as? type
if(foo is Stype)
{
    foo as Type
}else
{
    null
}
5.8.3.5 '?'

image.png

?表示可空类型与非空类型,Kotlin 的类型系统旨在消除来自代码空引用的危险,详细代码如下:

foo?
var foo?="abc"
foo=null
// 编译成功 foo可为空
var foo="abc"
foo=null
// 编译失败 foo不可以为空

六. Kotlin 面向对象

6.1 kotlin 继承和构造

kotlin中继承全部使用“:”,不区分extend或implement,但是有几个规则需要注意一下:

image.png

image.png

image.png

6.2 kotlin 类

6.2.2 kotlin object 类

object 全局声明的对象只有一个,所以他是天生的单例模型

image.png

6.2.2 kotlin data 类

在Kotlin里面声明一个data类需要满足以下条件:

  1. data类必须要有一个构造方法,且包含至少一个参数
  2. 该data类构造参数强制使用 val 或 var 进行声明
  3. data class 之前没有 abstract , open 或 inner 进行修饰

image.png

6.2.3 kotlin 内部类

image.png

6.3 kotlin 接口

image.png

6.4 kotlin 伴生对象

image.png

6.5 kotlin 修饰符

6.5.1 限制修饰符

  • val 翻译成字节码就是 final

image.png

private

image.png

  • internal

image.png

  • by

Kotlin 中 by 关键字用来简化实现代理 (委托) 模式,不仅可以类代理,还可以代理类属性, 监听属性变化

image.png

6.5.2 可见修饰符

嵌套类的用法: 如果要在 Kotlin 中嵌套一个类,需要在该内部类加 inner修饰

//嵌套类属于静态类和外部类没任何关系
fun main(args : Array<String>){ 
    var ot = OutClass().innerClass()
    ot.hello()
}
class OutClass{
    var name ="李武"
    //inner表示内部类
    inner class innerClass{
        var name = "张三"
        fun hello(){
            println("你好$name")
                        //内部类使用this,访问外部类的变量
            println("你好${this@OutClass.name}")  
        }
    }
}

七. 总结

本文先从kotlin概念带大家进入kotlin语言,然后说了一下kotlin和java8的异同以及相互转换方式,最后对Kotlin基础语法进行一一阐述,如: kotlin 方法和变量使用,kotlin字符串模板, lambada表达式,以及各种表达式的实际运用。好了今天的kotlin就说到这里了,如果大家对此有什么疑问欢迎到评论区留言~






















相关文章
|
1月前
|
Java 物联网 Kotlin
Kotlin - 面向对象之抽象类与接口
Kotlin - 面向对象之抽象类与接口
|
2月前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
本系列教程笔记详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。若需快速学习Kotlin,建议查看“简洁”系列教程。本期重点介绍了Kotlin与Java的共存方式,包括属性、单例对象、默认参数方法、包方法、扩展方法以及内部类和成员的互操作性。通过这些内容,帮助你在项目中更好地结合使用这两种语言。
53 1
|
25天前
|
Java Kotlin
Kotlin教程笔记(12) - 面向对象之继承与实现
Kotlin教程笔记(12) - 面向对象之继承与实现
32 4
|
25天前
|
Java 物联网 Kotlin
Kotlin教程笔记(11) - 面向对象之抽象类与接口
Kotlin教程笔记(11) - 面向对象之抽象类与接口
24 2
|
1月前
|
Java 物联网 Kotlin
Kotlin教程笔记(11) - 面向对象之抽象类与接口
Kotlin教程笔记(11) - 面向对象之抽象类与接口
31 6
|
1月前
|
Java Kotlin
Kotlin - 面向对象之继承与实现
Kotlin - 面向对象之继承与实现
32 4
|
1月前
|
Java Kotlin
Kotlin教程笔记(12) - 面向对象之继承与实现
Kotlin教程笔记(12) - 面向对象之继承与实现
76 9
|
1月前
|
Java 物联网 Kotlin
Kotlin教程笔记(11) - 面向对象之抽象类与接口
Kotlin教程笔记(11) - 面向对象之抽象类与接口
66 9
|
1月前
|
Java 物联网 Kotlin
Kotlin - 面向对象之抽象类与接口
Kotlin - 面向对象之抽象类与接口
52 5
|
1月前
|
Java 物联网 Kotlin
Kotlin - 面向对象之抽象类与接口
Kotlin - 面向对象之抽象类与接口
22 5