Kotlin Tutorial(2)10分鐘認識Kotlin by Michael | CodeData
top

Kotlin Tutorial(2)10分鐘認識Kotlin

分享:
tags: kotlin

Kotlin Tutorial(1)Hello! Kotlin! << 前情

就算是一個很有經驗的Java程式設計師,只花十分鐘,應該也沒有辦法「完全」認識與瞭解Kotlin。不過我從Kotlin挑選一些主題,這些內容有兩個用處:

  • 對具備Java程式設計經驗的人來說,你可以花十分鐘看看(或許更少一些),比較Java與Kotlin的差異
  • 如果沒有任何程式設計經驗,你可以花十分鐘看看(應該會更多一些),希望可以讓你覺得寫程式是一件很有趣的事情

套件(package)

Kotlin使用「package」宣告套件,幫應用程式的程式碼分類存放,方便開發與管理。沒有宣告套件的檔案,裡面撰寫的內容都屬於「預設套件、default package」,例如下面的原始程式碼:

/* HelloWorld.kt */
fun main(args: Array<String>) {
    println("Hello World!")
}

使用「package」宣告套件的原始程式碼檔案,並不需要放在對應的套件目錄,例如下面的原始程式碼檔案是放在應用程式的根目錄:

/* HelloPackage.kt */
package net.macdidi5.kotlin.demo

fun main(args: Array<String>) {
    println("Hello Package!")
}

下面的原始程式碼檔案,跟上面的程式碼有同樣的套件宣告,不過它存放在與套件對應的目錄:

/* net/macdidi5/kotlin/demo/HelloPackage2.kt */
package net.macdidi5.kotlin.demo

fun main(args: Array<String>) {
    println("Hello Package2!")
}

不論是否放在與套件對應的目錄,Kotlin在產生Java類別檔案的時候,都會根據「package」宣告,放在對應的目錄。所以把原始程式碼檔案放在與套件對應的目錄,只是為了專案管理的方便性。

變數(variable)

Kotlin使用下面的語法宣告不可改變的變數:

val 變數名稱: 型態 = 初始值

Kotlin使用下面的語法宣告可以改變的變數:

var 變數名稱: 型態 = 初始值

參考下面的宣告變數的範例程式碼:

/* net/macdidi5/kotlin/demo/variable/HelloVariable.kt */
package net.macdidi5.kotlin.demo.variable

fun main(args: Array<String>) {
    val x: Int = 3  // 使用val宣告不可改變的變數
    val y = 5       // 使用設定值推論變數型態
    val z: Int      // 沒有設定值的變數就一定要指定型態
    z = 7           // 設定值以後就不可以改變

    println("X: " + x)
    println("Y: " + y)
    println("Z: " + z)

    // 下面的敘述都會造成錯誤: Val cannot be reassigned
    /*
    x = 13
    y = 15
    z = 17
    */

    var v: Int = 3          // 使用var宣告可以改變的變數
    v = 13                  // 不會發生錯誤
    println("V: " + v)
}

函式(function)

Kotlin使用下面的語法宣告函式:

fun 函式名稱(參數名稱: 參數型態,...): 回傳型態 {

}

參考下面的宣告與使用函式的範例程式碼:

/* net/macdidi5/kotlin/demo/function/HelloFunction.kt */
package net.macdidi5.kotlin.demo.function

// 宣告一個接收兩個字串參數,執行後回傳字串的函式
fun getGreeting(greet: String, name: String): String {
    return greet + ", " + name + "!"
}

// 如果函式只有一個回傳的敘述,可以簡化成這樣
fun getGreeting2(greet: String, name: String) =
    greet + ", " + name + "!"

// 沒有回傳值的函式,把回傳值宣告為「Unit」
fun sayGreeting(greet: String, name: String): Unit {
    println(greet + ", " + name + "!")
}

// 沒有回傳值的函式,也可以省略「:Unit」
fun sayGreeting2(greet: String, name: String) {
    println(greet + ", " + name + "!")
}

fun main(args: Array<String>) {
    println( getGreeting("Hello", "Simon") )
    println( getGreeting2("Hello", "Simon") )
    sayGreeting("Hello", "Simon")
    sayGreeting2("Hello", "Simon")
}

使用import

Kotlin使用下面的語法撰寫import敘述:

import 套件.函式
import 套件.*

參考下面的範例程式碼,使用import敘述或包含套件的全名,呼叫寫在其它套件的函式:

/* HelloImport.kt */
import net.macdidi5.kotlin.demo.function.getGreeting
import net.macdidi5.kotlin.demo.function.getGreeting2
import net.macdidi5.kotlin.demo.function.sayGreeting

// 如果使用下面的敘述,就可以省略上面的三個import敘述
/* import net.macdidi5.kotlin.demo.function.* */

