Kotlin学习-基础篇(一)

Kotlin简介

  • 来自于著名的IDE IntelliJ IDEA(Android Studio基于此开发) 软件开发公司 JetBrains(位于东欧捷克)
  • 起源来自JetBrains的圣彼得堡团队,名称取自俄罗斯圣彼得堡附近的一个小岛(Kotlin Island)
  • 一种基于JVM的静态类型编程语言,2017年谷歌I/O大会确定Kotlin为Android的官方语言

Kotlin应用不同领域

  • Kotlin-Script脚本编写
  • Kotlin-Android项目开发
  • Kotlin-JavaScript前端项目开发
  • Kotlin-SpringBoot服务端项目开发
  • Kotlin-Native项目开发

Kotlin开发环境

  • 需要在IDE中安装Kotlin插件;Android Studio3.0以上

Kotlin的优点

  • 简洁(不用判断NullPointException,不需要写分号等)
  • 100% 兼容 Java
  • 类型自动转换并使用

定义变量

val a: Int = 1  // 显式标明类型,立即赋值  
val b = 2   // 自动推断出 `Int` 类型  
var c: Int  // 如果没有初始值类型不能省略  
c = 3       // 明确赋值

var和val的区别

  • var是一个可变变量,这种声明变量的方式和java中声明变量的方式一样。
  • val是一个只读变量,这种声明变量的方式相当于java中的final变量,以后不能被改变。
var name = "我是可改变的"  
println(name)  
name = "我真的是可改变"  
println(name)  
val finalValue = "我是不可改变的";  
println(finalValue); 

类定义

  • 在Kotlin中所有类都有一个共同的超类Any
//类定义,继承类和实现接口
class FeedBackActivity : NativeBaseActivity(), View.OnLongClickListener, BitmapUtil.SaveImageCall {
    
}
  • 创建类的实例
val invoice = Invoice()
val customer = Customer("Joe Smith")
//注意 Kotlin 并没有 new 关键字。

函数定义

Kotlin 中的函数使用 fun 关键字声明,参数即 name: type。参数用逗号隔开

fun double(x: Int): Int {
    return 2 * x
}
  • Int 返回类型可以省略
fun sum(a: Int, b: Int): Int {
    return a + b
}

也可以

fun sum(a: Int, b: Int) = a + b
  • 减少方法重载
//支持默认参数值,减少方法重载
fun showToast(message: String, duration:Int = Toast.LENGTH_LONG) {
    Toast.makeText(this, message, duration).show()
}

//调用方式:没有默认值的参数,调用时,必须填写
showToast("toast");
showToast("toast", Toast.LENGTH_LONG);
  • main方法比较
//Java
public static void main(String[] args){

}
//Kotlin
fun main(args:Array<String>){
   
}

主次构造函数

在Kotlin中的一个类可以有一个主构造函数和一个或多个次构造函数

  • 主构造函数:带有类名的为主构造函数(只有一个)
  1. 主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块
  2. 主构造函数中声明的属性可以是可变的(var)或只读的(val)
//如果构造函数有注解或可见性修饰符,这个 constructor 关键字是必需的,并且这些修饰符在constructor前面:
class Customer public @Inject constructor(name: String) { …… }

//无修饰可不写constructor关键字
class Customer (name: String) {
    var a :Int = 1
    init{……}
}
  • 次构造函数:不带类名并且有constructor关键字修饰的函数为次构造函数(可以一个或多个),并且只能存在主构造函数代码块之内
//如果类有一个主构造函数,每个次构造函数需要委托给主构造函数, 可以直接委托或者通过别的次构造函数间接委托。委托到同一个类的另一个构造函数用 this 关键字即可:
class Person(val name: String) {
    constructor(name: String, parent: Person) : this(name) {
        parent.children.add(this)
    }
}
  • 无参构造函数
  1. 如果没有构造函数,将会默认一个无参数构造函数
  2. 如果主构造函数的所有的参数都有默认值,编译器会生成一个额外的无参构造函数,它将使用默认值。
//如构造函数为私有,需用private修饰
class DontCreateMe public constructor () {

}

class Customer(val customerName: String = ""){}

函数调用

val result = double(2)
Sample().foo() // 创建类 Sample 实例并调用 foo

字符串模板

  • 字符串可以包含模板表达式,以$开始
val book = Book("Thinking In Java", 59.0f, "Unknown")
val extraValue = "extra"
Log.d("MainActivity", "book.name = ${book.name}; book.price=${book.price};extraValue=$extraValue")

区间

区间表达式由具有操作符形式 .. 的 rangeTo 函数辅以 in 和 !in 形成。

if (i in 1..10) { // 等同于 1 <= i && i <= 10
    println(i)
}

//顺序
for (i in 1..4) print(i) // 输出“1234”
for (i in 4..1) print(i) // 什么都不输出

//倒序
for (i in 4 downTo 1) print(i) // 输出“4321”

//要创建一个不包括其结束元素的区间,可以使用 until 函数:
for (i in 1 until 10) {   // i in [1, 10) 排除了 10
     println(i)
}

