前言
本系列文章作爲學習簡單的學習筆記,其目的在於2個:
- 記錄自己學過的知識
- 本着分享交流的原則分享
本系列適合完全沒有學過Kotlin並且像快速入門的同學,本人現在也是在學習中,所以作爲筆記難免會有錯誤,如果我理解的不對或是有疑問,真誠希望可以在留言區大家進行討論。
推薦學習資料
數據類型
1. Boolean類型
val b:Boolean=true
定義類型格式 :訪問修飾符 修飾符 對象名:類名=具體賦值
變量的修飾符有2種:
- val 不可變的屬性聲明
- var 可變屬性聲明
val修飾類似於java中的final修飾,定義時必須初始化(或在構造方法中或是init{}方法中),但是不完全相同Kotlin常量用const修飾。注意是不可變屬性不是靜態屬性
var是可變屬性,可以不初始化,可以多次賦值
在kotlin中不像java,基本數據類型可以用小寫的boolean聲明。這裏必須用他的裝箱類來定義。
訪問修飾符默認是public(java是defualt)
2. Number類型
val l:Long=1231231L
val l1:Long=1231231
val l2:Long=1231231l//error
val f:Float=3f
val f1:Float=3.0F
val f2:Float=3.0//error
val d1:Double=3.0
val s:Short=12712
val byte:Byte=127
在java中有基本數據類型int對應的裝箱類型Integer,Kotlin中是沒有這個概念的Kotlin中的Int相當於int與Integer合體,編譯器會幫我選擇。
Kotlin中不存在隱式轉換,如:
short s = 0;
int i = 0;
long l = 0;
i = s;
l = i;
l = s;
java中正確 Kotlin中
val s: Short = 0
var i: Int = 0
i = s.toInt()
i = s//error
3. Char類型
與java基本一致,這裏列出一些常用的轉義字符
轉義字符 | 含義 |
---|---|
\t | 製表符 |
\b | 光標後退一個字符 |
\n | 回車 |
\r | 光標回到行首 |
’ | 單引號 |
" | 雙引號 |
\ | 反斜槓 |
$ | 美元符號,Kotlin 支持美元符號開頭的字符模板 |
4. String類型
- == 與 ===
val str: String = "str"
val str1: String = String(charArrayOf('s', 't', 'r'))
fun main(args: Array<String>) {
println(str== str1)
println(str=== str1)
}
結果:
true
false
Kotlin中== 相當於.equals()對象比較相等用 ===
- 字符串模板
val int1: Int = 1
val int2: Int = 2
println(" " + int1+ " + " + int2 + " = " + (int1 + int2))
println("$int1 + $int2 = ${int1 + int2}")
//hello "world"
//前面提到的轉義字符
println("hello \"world\"")
val s:String="""
\t
\n
hello World
"""
println(s)
結果:
1 + 2 = 3
1 + 2 = 3
hello "world"
\t
\n
hello World
"${}"字符串模板 """ """ 原始字符串
5. 類與對象
直接將理論還是不夠直觀,所以直接上代碼:
class 美女 private constructor(val 性格: String, val 長相: String, val 聲音: String) {//1
constructor(性格: String, 長相: String, 聲音: String, 三圍: String) : this(性格, 長相, 聲音)//2
constructor(性格: String, 長相: String) : this(性格, 長相, "動聽")
}
class 帥哥(性格: String, 長相: String, 聲音: String) : 人(性格, 長相, 聲音) {//3
init {//4
println("帥哥: 性格:$性格,長相:$長相,聲音:$聲音")
}
}
class Test{//5
val d: Double
val i: Int
constructor(double: Double, int: Int) {
d = double
i = int
}
constructor(double: Double) {
d = double
i = 0
}
}
open class 人(val 性格: String, val 長相: String, val 聲音: String) {
init {
println("new 了一個${this.javaClass.simpleName}: 性格:$性格,長相:$長相,聲音:$聲音")
}
fun funA() {
println(this.聲音)//6
}
}
fun main(args: Array<String>) {
val 我喜歡的妹子: 美女 = 美女("溫柔", "甜美", "動聽","三圍")
val 我膜拜的漢子: 帥哥 = 帥哥("彪悍", "帥氣", "渾厚")
val test1 = Test(2.0)
val test2 = Test(2.0, 3)
}
這段代碼有點長,但是內容非常簡單,我也會分開來說
- 類的定義:
class <類名> 構造器(實參1/形參1,實參2/形參2){
}
Kotlin的構造函數分爲主構造器(primary constructor)和次級構造器(secondary constructor)。
簡單理解就是寫在類名後面的爲主構造器
寫在類裏面的爲次構造器
當主構造器被可見性修飾符修飾時,必須加上constructor關鍵字否則可以省略,如3處帥哥類
- 只有被open關鍵字修飾的類才能被繼承
- Kotlin中繼承是用冒號:來作爲繼承類或是實現接口
- 2處爲次構造器,如果定義了主構造器那麼次構造器需要繼承主構造器
- 形參和實參 人這個類中定義的形參,帥哥定義的實參
- init方法
當使用主構造器時,由於沒有方法體,那麼一些初始化的操作可以在init{}方法中實現。這個方法每次創建對象都會被執行 - 只有次構造器那麼構造方法可以重載
- 形參可以在方法中調用(如果val 聲音: String去掉val這行會報錯)
- java中所有類的父類是Object,Kotlin中所有類的父類是Any
更多知識參考Kotlin的構造函數
6. 空類型
在Kotlin對函數有更嚴格的要求,如在Java中你可以寫這樣一個方法:
public String getName() {
return null;
}
這樣完全是沒問題的,但是在Kotlin中卻不可以
會提示錯誤,意思說你不能返回一個空字符串
PS: 這裏簡單說下Kotlin中方法的定義:
<可見性修飾符> <其他修飾符> fun 方法名(形參1,形參2):<返回值類型>{
}
這個不難理解,基本和Java一樣都是固定格式,沒什麼好說的.
如果這個方法返回本省就可能爲空怎麼辦呢?可以這樣寫:
fun getName(): String? {
return null
}
String?表示他是一個可null的字符串,我們調用時可以這樣:
fun getName(): String? {
return null
}
fun main(args: Array<String>) {
val nameB:String? = getName()
println(nameB?.length)//
}
nameB?這樣表示name不爲空那麼就輸出長度,否則打印null,這樣程序不會崩潰
但是還有一種情況如下:
val value:String ?= "HelloWorld"
println(value!!.length)
定義value是可空類型,但是我明確知道它不是null,那麼我們可以使用value!!,表示我已經確定知道這個值不是null,不要給我報編譯錯誤。
總結
- val notNull: String = null //錯誤,不能爲空
- val nullable: String? = null //正確,可以爲空
- notNull.length //正確,不爲空的值可以直接使用
- nullable.length //錯誤,可能爲空,不能直接獲取長度
- nullable!!.length //正確,強制認定nullable不可空
- nullalbe?.length //正確,若nullable爲空,返回空
7. 智能類型轉換
下面來看:
if (name != null)
println(name.length)
else
return
等價於:
val name: String = getName()?: return
println(name.length)
通過條件語句確定name一定不爲空那麼可以直接調用方法,這就是隻能轉換String?轉String
Java中:
class Parent{
}
class Chlid extends Parent{
public int age=11
}
public void main(){
Parent parent=new Child()
((Chlid)parent).age
}
只有強轉才能調用子類的方法,但是在Kotlin中卻不用 如下:
val parentA: Parent = Chlid()
if (parentA is Chlid) {
parentA.age
}
is關鍵字,常用語判斷,如果判斷成立那麼parentA就是Child不用強轉
關於強轉如下:
val chlidA: Chlid = parentB as Chlid//非安全強轉失敗crash
val chlidB: Chlid? = parentB as? Chlid//安全強轉失敗爲null
總結:
◆ Java Style類型轉換
- val sub: SubClass = parent as SubClass
- 類似於Java的類型轉換,失敗則拋異常
◆ 安全類型轉換
- val sub: SubClass? = parent as? SubClass
- 如果轉換失敗,返回null ,不拋異常
◆ 智能類型轉換
- if(parent is SubClass) parent. <子類的成員>
- 編譯器儘可能的推導類型,遠離無用的類型轉換
- if(nullable != null) nullable.length
- 正確!因爲我們確認nullable不爲空!.
8. 區間
關於區間比較簡單 直接說下概念:
- 個數學上的概念,表示範圍
- ClosedRange的子類, IntRange最常用
- 基本寫法:
- 0…100表示[0, 100]
- 0 until 100表示[0, 100)
- i in 0…100判斷i是否在區間[0, 100]中
代碼:
val rangeInt: IntRange = 1..1024//[0,1024]
val range_exclusive: IntRange = 0 until 1024//[0,1024)
val b: Boolean = true
fun main(args: Array<String>) {
println(rangeInt.contains(50))
println(rangeInt.contains(1024))
println(1024 in rangeInt)
println(range_exclusive.contains(1024))
println(1024 in range_exclusive)
for (i in range_exclusive) {
println(i)
}
}
9. 數組
數組的使用方法
- val array: Array = array0f…)
基本操作
- print array[i] 輸出第i個成員
- array[i] = ,“Hello” 給第i個成員賦值
- array.length 數組的長度
爲了避免不必要的裝箱和拆箱, 基本類型的數組是定製的如下:
例子:
val arrayInt: IntArray = intArrayOf(1, 3, 5, 7)
val arrayChar: CharArray = charArrayOf('H', 'e', 'l', 'l', 'o')
val arrayString: Array<String> = arrayOf("陳", "冠", "希")
val array書記: Array<市委書記> = arrayOf(市委書記("張"), 市委書記("李"), 市委書記("王"))
fun main(args: Array<String>) {
println(arrayInt.size)
for (i in arrayInt) {
println(i)
}
println(arrayChar.joinToString(""))//連接字符
println(arrayString.joinToString(""))//連接字符串
println(array書記[1])
array書記[1] = 市委書記("趙")
println(array書記[1])
println(arrayInt.slice(1..3))//表示的是下標 slice表示"切片"
}
結語
本篇就到這裏下一篇將說下程序結構相關。