KEMBAR78
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹 | PDF
炎炎夏⽇日學 Android
Johnny Sung
Part1: Kotlin 語法介紹
Mobile device developer
Johnny Sung
https://fb.com/j796160836
https://blog.jks.coffee/
https://www.slideshare.net/j796160836
https://github.com/j796160836
⼤大綱
• Kotlin 語法介紹

• Android 元件介紹

• Hello Android
環境準備
• 電腦⼀一台 💻

• 安裝 Android Studio & Android SDK

• Android ⼿手機⼀一⽀支(極建議,非必要)

• 夠快的網路路 Wifi 

• 你最愛的飲料⼀一杯 🥤
純命令列列環境
• 電腦版 IntelliJ 新增 Kotlin JVM 專案

• IntelliJ IDEA CE

https://www.jetbrains.com/idea/

• Kotlin 線上編譯器

https://play.kotlinlang.org

• Java 線上編譯器

https://www.tutorialspoint.com/compile_java_online.php
純命令列列環境
線上版 電腦版
• 優點:跨平台,不需安裝,

不佔硬碟空間,快速⽅方便便使⽤用。

• 缺點:編輯器語法⾃自動完成較陽春,

無⾃自動格式化。
• 優點:編譯較快,

編輯器語法⾃自動完成較完整,

• 缺點:需安裝,佔硬碟空間。
IntelliJ IDEA CE

https://www.jetbrains.com/idea/
Kotlin 線上編譯器

https://play.kotlinlang.org
Java 線上編譯器

https://www.tutorialspoint.com/compile_java_online.php
變數 (Variable)
https://www.citiesocial.com/products/picardie-500ml-6
glass
var glass: String = "檸檬紅茶茶"
變數名稱 型態 值
宣告(指定給...)
(初始化)
http://www.royalhost.com.tw/m/mealList.php?class_type=07&pid=132
glass
• 數字

• String 字串串 (陸譯:字符串串)

• Boolean 布林林 (陸譯:布爾)

• Array 陣列列 (陸譯:數組)

• Char 字元 (陸譯:字符)
• Double ⾼高精度浮點數 (64 bit)

• Float 浮點數 (32 bit)

• Long 長整數 (64 bit)
基礎資料型態
https://www.kotlincn.net/docs/reference/basic-types.html
• Int 整數 (32 bit)

• Short 整數 (16 bit)

• Byte 整數 (8 bit)
var val宣告⼀一個可修改的變數 宣告⼀一個不可改的常數
var number: Int? = null
var number2: Int = 1
變數名稱 型態 值
變數名稱 型態 值
有問號
沒有問號
null
https://www.citiesocial.com/products/picardie-500ml-6
Int? Int
有問號 沒有問號
變數可以為空值 變數不可為空值
var

(變數可修改)
val

(變數不可改)
型態有問號

(可以為空值)
✅ ❌
型態沒有問號

(不可為空值)
✅ 

(需給初始值)
✅

(需給初始值)
var myString1: String = "abc"
var myString2: String? = null
val myString3: String = "abc"
宣告⼀一個 myString 的字串串,初始為 "abc" (不為 null,⼀一定要給值)
宣告⼀一個可為 null 的字串串叫 myString,初始為 null
宣告⼀一個不可改的字串串叫 myString,值為 "abc"
流程與判斷 