//能否以不等于 1 的任意步长迭代数字? 当然没问题, step() 函数有助于此:每循环到第二个元素就剔除

for (i in 1..4 step 2) print(i) // 输出“13”

for (i in 4 downTo 1 step 2) print(i) // 输出“42”


控制流:if、when、for、while

if表达式

if和Java用法一致

val max = if (a > b) a else b
when表达式

when它能完全取代switch/case,也可以用来取代 if-else if链,并且还有很多新的特性。

如果其他分支都不满足条件将会求值else分支。 如果 when 作为一个表达式使用,则必须有 else 分支, 除非编译器能够检测出所有的可能情况都已经覆盖了。

//分支条件可以是:Int,区间,方法,字符串,对象等
when (x) {
    0, 1 -> print("x == 0 or x == 1")
    in 2 -> print("x == 2")
    in 3..8 -> print("x == 3..8")
    parseInt(s)-> print("parseInt")
    is String -> print("x is String")
    else -> print("otherwise")
}


fun hasPrefix(x: Any) = when(x) {
    is String -> x.startsWith("prefix")//智能转换
    else -> false
}

//when 也可以用来取代 if-else if链。 如果不提供参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支:
when {
    x.isOdd() -> print("x is odd")
    x.isEven() -> print("x is even")
    else -> print("x is funny")
}

for 循环
for (item in collection) print(item)

//循环体可以是一个代码块。
for (item: Int in ints) {
    // ……
}


for (i in 1..3) {
    println(i)//输出“123”
}

for (i in 6 downTo 0 step 2) {
    println(i)//输出“6420”
}

//如果想索引遍历,可以通过indices函数
for (i in array.indices) {
    println(array[i])
}

//或者你可以用库函数 withIndex:
for ((index, value) in array.withIndex()) {
    println("the element at $index is $value")
}
//输出:
the element at 0 is a
the element at 1 is b
the element at 2 is c

While 循环

while 和 do..while 照常使用,省略

Kotlin 有三种结构化跳转表达式:

  • return,默认从最直接包围它的函数或者匿名函数返回。
  • break,终止最直接包围它的循环。
  • continue,继续下一次最直接包围它的循环。

特殊符号?和!!

  • ?:表示当前是否对象可以为空

  • !!: 表示当前对象不为空的情况下执行

private var cloth_Rv: RecyclerView ?= null
cloth_Rv!!.setHasFixedSize(true)

可见性修饰符

类、对象、接口、构造函数、方法、属性和它们的 setter 都可以有 可见性修饰符。 在 Kotlin 中有这四个可见性修饰符:private、 protected、 internal 和 public。 如果没有显式指定修饰符的话,默认可见性是 public

  • internal —— 能见到类声明的 本模块内 的任何客户端都可见其 internal 成员
  • 其它和Java一样

重要关键字

Any

在Kotlin中所有类都有一个共同的超类Any,Any并不是Object

open

  1. 修饰类:表示能被继承
  2. 修饰方法:表示需要重写

final、open、abstract、override对比

修饰符 相应类的成员 注解
final 不能被重写 在kotlin中默认所有的方法和类都是final属性
open 可以被重写 需要被明确指出
abstract 必须要重写 不能被实例化,默认具有open属性
override 覆写超类的方法 如果没有被指定为final,则默认具有open属性

companion 伴生对象

//可以省略Factory
class MyClass {
     companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

val instance = MyClass.create()

内部类和匿名内部类

  • 内部类
//如果需要调用成员变量,需要用inner修饰内部类
class Outer {
    private val bar: Int = 1
    inner class Inner {
        fun foo() = bar
    }
}

val demo = Outer().Inner().foo() // == 1
  • 匿名内部类
//匿名内部类
textView.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?) {
       //...
    }
})

扩展

函数扩展可以让你对任意类进行扩展,而不用继承等等复杂的操作。

对参数的解释:

  • Context:表示函数的接收者,也就是函数扩展的对象
  • . :扩展函数修饰符
  • toast:扩展函数的名称或者属性名称

扩展函数

fun Context.showToast(content: String, duration: Int = Toast.LENGTH_SHORT): Toast {
    val toast = Toast.makeText(MyApplication.context, content, duration)
    toast.show()
    return toast
}

这样只要是Context的子类,任何地方都可以调用Toast了

扩展属性

var View.padLeft: Int
    set(value) {
        setPadding(value, paddingTop, paddingRight, paddingBottom)
    }
    get() {
        return paddingLeft
    }
    //调用 textView.padLeft = 16

Any扩展函数

apply

  • apply 是 Any 的扩展函数,因而所有类型都能调用。
  • apply 接受一个lambda表达式作为参数,并在apply调用时立即执行,apply返回原来的对象。
  • apply 主要作用是将多个初始化代码链式操作,提高代码可读性。
val task = Runnable { println("Running") }
val thread = Thread(task)
thread.setDaemon(true)
thread.start()

以上代码可以简化为:

val task = Runnable { println("Running") }
Thread(task).apply { setDaemon(true) }.start()

如有问题欢迎留言,感谢支持和关注。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342