Kotlin 入門學習筆記

以下內容純粹為本人學習期間總結破喻,如有錯誤之處煩請指正不勝感激??

此次學習分享的內容均是Kotlin入門基礎語法;協(xié)程,Anko跛蛋,擴展屬性等等還沒涉及到

繼承

  • Java
class A extends B { }
  • Kotlin
class A : B() {}

接口

  • Java
class A implements B, C {}
  • Kotlin
class A : B, C {}

override

Java 中是注解庆揪。重寫父類方法,實現(xiàn)接口方法
Kotlin中成了類似關鍵字的東西囚枪。重寫和實現(xiàn)自帶了,不再是注解

  • Java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
}
  • Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)
}

Object 類

  • JavaObject是所有類型的頂級父類
  • Kotlin中并沒有Object劳淆,取而代之的是Any()链沼,意義和Java中的Object一樣。注意此處指的是大寫OObject沛鸵,非小寫oobject

結扎關鍵字

  • JavaKotlin都不能繼承自結扎類
  • Java中用final修飾的類不可被繼承括勺,并且Java中的類不聲明為final的話則默認可被繼承
  • Kotlin中則和Java相反,Kotlin中的類默認是被結扎的曲掰,不可被繼承疾捍,除非使用了open關鍵字
  • Kotlin中如果某個類被聲明為abstract,則不需要使用open進行修飾了栏妖,默認已經(jīng)帶上

實例化對象

  • Java
Person person = new Person(bug, 需求)乱豆;
  • Kotlin
var person = Person(bug, 需求)

打印日志

  • Java
System.out.print("打印日志");
System.out.println("打印日志");
  • Kotlin
print("打印日志")
println("打印日志")

常量與變量

  • Java
String name = "Hello Java";
final String name = "Hello 結扎過的 Java";
  • Kotlin
var name = "Hello Kotlin"
val name = "Hello 結扎過的 Kotlin"

null聲明

  • Java
String otherName;
otherName = null;
  • Kotlin
//在類型后面跟英文問號代表此變量可空
var otherName : String?
otherName = null

空判斷

  • Java
if (text != null) {
    int length = text.length();
}
  • Kotlin
text?.let {
    val length = text.length
}
// 簡單寫法
val length = text?.length

字符串拼接

  • Java
String firstName = "ja";
String lastName = "va";
String message = "名字是: " + firstName + " " + lastName;
  • Kotlin
val firstName = "Ko"
val lastName = "tlin"
val message = "名字是: $firstName $lastName"

換行

  • Java
String text = "第一行\(zhòng)n" +
              "第二行\(zhòng)n" +
              "第三行";
  • Kotlin
//又叫多行文本字符串
val text = """
        |第一行
        |第二行
        |第三行
        """.trimMargin()
//trimMargin()方法是Kotlin自己的,用于替換掉字符串中的指定符號吊趾,點擊查看源碼可知默認值是"|"宛裕,所以我們可以依照自己的需求來進行替換

val text = """
        >First Line
        |Second Line
        >Third Line
        """.trimMargin(">")
//這樣就只會替換掉第一行和第三行前面的大于符號

三目運算符

  • Java
String text = x > 5 ? "x > 5" : "x <= 5";
  • Kotlin
val text = if (x > 5)
              "x > 5"
           else "x <= 5"

//簡單寫法
var s: String? = null
var text = s ?: "空了"  //s為空么?不為空返回自己论泛,為空返回"空了"

操作符

  • java
final int andResult  = a & b;
final int orResult   = a | b;
final int xorResult  = a ^ b;
final int rightShift = a >> 2;
final int leftShift  = a << 2;
  • Kotlin
val andResult  = a and b
val orResult   = a or b
val xorResult  = a xor b
val rightShift = a shr 2
val leftShift  = a shl 2

類型判斷和轉換 (聲明式)

  • Java
if (object instanceof Car) {
}
Car car = (Car) object;
  • Kotlin