fun main(args: Array<String>) {

    // 使用import敘述後就可以直接呼叫
    println( getGreeting("Hello", "Simon") )
    println( getGreeting2("Hello", "Simon") )
    sayGreeting("Hello", "Simon")

    // 沒有使用import敘述就必須使用包含套件的全名
    net.macdidi5.kotlin.demo.function.sayGreeting2("Hello", "Simon")

}

字串模板(string template)

Kotlin使用字串模板簡化文字內容的處理,你可以在字串裡面需要替換內容的地方使用下面的作法:

"...$變數..."

如果需要替換的內容是一個運算式,就必須使用大刮號:

"...${運算式}..."

參考下面使用字串模板的範例程式碼:

/* net/macdidi5/kotlin/demo/stringtemplate/HelloStringTemplate.kt */
package net.macdidi5.kotlin.demo.stringtemplate

fun main(args: Array<String>) {
    val x = 3
    val y = 5
    val z = 7

    // 替換變數內容以後的字串指定給變數s
    val s = "X: $x, Y: $y, Z: $z"
    println(s)

    // 顯示: summary: 3 + y + z
    println("summary: $x + y + z")

    // 顯示: summary: 15
    println("summary: ${x + y + z}")
}

條件(conditions)

Kotlin使用if,else if與else執行條件判斷的工作,參考下面的範例程式碼:

/* net/macdidi5/kotlin/demo/condition/HelloCondition.kt */
package net.macdidi5.kotlin.demo.condition

fun main(args: Array<String>) {    
    val x = 3
    val y = 5

    if (x > y) {
        println("x greater than y")
    }
    else if (x < y) {
        println("x less than y")
    }
    // 只有一行需要執行的敘述,可以省略大刮號
    else
        println("x equals y")
    // 執行程式後顯示: x less than y
}

如果是比較簡單的if與else判斷,可以使用if-else運算式的語法:

/* net/macdidi5/kotlin/demo/condition/HelloCondition2.kt */
package net.macdidi5.kotlin.demo.condition

fun main(args: Array<String>) {
    val x = 3
    val y = 5
    val z: Int

    // 一般的寫法
    if (x > y) {
        z = x
    }
    else {
        z = y
    }
    // 顯示: 5
    println(z)

    val v: Int

    // if-else運算式的寫法
    v = if (x > y) x else y
    // 顯示: 5
    println(v)
}

Kotlin使用when執行單一變數值的判斷,跟if-else運算式一樣,它也可以使用簡化的運算式語法,參考下面的範例程式碼:

/* net/macdidi5/kotlin/demo/condition/HelloCondition3.kt */
package net.macdidi5.kotlin.demo.condition

fun main(args: Array<String>) {
    val grade = 'B'
    val bonus: Int

    when (grade) {
        'A'     -> bonus = 5000
        'B'     -> bonus = 3000
        'C'     -> bonus = 1000
        else    -> bonus = 50
    }

    // 顯示: Bonus: 3000
    println("Bonus: $bonus")

    val bonus2 =
            when (grade) {
                'A'     -> 5000
                'B'     -> 3000
                'C'     -> 1000
                else    -> 50
            }

    // 顯示: Bonus: 3000
    println("Bonus2: $bonus2")
}

迴圈(loop)

Kotlin使用whil、do-while與for三種迴圈,用來執行重複的工作。參考下面使用while迴圈的範例程式碼:

/* net/macdidi5/kotlin/demo/loop/HelloWhileLoop.kt */
package net.macdidi5.kotlin.demo.loop

fun main(args: Array<String>) {
    var index = 0

    while (index < 10) {
        print(index)
        index++
    }
    // 執行程式後顯示: 0123456789
}

參考下面使用do-while迴圈的範例程式碼:

/* net/macdidi5/kotlin/demo/loop/HelloDoWhileLoop.kt */
package net.macdidi5.kotlin.demo.loop

fun main(args: Array<String>) {
    var index = 0

    do {
        print(index)
        index++
    } while (index < 10)
    // 執行程式後顯示: 0123456789
}

參考下面使用for迴圈的範例程式碼:

/* net/macdidi5/kotlin/demo/loop/HelloForLoop.kt */
package net.macdidi5.kotlin.demo.loop

fun main(args: Array<String>) {
    // 顯示: 12345
    for (index: Int in 1..5) {
        print(index)
    }

    println()

    // 顯示: 135
    for (index: Int in 1..5 step 2)
        print(index)

    println()

    // 顯示: 54321
    for (index: Int in 5 downTo 1)
        print(index)
}

陣列(array)

用來包裝多個資料的陣列,可以搭配迴圈,很方便執行一些大量資料的統計、平均與其它類似的工作。參考下面使用for迴圈執行陣列資料合計的範例程式碼:

/* net/macdidi5/kotlin/demo/collection/HelloArray.kt */
package net.macdidi5.kotlin.demo.collection

