kotlin 初识 | 青训营笔记

158 阅读7分钟

这是我参与「第四届青训营 」笔记创作活动的第6天

本文参考自 郭神的 《第一行代码》第三版

Kotlin是由 JetBrains 公司开发与设计的,2017 年Google 宣布Kotlin正式成为Android 一级开发语言。

kotlin 兼容java的工作原理 是因为 java虚拟机并不是和java代码打交道,而是和编译后的class文件打交道,Java 虚拟机不关心class 文件是 从Java 编译来的,还是从Kotlin编译来的,只要是符合规格的class 文件,它都能识别。也正是 这个原因,JetBrains 才能以一个第三方公司的身份设计出一门用来开发Android 应用程序的编 程语言。

kotlin语法简洁,语法更加高级

两种main方法的使用

package com.yxl.kotlin
​
class helloWorld {
   companion object{//静态块
      @JvmStatic
      fun main(args:Array<String>){
      println("hello kotlin")
      }
   }
}
​
fun main(){
   println("hello world")
}

在 kotlin中变量默认的修饰符时 public

变量

kotlin 与java的变量声明方式有很大的不同

需要在最先 声明var(非final) 与val(final) 然后再声明 变量的具体类型

格式

val 变量名 :类型=....

并且kotlin有类型推导机制,有时候并不需要自己指明具体的类型

Kotlin完全抛弃了Java 中的 基本数据类型,全部使用了对象数据类型。在Java 中int是关键字,而在Kotlin中Int变成了一 个类,它拥有自己的方法和继承结构。

函数

fun methodName(param1: Int, param2: Int): Float { 
 return 0f//返回类型为Float 
} 

Unit 是 代表没有返回值类型 (可以省略不写)

在形式参数的传递 中需要注意的是 可空变量 不能传递给不可空变量

函数的默认参数

在定义一个函数时可以给任意参数设定一个默认值,这样调用此函数时就不会强制要求为此方法传值

fun printParams(num: Int = 100, str: String) { 
 println("num is $num , str is $str") 
} 

当默认参数为第一个时,需要用显示参数指定的方式来传递

fun main() { 
 printParams(str = "world") 
} 

if语句

if语句可以和java有相同的用法,但是有更强大的特性

在kt中if语句可以有返回值语句中每个条件的最后一行代码即为返回值

fun largerNum1(num1: Int,num2: Int): Int {
   val value=if (num1>num2){
      num1
   }else{
      num2
   }
   return value
}

当函数只有一行代码时可以直接省略函数的主体部分,不用return,直接用等于号连接

这时是一种kt的语法糖

fun largerNum2(num1: Int,num2: Int)=if (num1>num2){
   num1
}else{
   num2
}

when语句

when语句类似于java的switch语句,但是他有更强大的功能

fun getScore(name:String)=when(name){
   "Tom"->86
   "JIm"->56
   "xiao"->66
   else ->0
}

when和if语句一样也是有返回值的

条件格式

匹配值 ->{ 执行逻辑} 当执行逻辑只有一行代码时{ }可以省略

is 关键字

is 相当于 java的instanceof 关键字

fun checkNumber(num1:Number)=when(num1){
   is Int -> println("number is Int ")
   is Double-> println("number is Double")
   else -> println("number not support")
}

循环

kt的while循环与java一样

java种的for- i循环被舍弃了

foreach循环 被kt大幅度增强 --> for - in 循环

  • 区间

    kt可以使用 start..end 的方式来创造一个闭区间

    [start,end]

有了区间之后就可以通过 for - in 来遍历

val range=0..10
for (i in range){
   println(i)
}
  • until

为了和其他编程语言的习惯一致

kt还提供了 until 关键字来 创建一个左开右闭的区间

val range =0 until 10
  • step

    指定 每次循环的步长 ,默认为一, 即与 i ++ 类似

    for (i 0 until 10 step 2 ){//与 i+=2 类似
        //doSomething
    }
    
  • downTo 降序

    .. 和 until 都是 升序 , downTo 可以创建降序闭区间

    for( i in 10 downTo 1)
    

字符串拼接

Kotlin允许我们在字符串里嵌入${}这种语法结构的表达式,并在运行时使用表达式 执行的结果替代这一部分内容。

kt 面向对象编程