if (object is Car) {
}
var car = object as Car

類型判斷和轉換 (隱式)

  • Java
if (object instanceof Car) {
   Car car = (Car) object;
}
  • Kotlin
if (object is Car) {
   var car = object // smart casting
}

多重條件

  • Java
if (score >= 0 && score <= 300) { }
  • Kotlin
if (score in 0..300) { }

更靈活的case語句

  • Java
int score = // some score;
String grade;
switch (score) {
    case 10:
    case 9:
        grade = "Excellent";
        break;
    case 8:
    case 7:
    case 6:
        grade = "Good";
        break;
    case 5:
    case 4:
        grade = "OK";
        break;
    case 3:
    case 2:
    case 1:
        grade = "Fail";
        break;
    default:
        grade = "Fail";
}
  • Kotlin
var score = // some score
var grade = when (score) {
    9, 10 -> "Excellent"
    in 6..8 -> "Good"
    4, 5 -> "OK"
    in 1..3 -> "Fail"
    else -> "Fail"
}

for循環(huán)

  • Java
for (int i = 1; i <= 10 ; i++) { }

for (int i = 1; i < 10 ; i++) { }

for (int i = 10; i >= 0 ; i--) { }

for (int i = 1; i <= 10 ; i+=2) { }

for (int i = 10; i >= 0 ; i-=2) { }

for (String item : collection) { }

for (Map.Entry<String, String> entry: map.entrySet()) { }
  • Kotlin
for (i in 1..10) { }

for (i in 1 until 10) { }

for (i in 10 downTo 0) { }

for (i in 1..10 step 2) { }

for (i in 10 downTo 1 step 2) { }

for (item in collection) { }

for ((key, value) in map) { }

更方便的集合操作一

  • Java
final List<Integer> listOfNumber = Arrays.asList(1, 2, 3, 4);

final Map<Integer, String> keyValue = new HashMap<Integer, String>();
map.put(1, "Java");
map.put(2, "Kotlin");
map.put(3, "Scala");
map.put(4, "Swift");

// Java 9
final List<Integer> listOfNumber = List.of(1, 2, 3, 4);

final Map<Integer, String> keyValue = Map.of(1, "Java",
                                             2, "Kotlin",
                                             3, "Scala",
                                             4, "Swift");
  • Kotlin
val listOfNumber = listOf(1, 2, 3, 4)
val keyValue = mapOf(1 to "Java",
                     2 to "Kotlin",
                     3 to "Scala",
                     4 to "Swift")

更方便的集合操作二

  • Java
List<String> list = new ArrayList();
list.add("Java");
list.add("Kotlin");
list.add("Scala");
list.add("Swift");

Map<Integer, String> map = new HashMap();
map.put(1, "Java");
map.put(2, "Kotlin");
map.put(3, "Scala");
map.put(4, "Swift");
  • Kotlin
var list = mutableListOf<String>()
list.add("Java")
list.add("Kotlin")
list.add("Scala")
list.add("Swift")

var map = mutableMapOf<Int, String>()
map.put(1, "Java")
map.put(2, "Kotlin")
map.put(3, "Scala")
map.put(4, "Swift")


遍歷

  • Java
// Java 7 和以前
for (Car car : cars) {
  System.out.println(car.speed);
}

// Java 8+
cars.forEach(car -> System.out.println(car.speed));

// Java 7 和以前
for (Car car : cars) {
  if (car.speed > 100) {
    System.out.println(car.speed);
  }
}

// Java 8+
cars.stream().filter(car -> car.speed > 100).forEach(car -> System.out.println(car.speed));
  • Kotlin
cars.forEach {
    println(it.speed)
}

cars.filter { it.speed > 100 }
      .forEach { println(it.speed)}

方法定義

  • Java
void doSomething() {
   
}

void doSomething(int... numbers) {
   
}
  • Kotlin
fun doSomething() {
   
}

fun doSomething(vararg numbers: Int) {
   
}