fun main(args: Array<String>) {
    // 有三個元素的整數陣列
    val ia: IntArray = intArrayOf(3, 5, 7)

    // 合計變數
    var total: Int = 0

    // 依序處理所有陣列元素的迴圈
    // 執行過程會自動把每一個陣列的元素指定給變數n
    for (n in ia) {
        total += n
    }

    // 顯示: Total: 15
    println("Total: $total")
}

擔心Java 8的Lambda是否會在Kotlin出現嗎?Kotlin在Lambda提供更精簡的寫法,參考下面為陣列資料執行很多複雜工作,可是程式碼卻不會複雜的範例:

/* net/macdidi5/kotlin/demo/collection/HelloLambda.kt */
package net.macdidi5.kotlin.demo.collection

fun main(args: Array<String>) {
    // 有五個元素的整數陣列
    val ia: IntArray = intArrayOf(120, 30, 15, 27, 66)

    ia.filter { it > 50 }         // 留下大於50的元素
      .sortedBy { it }            // 依照大小排序
      .map { it / 10 }            // 元素值除以10
      .forEach { print("$it-") }  // 顯示元素值
    // 顯示: 6-12-
}

類別(class)

物件導向?參考下面宣告類別、建立與使用物件的範例程式碼(如果你還沒有程式設計經驗,可以忽略這一個主題):

/* net/macdidi5/kotlin/demo/classes/HelloClass.kt */
package net.macdidi5.kotlin.demo.classes

// 宣告Person類別,使用open讓這個類別可以被繼承
// (var name: String)是一個字串參數的主要建構式(primary constructor)
open class Person(var name: String) {

    // 一個可以改變值的屬性(property)
    var gender: Char = 'U'
    // 一個不可以改變值的屬性
    val information: String
        // 為information加入getter方法
        get() = "$name(${if (gender=='M') "Male" else "Female"})"

    // 其它建構式,使用this(name)呼叫主要建構式
    constructor(name: String, gender: Char) : this(name) {
        // 設定屬性
        this.gender = gender
    }

    // 函式
    fun sayGreeting() {
        println("Hello, $name!")
    }

    // 函式,使用open讓子類別可以覆寫這個方法
    open fun printInformation() {
        println("Name: $name")
        println("Gender: $gender")
    }

}

fun main(args: Array<String>) {
    // 呼叫主要建構式建立Person物件
    val simon: Person = Person("Simon")
    // 呼叫函式,顯示: Hello, Simon!
    simon.sayGreeting()
    // 設定屬性值
    simon.gender = 'M'
    // 使用屬性值,顯示: Simon(Male)
    println(simon.information)

    println()

    // 呼叫其它建構式建立Person物件
    val mary = Person("Mary", 'F')
    // 呼叫函式,顯示: Hello, Mary!
    mary.sayGreeting()
    // 使用屬性值,顯示: Mary's gender is F
    println("${mary.name}'s gender is ${mary.gender}")
}

繼承(inheritance)

既然有物件導向基本的類別,繼承也是應該要有的。參考下面宣告子類別的範例程式碼(如果你還沒有程式設計經驗,可以忽略這一個主題):

package net.macdidi5.kotlin.demo.classes

// 宣告Employee類別,沒有使用open,表示這個類別不可以被繼承
// (name: String)是一個字串參數的主要建構式(primary constructor)
// 使用Person(name)呼教父類別的建構式
class Employee(name: String) : Person(name) {

    // 一個可以改變值的屬性(property)
    var salary: Double = 0.0

    // 其它建構式,使用this(name)呼叫主要建構式
    constructor(name: String, gender: Char, salary: Double): this(name) {
        // 設定繼承自父類別的屬性值
        super.gender = gender
        // 設定屬性值
        this.salary = salary
    }

    // 覆寫繼承自父類別的函式
    override fun printInformation() {
        // 呼叫父類別的函式
        super.printInformation()
        println("Salary: $salary")
    }

}

fun main(args: Array<String>) {
    // 呼叫其它建構式建立Employee物件
    val simon = Employee("Simon", 'M', 25000.0)
    // 呼叫函式
    simon.printInformation()
    // 執行後顯示:
    //      Name: Simon
    //      Gender: M
    //      Salary: 25000.0
}

下一步

對Kotlin是一知半解或是很有感覺?接下來準備正式進入Kotlin程式設計的世界。

相關的檔案都可以在GitHub瀏覽與下載。

https://github.com/macdidi5/Kotlin-Tutorial

後續 >> Kotlin Tutorial(3)Kotlin程式設計基礎

分享:
按讚!加入 CodeData Facebook 粉絲群

留言

留言請先。還沒帳號註冊也可以使用FacebookGoogle+登錄留言

關於作者

張益裕。目前的工作是講師與作者,專長是教育訓練課程規劃、教材編製與課程推廣,技術書籍與專欄寫作。涵蓋的領域有OOAD、Java程式設計、JavaFX、Java Embedded、Android與SQL。已出版電子書Google Play圖書Pubu

熱門論壇文章

熱門技術文章