(Conditions & Flows)
if
https://goods.ruten.com.tw/item/show?21738146420312
(⾃自動判斷為布林林值,省略略型態寫法)
var temperature = 15
if (temperature > 40) {
print("是熱⽔水")
} else {
print("是冷⽔水")
}
var isCreature = true
if (isCreature) {
print("是⽣生物")
} else {
print("不是⽣生物")
}
(⾃自動判斷為布林林值,省略略型態寫法)
常⽤用運算元
== 等於
> ⼤大於
>= ⼤大於等於
< ⼩小於
<= ⼩小於等於
&& AND
|| OR
! NOT
真值表
A B A && B A || B
false false false false
false true false true
true false false true
true true true true
Switch
when
http://www.dmerci.com/index.php/product/new%E6%96%B0%E5%93%81classic%E5%BD%88%E7%8F%A0%E5%8F%B0/
val viewType: Int = 1
when (viewType) {
1, 2 -> {
// Do something with value 1 or 2
}
3 -> {
// Do something with value 3
}
else -> {
// Do something with default
}
}
switch (viewType) {
case 1:
case 2:
// Do something with value 1 or 2
break;
case 3:
// Do something with value 3
break;
default:
// Do something with default
}
val viewType: Int = 1
when (viewType) {
1, 2 -> {
// Do something with value 1 or 2
}
3 -> {
// Do something with value 3
}
else -> {
// Do something with default
}
}
Java Kotlin
😮
Java Kotlin
if (item instanceof ModelA) {
// ...
} else if (item instanceof ModelB) {
// ...
} else if (item instanceof ModelC) {
// ...
} else {
// ...
}
when (item) {
is ModelA -> {
// ...
}
is ModelB -> {
// ...
}
is ModelC -> {
// ...
}
else -> {
// ...
}
}
😎
型態判斷
型態判斷
for
迴圈
http://120.116.50.2/school/album/index_showpic.php?picpage=1&selpage=1&prgid=3&sgd=&actid=7275&sernum=6&selpart=
http://www.winled.com.tw/product_details.php?id=114
( 0 到 1
0 )
for (i in 0..10) {
println(i)
}
開始值 結束值
關鍵字的點點
賦予計數的變數名

(計數器的變數)
開始值 結束值
關鍵字 downTo
賦予計數的變數名