帶返回值的方法

  • Java
int getScore() {
  
   return score;
}
  • Kotlin
fun getScore(): Int {
   
   return score
}

//可直接在方法后返回
fun getScore(): Int = score

無結束符號

  • Java
int getScore(int value) {
   
    return 2 * value;
}
  • Kotlin
fun getScore(value: Int): Int {
   
   return 2 * value
}

//可直接在方法后返回
fun getScore(value: Int): Int = 2 * value

constructor 構造器

  • Java
public class Utils {

    private Utils() { 
     
    }
  
    public Utils(Int i ,String s){
      
    }
    
}
  • Kotlin
class Utils constructor(i: Int, s: String) {
    //這種方式的構造器是顯示構造器揩尸,聲明類的時候定好構造方法,實例化的時候必須按照參數(shù)列表進行實例化
  var utils = Utils(1, "")
}

class Utils (i: Int, s: String) {
    //上面的方式可省略 constructor 關鍵字
  var utils = Utils(1, "")
}

class Utils {
    constructor(i: Int, s: String)
    //上面同樣可以寫成這種樣子屁奏,構造函數(shù)單獨寫進類里面
  var utils = Utils(1, "")
}


class Utils private constructor(i: Int, s: String) {
    //如果 constructor 前面有修飾符岩榆,則不能省略
  var utils = Utils()
}

class Utils private constructor() {
    constructor(i: Int, s: String) : this() {
        //這種聲明表示我們有一個私有的構造方法,無參的,也可以有參朗恳,自己定義就好湿颅;然后我們公開了一個有參的構造方法供外部進行實例化
      var utils = Utils(1, "")
    }
}

class Utils constructor(i: Int = 2, s: String = "") {
    //如果構造方法中給定了默認值,那么在實例化對象的時候可以不傳入?yún)?shù)粥诫,不傳的話實例化出來的對象默認參數(shù)就是構造方法中的參數(shù)
  var utils = Utils()
  var utils = Utils(1)
  var utils = Utils("")
  var utils = Utils(1, "")
}

class Utils constructor(i: Int, s: String = "") {
    //但如果參數(shù)列表中有那種沒有給定值的變量時油航,實例化時必須要將他們都傳入構造方法
  var utils = Utils(1)
  var utils = Utils(1, "")
}


//引申內容,方法重載怀浆,注意和下面的 Kotlin 擴展函數(shù)區(qū)別開
class MainActivityKotlin {
  
  override fun onCreate(saveInstance: Bundle?) {
      super.onCreate(savedInstanceState)
        makeToast()
        makeToast("test")
        makeToast(time = Toast.LENGTH_LONG)
        makeToast("test", Toast.LENGTH_LONG)
        makeToast(msg = "test", time = Toast.LENGTH_LONG)
    }

    fun makeToast(msg: String = "msg", time: Int = Toast.LENGTH_SHORT) {
        Toast.makeText(this, msg, time).show()
    }
}

Kotlin 擴展函數(shù)

  • Kotlin
//擴展函數(shù)一般用在工具類的封裝上谊囚,可以對現(xiàn)有的函數(shù)在不繼承的情況下進行擴展
//object 聲明下面會講到
//擴展函數(shù)一般寫法是,fun 關鍵字 加上要擴展的類的類名执赡,以及方法名
object Utils {

    fun Activity.makeToast(msg: String = "msg", time: Int = Toast.LENGTH_SHORT) {
        Toast.makeText(this, msg, time).show()
    }
}

//調用時如下
//從調用處的包引入`import com.danlu.kotlindemo.Utils.makeToast`可以知道镰踏,擴展函數(shù)實際上是以靜態(tài)被引入的,事實上它是靜態(tài)解析的
//除了擴展函數(shù)沙合,還有擴展屬性
class MainActivityKotlin : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        makeToast()
        makeToast("test")
        makeToast(time = Toast.LENGTH_LONG)
        makeToast("test", Toast.LENGTH_LONG)
        makeToast(msg = "test", time = Toast.LENGTH_LONG)

    }
}