通过类的封装,我们就可以在适当的时候创建该类的对象,然后调用对象中的字段和函数 来满足实际编程的需求,这就是面向对象编程最基本的思想

kt 不同于 Java 只能创建类

  • kt 可以创建 File 通常是用于编写 kotlin的 顶层函数扩展函数

实例化

定义一个类 person

package com.yxl.kotlin
​
class Person {
    var name =""
    var age=0
    fun eat(){
        println(name +" is eating ,he is ${age}")
    }
}
val person =Person()
person.age=10
person.name="xiao Long"
person.eat()

在 kt中 实例化对象少了 new 关键字

kotlin的 非空设计

在kotlin中 所有的 变量默认不能为null ,它 不像 java的 field 一样 有默认的 初始值

  • 可空类型

    1.但是你需要 一个变量默认值为空时, 可以 在 类型的右边加一个? 来接触它的非空限制,之后再代码的任何地方都可以对它赋值为null

    2.但是调用的时候有会出问题,再使用可空变量的时候kotlin 默认不能使用

    此时要把 . 改为 ?.

    view?.setBackgroundColor(Color.RED)
    

    这种 调用方法时 线程安全的,会在调用之前进行非空检查

    或者

    view!!.setBackgroundColor(Color.RED)
    

    两个 !! 是 告诉编译器 ,你不要进行非空检查

  • lateinit

对于 在 第一时间无法初始化的 变量(如 activity的 view的findviewById),kotlin提供了 lateinit

这种方式也是 告诉 kotlin 不要对变量进行初始化的检查

  • ? : 操作符

    表达式结果不为空就返回左边 ,否则返回右边

    val c =a? :b

继承与构造函数

类的继承的写法,Java 里用的是 extends,而在 Kotlin 里使用 :,但其实 : 不仅可以表示继承,还可以表示 Java 中的 implement

在kt中,一个类默认是不可继承的(除了抽象类) ,也就对于java中的 final,所以要想继承一个类,首先要让一个类变得可继承

抽象类特殊是因为 它本身是不可以创建实例的 ,需要子类实现才能创建实例

//主构造函数
class Student(val score :Int,val grade :String) :Person() {
    /*var score=0
    var grade=""*/
    init {
        //构造代码块
        println("score is ${score} ,grade is ${grade}")
    }
​
​
}

person 后要加 括号的原因是 子类构造函数需要调用父类的构造方法,即使是默认空参构造也不能省略

在java中即使不写super 也会默认调用

在主构造函数中声明成val或者var的参数将自动成为该类的字段

class Student(val score :Int,val grade :String,name:String,age:Int,another:String) :Person(name,age) {
    /*var score=0
    var grade=""*/
    init {
        //构造代码块
        println("score is ${score} ,grade is ${grade}")
    }
    constructor(score: Int, grade: String):this(score,grade,"name",15,"another")
}

次构造函数需要主动调用主构造函数(或者另一个调用了主构造函数的次构造函数(间接调用)) 用 :this()

而且次构造函数不允许出现 val var来声明字段

接口

接口是实现多态编程的重要组成部分

kt与java一样 单继承 多实现

修饰符

kotlin 中 有 public ,private , protected , internal 四种修饰符

private只对当前类可见同java
protected当前类和子类java 在同一包路径下也可见
internal只对当前模块可见java 无
default同一包路径下可见kotlin 无
public全局可见同java

数据类与单例类

这是kotlin中特有的知识点

在java中一个数据bean类一般需要重写equals() ,toString() HashMap() 方法

然而在kotlin中它变得异常简单,不需要重写任何代码

data class CellPhoneBean(val brand :String,val price :Int) {
}

单例模式

object Single{   
}

其使用方法 与java 静态方法调用相似

object :顾名思义 对象 ,其实 就是 创建一个类并创建它的对象

静态方法

用object 修饰的变量和函数都是静态的,但是有的时候我们只需要让变量是静态的

class A{
object static{
    val str:String="我是静态的"
}
    
}

使用

A.static.str

伴生对象

class A{
companion object staticB{
    val str2:String="伴生静态"
}
}

使用

A.str2

此时staticB不需要出现,也可以在代码中直接省略

companion object {
    val str2:String="伴生静态"
}

top-level property /function 声明

把属性和函数不写在class里面 ,而是写在 File中

这样写的属性和函数,不属于任何 class,而是直接属于 package,它和静态变量、静态函数一样是全局的