(計數器的變數)
for (i in 10 downTo 0 step 1) {
println(i)
}
步進值
( 10 到 0 )
Java
Kotlin
for (i in 10 downTo 0 step 1) {
println(i)
}
for (int i = 10; i >= 0; i--) {
System.out.println(i);
}
for (i in 0..10) {
println(i)
}
for (int i = 0; i <= 10; i++) {
System.out.println(i);
}
( 0 到 10 )
( 10 到 0 )
( 0 到 10 )
( 10 到 0 )
陣列列 (Array)
http://tw.gigacircle.com/2409121-1
Java
Kotlin
String[] strings = new String[]{"a", "b"};
陣列列型態
陣列列型態
val strings: Array<String> = arrayOf("a", "b")
ArrayList<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
val strings:ArrayList<String> = ArrayList<String>()
strings.add("a")
strings.add("b")
strings.add("c")
ArrayList 型態
ArrayList 型態
陣列列搭配 for 迴圈是好⿇麻吉
☺
Java
Kotlin
val strings = arrayOf("a", "b", "c")
for ((index, value) in strings.withIndex()) {
println("The element at $index is $value")
}
String[] strings = new String[]{"a", "b", "c"};
for (int index = 0; index < strings.length; index++) {
String value = strings[index];
System.out.println("The element at " + index + " is " + value);
}
Kotlin
型態省略略
val strings = arrayOf("a", "b")
val strings = ArrayList<String>()
strings.add("a")
strings.add("b")
strings.add("c")
型態省略略
val num = 1
val str = "hello"
型態省略略
型態省略略
val str:String = "hello"
val num:Int = 1
Java
Kotlin
for (int i = 0; i < strings.length; i++) {
String string = strings[i];
// ...
}
for (String string : strings) {
// ...
}
for (string in strings) {
// ...
}
String[] strings = new String[]{"a", "b"};
陣列列
陣列列
val strings: Array<String> = arrayOf("a", "b")
for (i in 0 until strings.size) {
// ...
}
多維陣列列
http://tw.gigacircle.com/2409121-1
a0
a1
a2
a3
a4
b0
b1
b2
b3
b4
c0
c1
c2
c3
c4
d0
d1
d2
d3
d4
val ice = arrayOf(
arrayOf("a0", "a1", "a2", "a3", "a4"),
arrayOf("b0", "b1", "b2", "b3", "b4"),
arrayOf("c0", "c1", "c2", "c3", "c4"),
arrayOf("d0", "d1", "d2", "d3", "d4")
)
http://tw.gigacircle.com/2409121-1
ice[0][0]
ice[0][1]
ice[0][2]
ice[0][3]
ice[0][4]
ice[1][0]
ice[1][1]
ice[1][2]
ice[1][3]
ice[1][4]
ice[2][0]
ice[2][1]
ice[2][2]
ice[2][3]
ice[2][4]
ice[3][0]
ice[3][1]
ice[3][2]
ice[3][3]
ice[3][4]
function
(method)
fun plus(a: Int, b: Int): Int {
return a + b
}
參參數1 參參數1型態 參參數2 參參數2型態函式名字 回傳值型態(宣告)
(呼叫)
val c = plus(1,3)
Anonymous function
匿名函式
Callback
回呼
my_button.setOnClickListener {
// ...
}
my_button.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
// ...
}
})
my_button.setOnClickListener {
// ...
}
val doneCallback: () -> Unit = {
// I'm done!
}
doneCallback()
doneCallback.invoke()
(宣告)
(呼叫)
變數型態
呼叫
val doneCallback: (String) -> Unit = { str ->
println(str)
}
(宣告)
(呼叫)
變數型態
呼叫
doneCallback.invoke("The result")
var doneCallback: ((String) -> Unit)? = null
doneCallback = { str ->
println(str)
}
doneCallback?.invoke("The result")
(宣告)
(呼叫)
可能為 null 的型態
如果是 null 就不呼叫
if (doneCallback != null) {
doneCallback.invoke("The result")
}
錯誤處理理
錯誤處理理
try {
// ...
throw IllegalArgumentException("Invalid argument.")
// ...
} catch (e: Exception) {
e.printStackTrace()
}
拋出錯誤
接住錯誤
class & method
(Function)
class MyClass {
private val str = "hello"
public fun printHello() {
println(str)
}
}
類別名
類別變數
類別⽅方法
public class MyClass {
private String str = "hello";
public void printHello() {
System.out.println(str);
}
}
class MyClass {
private val str = "hello"
public fun printHello() {
println(str)
}
}
Java Kotlin
class 類別 object 物件
https://auto.epochtimes.com/car-b5-36337-%E6%96%B0%E8%BB%8A%E4%BB%8B%E7%B4%B9%EF%BC%9A2019%E6%AC%BE%E5%A5%A7%E8%BF%AAAudi%20A6.html
https://itw01.com/V25GNEJ.html
class MyDataModel {
var name: String? = ""
var num: Int = 0
}
val model = MyDataModel()
model.name = "John"
model.num = 123
建立 MyDataModel 物件
建構⼦子
Java Kotlin
class Student {
private String name;
public Student(String name) {
this.name = name;
}
public void printName() {
System.out.println(name);
}
}
class Student {
var name: String
constructor(name: String) {
this.name = name
}
fun printName(){
println(name)
}
}
建構⼦子
建構⼦子的變形
class Student {
var name: String
constructor(name: String) {
this.name = name
}
fun printName(){
println(name)
}
}
class Student(var name: String) {
fun printName(){
println(name)
}
}
static Method
class MyClass {
companion object {
fun staticMethod() {
}
}
}
public class MyClass {
public static void staticMethod() {
}
}
Java
Kotlin
Kotlin
class MyClass {
companion object {
fun staticMethod() {
}
}
}
object MyClass {
fun staticMethod() {
}
}
物件導向程式設計

(Object-oriented programming)
• 抽象(Abstraction)

• 封裝(Encapsulation)

• 繼承(Inheritance)

