Kotlin簡介
- 來自于著名的IDE IntelliJ IDEA(Android Studio基于此開發(fā)) 軟件開發(fā)公司 JetBrains(位于東歐捷克)
- 起源來自JetBrains的圣彼得堡團隊杨刨,名稱取自俄羅斯圣彼得堡附近的一個小島(Kotlin Island)
- 一種基于JVM的靜態(tài)類型編程語言但骨,2017年谷歌I/O大會確定Kotlin為Android的官方語言
Kotlin應用不同領(lǐng)域
- Kotlin-Script腳本編寫
- Kotlin-Android項目開發(fā)
- Kotlin-JavaScript前端項目開發(fā)
- Kotlin-SpringBoot服務端項目開發(fā)
- Kotlin-Native項目開發(fā)
Kotlin開發(fā)環(huán)境
- 需要在IDE中安裝Kotlin插件;Android Studio3.0以上
Kotlin的優(yōu)點
- 簡潔(不用判斷NullPointException,不需要寫分號等)
- 100% 兼容 Java
- 類型自動轉(zhuǎn)換并使用
定義變量
val a: Int = 1 // 顯式標明類型钱反,立即賦值
val b = 2 // 自動推斷出 `Int` 類型
var c: Int // 如果沒有初始值類型不能省略
c = 3 // 明確賦值
var和val的區(qū)別
- var是一個可變變量,這種聲明變量的方式和java中聲明變量的方式一樣征讲。
- val是一個只讀變量,這種聲明變量的方式相當于java中的final變量,以后不能被改變脓钾。
var name = "我是可改變的"
println(name)
name = "我真的是可改變"
println(name)
val finalValue = "我是不可改變的";
println(finalValue);
類定義
- 在Kotlin中所有類都有一個共同的超類
Any
//類定義洗鸵,繼承類和實現(xiàn)接口
class FeedBackActivity : NativeBaseActivity(), View.OnLongClickListener, BitmapUtil.SaveImageCall {
}
- 創(chuàng)建類的實例
val invoice = Invoice()
val customer = Customer("Joe Smith")
//注意 Kotlin 并沒有 new 關(guān)鍵字越锈。
函數(shù)定義
Kotlin 中的函數(shù)使用 fun 關(guān)鍵字聲明,參數(shù)即 name: type膘滨。參數(shù)用逗號隔開
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
- 減少方法重載
//支持默認參數(shù)值甘凭,減少方法重載
fun showToast(message: String, duration:Int = Toast.LENGTH_LONG) {
Toast.makeText(this, message, duration).show()
}
//調(diào)用方式:沒有默認值的參數(shù),調(diào)用時火邓,必須填寫
showToast("toast");
showToast("toast", Toast.LENGTH_LONG);
- main方法比較
//Java
public static void main(String[] args){
}
//Kotlin
fun main(args:Array<String>){
}
主次構(gòu)造函數(shù)
在Kotlin中的一個類可以有一個主構(gòu)造函數(shù)和一個或多個次構(gòu)造函數(shù)
- 主構(gòu)造函數(shù):帶有類名的為主構(gòu)造函數(shù)(只有一個)
- 主構(gòu)造函數(shù)不能包含任何的代碼丹弱。初始化的代碼可以放到以 init 關(guān)鍵字作為前綴的初始化塊
- 主構(gòu)造函數(shù)中聲明的屬性可以是可變的(var)或只讀的(val)
//如果構(gòu)造函數(shù)有注解或可見性修飾符,這個 constructor 關(guān)鍵字是必需的铲咨,并且這些修飾符在constructor前面:
class Customer public @Inject constructor(name: String) { …… }
//無修飾可不寫constructor關(guān)鍵字
class Customer (name: String) {
var a :Int = 1
init{……}
}
- 次構(gòu)造函數(shù):不帶類名并且有constructor關(guān)鍵字修飾的函數(shù)為次構(gòu)造函數(shù)(可以一個或多個)躲胳,并且只能存在主構(gòu)造函數(shù)代碼塊之內(nèi)
//如果類有一個主構(gòu)造函數(shù),每個次構(gòu)造函數(shù)需要委托給主構(gòu)造函數(shù)纤勒, 可以直接委托或者通過別的次構(gòu)造函數(shù)間接委托坯苹。委托到同一個類的另一個構(gòu)造函數(shù)用 this 關(guān)鍵字即可:
class Person(val name: String) {
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
- 無參構(gòu)造函數(shù):
- 如果沒有構(gòu)造函數(shù),將會默認一個無參數(shù)構(gòu)造函數(shù)
- 如果主構(gòu)造函數(shù)的所有的參數(shù)都有默認值摇天,編譯器會生成一個額外的無參構(gòu)造函數(shù)粹湃,它將使用默認值恐仑。
//如構(gòu)造函數(shù)為私有,需用private修飾
class DontCreateMe public constructor () {
}
class Customer(val customerName: String = ""){}
函數(shù)調(diào)用
val result = double(2)
Sample().foo() // 創(chuàng)建類 Sample 實例并調(diào)用 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")
區(qū)間
區(qū)間表達式由具有操作符形式 .. 的 rangeTo 函數(shù)輔以 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”
//要創(chuàng)建一個不包括其結(jié)束元素的區(qū)間裳仆,可以使用 until 函數(shù):
for (i in 1 until 10) { // i in [1, 10) 排除了 10
println(i)
}
//能否以不等于 1 的任意步長迭代數(shù)字? 當然沒問題孤钦, step() 函數(shù)有助于此:每循環(huán)到第二個元素就剔除
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 分支
统扳, 除非編譯器能夠檢測出所有的可能情況都已經(jīng)覆蓋了喘帚。
//分支條件可以是:Int,區(qū)間,方法,字符串,對象等
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")//智能轉(zhuǎn)換
else -> false
}
//when 也可以用來取代 if-else if鏈咒钟。 如果不提供參數(shù)吹由,所有的分支條件都是簡單的布爾表達式,而當一個分支的條件為真時則執(zhí)行該分支:
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
for 循環(huán)
for (item in collection) print(item)
//循環(huán)體可以是一個代碼塊朱嘴。
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函數(shù)
for (i in array.indices) {
println(array[i])
}
//或者你可以用庫函數(shù) 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 循環(huán)
while 和 do..while 照常使用,省略
Kotlin 有三種結(jié)構(gòu)化跳轉(zhuǎn)表達式:
- return萍嬉,默認從最直接包圍它的函數(shù)或者匿名函數(shù)返回乌昔。
- break,終止最直接包圍它的循環(huán)壤追。
- continue磕道,繼續(xù)下一次最直接包圍它的循環(huán)。
特殊符號?和!!
?:表示當前是否對象可以為空
!!: 表示當前對象不為空的情況下執(zhí)行
private var cloth_Rv: RecyclerView ?= null
cloth_Rv!!.setHasFixedSize(true)
可見性修飾符
類行冰、對象溺蕉、接口、構(gòu)造函數(shù)悼做、方法疯特、屬性和它們的 setter 都可以有 可見性修飾符。 在 Kotlin 中有這四個可見性修飾符:private贿堰、 protected辙芍、 internal 和 public。 如果沒有顯式指定修飾符的話,默認可見性是 public
- internal —— 能見到類聲明的 本模塊內(nèi) 的任何客戶端都可見其 internal 成員
- 其它和Java一樣
重要關(guān)鍵字
Any
在Kotlin中所有類都有一個共同的超類Any
,Any并不是Object
open
- 修飾類:表示能被繼承
- 修飾方法:表示需要重寫
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()
內(nèi)部類和匿名內(nèi)部類
- 內(nèi)部類
//如果需要調(diào)用成員變量,需要用inner修飾內(nèi)部類
class Outer {
private val bar: Int = 1
inner class Inner {
fun foo() = bar
}
}
val demo = Outer().Inner().foo() // == 1
- 匿名內(nèi)部類
//匿名內(nèi)部類
textView.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
//...
}
})
擴展
函數(shù)擴展可以讓你對任意類進行擴展徘层,而不用繼承等等復雜的操作峻呕。
對參數(shù)的解釋:
- Context:表示函數(shù)的接收者,也就是函數(shù)擴展的對象
- . :擴展函數(shù)修飾符
- toast:擴展函數(shù)的名稱或者屬性名稱
擴展函數(shù)
fun Context.showToast(content: String, duration: Int = Toast.LENGTH_SHORT): Toast {
val toast = Toast.makeText(MyApplication.context, content, duration)
toast.show()
return toast
}
這樣只要是Context的子類趣效,任何地方都可以調(diào)用Toast了
擴展屬性
var View.padLeft: Int
set(value) {
setPadding(value, paddingTop, paddingRight, paddingBottom)
}
get() {
return paddingLeft
}
//調(diào)用 textView.padLeft = 16
Any擴展函數(shù)
apply
- apply 是 Any 的擴展函數(shù)瘦癌,因而所有類型都能調(diào)用。
- apply 接受一個lambda表達式作為參數(shù)跷敬,并在apply調(diào)用時立即執(zhí)行讯私,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()
如有問題歡迎留言,感謝支持和關(guān)注。