Get Set 構造器

  • Java
public class Developer {

    private String name;
    private int age;

    public Developer(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Developer developer = (Developer) o;

        if (age != developer.age) return false;
        return name != null ? name.equals(developer.name) : developer.name == null;

    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }

    @Override
    public String toString() {
        return "Developer{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • Kotlin
data class Developer(val name: String, val age: Int)

靜態(tài)

  • Java
public class Utils {

    private Utils() { 
    }
    
    public static int getDBVersion() {
        return CURRENT_DB_VERSION;
   }
}

int db_verison = Utils.getDBVersion();
  • Kotlin

Kotlin中使用object修飾靜態(tài)類奠伪,被修飾的類,可以使用類名.方法名的形式調用

object Utils {

    fun getDBVersion(): Int {
        return CURRENT_DB_VERSION
    }

}

var db_verison = Utils.getDBVersion()

Kotlin中使用companion object修飾靜態(tài)方法首懈,稱為伴生對象绊率,可以使用類名.方法名的形式調用

class Utils {

    companion object {
        fun getDBVersion(): Int {
            return CURRENT_DB_VERSION
        }
    }
}

var db_verison = Utils.getDBVersion()

權限修飾符

Java

  • public 對所有類可見
  • default 在同一包內可見,不寫默認default
  • protected 對同一包內的類和所有子類可見
  • private 在同一類內可見

Kotlin

  • public 凡是能夠訪問到這個類的地方, 同時也能訪問這個類的public成員究履,不寫默認是public
  • internal 在module之內, 凡是能夠訪問到這個類的地方, 同時也能訪問到這個類的internal成員
  • protected 與private一樣, 另外在子類中也可以訪問
  • private 表示只在這個類(以及它的所有成員)之內可以訪問滤否,不會自動生成getter setter方法

標簽(@)

  • Java
loop:
for (int i = 0; i < 100; i++) {
    loop1:
    for (int j = 0; j < 100; j++) {
        if (i == 3) { 
            continue loop1;
        } else if(i == 5) {
            continue loop;
        } else {
            break loop1;
        }
    }
}
  • Java中的標簽我們用的極少,它主要是用來控制流程語句的執(zhí)行最仑,continue藐俺,break。用法是:在語句內部需要continue泥彤,break的地方欲芹,在控制關鍵字后跟上你想控制的某個循環(huán)。簡單地說就是吟吝,一個循環(huán)一組標簽耀石,起始和終止位置標簽內容一致。在循環(huán)內部爸黄,任意地方可以控制其他循環(huán)。為了方便跳轉到指定位置

  • 在循環(huán)開始之前用自定義的名字加上英文冒號作為起始點揭鳞,然后書寫循環(huán)語句loop:循環(huán)語句體...continue/break loop;


  • Kotlin

val ints = intArrayOf(1, 2, 3, 0, 4, 5, 6)
ints.forEach foreach@ {
    if (it == 0) return@foreach
    print(it)
}
  • 由于Kotlin中幾乎萬物都是表達式炕贵,所以會有方法后直接跟運算體的寫法。Kotlin中的標簽和Java中大同小異野崇,只不過在循環(huán)控制上多了return称开,用來指定:在指定位置返回,上面的代碼就說明在 it== 0時返回,不打印鳖轰,所以打印結果是 123456
  • 另外Kotlin中的標簽還可以用在this關鍵字上清酥。Java中我們通常有XXXActivity.this的寫法,用來代指XXXActivity這個引用蕴侣,Kotlin中寫法是this@XXXActivity

init代碼塊

class Test public constructor(val i: Int) {
  
    // 只對主構造方法生效
    init {
      
    }

    constructor(i: Int, s: String) : this(i) {
      
    }

    fun xxx() {

    }
}

上述代碼中焰轻,定義了Test類的兩個構造方法,參數(shù)列表不同昆雀;實例化時可以:

val test = Test(1)
val test1 = Test(1, "")

而某些操作可能需要在默認/主構造方法中進行初始化辱志,也就是單參數(shù)的構造方法中,所以這時候就有init代碼塊狞膘;Kotlin主構造函數(shù)不能包含任何的代碼揩懒,所以初始化的代碼可以放到init塊中進行


lateinit 和 by lazy

對象/變量可以通過依賴注入來初始化, 或者在單元測試的setup方法中初始化挽封。 這種情況下已球,我們并不能直接在構造方法內提供一個非空構造器,但我們使用時依然想要避免對象/變量的空問題辅愿,所以智亮。。渠缕。

  • lateinit意思是延遲初始化鸽素,只有當變量/對象被聲明為var時才可使用
  • by lazy意思是懶初始化,只有當變量/對象被聲明為val時才可使用
// by lazy 使用方式后面跟大括號亦鳞,里面進行對象/變量的實例化/賦值
// by lazy 只會在第一次使用 danluUtil / name / id 的時候才會創(chuàng)建對象或者實例初始化變量
// 和 java 中的懶漢式單例一樣馍忽,使用時候判空,不為空直接返回對象燕差,為空的話實例化對象再返回
val danluUtil by lazy {
     DanluUtil(i, j)
}
val name by lazy {"名字"}
val id by lazy {1}


// lateinit 使用方式在 var 前面加上 lateinit 即可遭笋,后面跟上變量和變量類型
// lateinit 聲明的變量/對象,不能為空徒探,也不能被立即初始化:比如下面兩種方式都是不允許的:
// lateinit var danluUtil: DanluUtil = DanluUtil(i, j)
// lateinit var danluUtil: DanluUtil?
// 大致來說瓦呼,這段代碼將變量的初始化與定義分離開了
// 使用場景包括但不限于依賴注入框架(例如 Dagger2),那些預先聲明的變量也無法成功初始化测暗。在這種情況下央串,必須使用 lateinit 關鍵字確保變量在稍后將被初始化
lateinit var danluUtil: DanluUtil
// 聲明完畢后在需要用到的地方進行初始化:
danluUtil = DanluUtil(i, j)

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市碗啄,隨后出現(xiàn)的幾起案子质和,更是在濱河造成了極大的恐慌,老刑警劉巖稚字,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饲宿,死亡現(xiàn)場離奇詭異厦酬,居然都是意外死亡,警方通過查閱死者的電腦和手機瘫想,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門仗阅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人国夜,你說我怎么就攤上這事减噪。” “怎么了支竹?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵旋廷,是天一觀的道長。 經(jīng)常有香客問我礼搁,道長饶碘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任馒吴,我火速辦了婚禮扎运,結果婚禮上,老公的妹妹穿的比我還像新娘饮戳。我一直安慰自己豪治,他們只是感情好,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布扯罐。 她就那樣靜靜地躺著负拟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪歹河。 梳的紋絲不亂的頭發(fā)上掩浙,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機與錄音秸歧,去河邊找鬼厨姚。 笑死,一個胖子當著我的面吹牛键菱,可吹牛的內容都是我干的谬墙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼经备,長吁一口氣:“原來是場噩夢啊……” “哼斧蜕!你這毒婦竟也來了镜豹?” 一聲冷哼從身側響起绒怨,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤贡蓖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蘑志,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年急但,在試婚紗的時候發(fā)現(xiàn)自己被綠了澎媒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡波桩,死狀恐怖戒努,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情镐躲,我是刑警寧澤储玫,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站萤皂,受9級特大地震影響撒穷,放射性物質發(fā)生泄漏。R本人自食惡果不足惜裆熙,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一端礼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧入录,春花似錦蛤奥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蚀同,卻和暖如春缅刽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背唤崭。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工拷恨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谢肾。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓腕侄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親芦疏。 傳聞我的和親對象是個殘疾皇子冕杠,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內容