• 多型(Polymorphism)
陸譯:⾯面向对象程序设计
interface Animal {
fun sound()
}
class Cat : Animal {
override fun sound() {
println("喵喵喵~")
}
}
class Dog : Animal {
override fun sound() {
println("汪汪汪~")
}
}
繼承(或實作)
val pet: Animal = Cat()
pet.sound()
// 喵喵喵~
class HairClipperForDog {
fun haircut(dog: Dog) {
println("(理理髮器聲...)")
dog.sound()
println("頭⽑毛理理好了了!")
}
}
class HairClipperForCat {
fun haircut(cat: Cat) {
println("(理理髮器聲...)")
cat.sound()
println("頭⽑毛理理好了了!")
}
}
val myCat = Cat()
val catClipper = HairClipperForCat()
catClipper.haircut(myCat)
val myDog = Dog()
val dogClipper = HairClipperForDog()
dogClipper.haircut(myDog)
class HairClipper {
fun haircut(animal: Animal) {
println("(理理髮器聲...)")
animal.sound()
println("頭⽑毛理理好了了!")
}
}
https://tw.buy.yahoo.com/gdsale/
%E6%97%A5%E8%B1%A1%E9%BB%91%E9%91%BD%E9%9B%BB%E5%8B%95%E7%90%86%E9%AB%AE%E5%99%A8%E5%85%85%E6%8F%92%E6%9C%89%E7%B7%9A%E7%84%A1%E7%B7%9AZOH-2600C-5289698.html
val hairClipper = HairClipper()
val myDog = Dog()
hairClipper.haircut(myDog)
val myCat = Cat()
hairClipper.haircut(myCat)
Java Kotlin
interface Animal {
public void eat();
}
class Cat implements Animal {
@Override
public void eat() {
// ...
}
}
class Dog implements Animal {
@Override
public void eat() {
// ...
}
}
interface Animal {
fun eat()
}
class Cat : Animal {
override fun eat() {
// ...
}
}
class Dog : Animal {
override fun eat() {
// ...
}
}
變數轉型
變數轉型
• 基本型別的轉型

• 有對應函式能使⽤用
變數轉型
• 物件的轉型

• 要是繼承樹裡的才能轉型
open class Father {
// ...
}
class Brother: Father() {
// ...
}
var a: Father = Brother()
var b = a as? Brother
如果轉型失敗就回傳 null
變數型態為:Brother?
Collections
Collections
• Map

• HashMap

• TreeMap
• List

• ArrayList

• LinkedList

• Stack

• Queue
• Set

• SortedSet

• HashSet

• TreeSet
[ 清單類 ] [ 不重複類 ] [ key-value 類 ]
ArrayList
val strings:ArrayList<String> = ArrayList<String>()
strings.add("a")
strings.add("b")
strings.add("b")
strings.add("a")
ArrayList 型態
( 有順序的清單 )
a b b a
Java
Kotlin
String[] strings = new String[]{"a", "b"};
陣列列型態
陣列列型態
val strings: Array<String> = arrayOf("a", "b")
ArrayList<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
val strings:ArrayList<String> = ArrayList<String>()
strings.add("a")
strings.add("b")
strings.add("c")
ArrayList 型態
ArrayList 型態
Array 陣列列 ArrayList
可修改數量量數量量不可修改
(數量量在宣告時即固定,不可修改)
我有問題 (
為何宣告不可改的東⻄西⼜又可以改?
val strings:ArrayList<String> = ArrayList<String>()
strings.add("a")
strings.add("b")
strings.add("c")
宣告不可改
為什什麼⼜又可以改?
http://www.funbugi.com/%E8%87%AA%E5%B7%B1%E5%8B%95%E6%89%8Bdiy%E7%95%AB%E5%AE%A4%E5%85%A7%E8%A8%AD%E8%A8%88%E5%B9%B3%E9%9D%A2%E5%9C%96sketchup/
倉庫
倉庫 倉庫
倉庫
倉庫
http://www.funbugi.com/%E8%87%AA%E5%B7%B1%E5%8B%95%E6%89%8Bdiy%E7%95%AB%E5%AE%A4%E5%85%A7%E8%A8%AD%E8%A8%88%E5%B9%B3%E9%9D%A2%E5%9C%96sketchup/
主臥室
⼩小孩房 客廳
⼯工作室
倉庫
空間本⾝身不能變,

內裝配置沒限制 😊
HashSet
val hashSet = HashSet<String>()
hashSet.add("a")
hashSet.add("a")
hashSet.add("b")
hashSet.add("b")
a
b
( 不允許重複的資料集 )
HashMap
val students = HashMap<String, String>()
students.put("A001", "王⼤大明")
students.put("A002", "黎黎曉彤")
students.put("A003", "桃⼤大姐")
students.put("A001", "王⼤大明")
王⼤大明
黎黎曉彤
桃⼤大姐A001 A002
A003
(⽤用 key-value 存放的不重複資料集 )
猛虎出柙雙劍合璧版--最新 OCA / OCP Java SE 7 Programmer 專業認證
https://books.google.com.tw/books?id=EElBCgAAQBAJ&pg=PA407&lpg=PA407&source=bl&ots=bPzrpKU4n4&sig=ACfU3U31_OKnAJo5ELdqMfu2E4TNIW218A&hl=zh-TW&sa=X&ved=2ahUKEwi-u5uYzPTiAhWKF6YKHVAXB-sQ6AEwAHoECAkQAQ#v=onepage&
猛虎出柙雙劍合璧版--最新 OCA / OCP Java SE 7 Programmer 專業認證
https://books.google.com.tw/books?id=EElBCgAAQBAJ&pg=PA407&lpg=PA407&source=bl&ots=bPzrpKU4n4&sig=ACfU3U31_OKnAJo5ELdqMfu2E4TNIW218A&hl=zh-TW&sa=X&ved=2ahUKEwi-u5uYzPTiAhWKF6YKHVAXB-sQ6AEwAHoECAkQAQ#v=onepage&
程式設計原則 - SOLIDby Robert C. Martin
SOLID
• 單⼀一職責原則 Single responsibility

• 開放封閉原則 Open-Close

• ⾥里里⽒氏替換原則 Liskov substitution

• 接⼝口隔離原則 Interface segregation

• 依賴反轉原則 Dependency inversion
by Robert C. Martin
https://ithelp.ithome.com.tw/articles/10191553
http://teddy-chen-tw.blogspot.com/2014/04/solid.html
單⼀一職責原則

(Single responsibility principle, SRP)
每個 類別 (class)、函數 (method) 負責的功能,都應該只做⼀一件事。
泛型 (Generic)
https://www.pcstore.com.tw/3m-house/M17129526.htm
<物品名稱>
<物品>
https://www.jingyeqian.com/news-68.html
https://www.pcstore.com.tw/3m-house/M17129526.htm
ArrayList
val strings:ArrayList<String> = ArrayList<String>()
strings.add("a")
strings.add("b")
strings.add("c")
ArrayList 型態
泛型帶入的型別
class HairClipperForDog {
fun haircut(dog: Dog) {
println("(理理髮器聲...)")
dog.sound()
println("頭⽑毛理理好了了!")
}
}
class HairClipperForCat {
fun haircut(cat: Cat) {
println("(理理髮器聲...)")
cat.sound()
println("頭⽑毛理理好了了!")
}
}
val myCat = Cat()
val catClipper = HairClipperForCat()
catClipper.haircut(myCat)
val myDog = Dog()
val dogClipper = HairClipperForDog()
dogClipper.haircut(myDog)
class HairClipper<T : Animal> {
fun haircut(animal: T) {
println("(理理髮器聲...)")
animal.sound()
println("頭⽑毛理理好了了!")
}
}
https://tw.buy.yahoo.com/gdsale/
%E6%97%A5%E8%B1%A1%E9%BB%91%E9%91%BD%E9%9B%BB%E5%8B%95%E7%90%86%E9%AB%AE%E5%99%A8%E5%85%85%E6%8F%92%E6%9C%89%E7%B7%9A%E7%84%A1%E7%B7%9AZOH-2600C-5289698.html
⾃自⼰己取的型態 T
只限於 Animal 繼承樹上的
val myDog = Dog()
val hairClipperForDog = HairClipper<Dog>()
hairClipperForDog.haircut(myDog)
val myCat = Cat()
val hairClipperForCat = HairClipper<Cat>()
hairClipperForCat.haircut(myCat)
延伸閱讀
https://classroom.udacity.com/courses/ud9011/
https://classroom.udacity.com/courses/ud9012/
Kotlin Bootcamp for Programmers
Developing Android Apps with Kotlin
延伸閱讀
https://kotlinlang.org/docs/tutorials/
https://kotlinlang.org/docs/reference/
Kotlin Tutorials
Learn Kotlin
https://www.kotlincn.net/docs/reference/
https://www.kotlincn.net/docs/reference/
https://www.kotlincn.net/docs/tutorials/
Tea time~ ☕

炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