Kotlin 基礎(一)

Kotlin 是一門很是優秀的語言,兼容了 N 多種語言的優勢,學習 Kotlin 有助於提高咱們多層編程開發的認識。

Kotlin 是靜態類型的開源編程語言,能夠有效地運行在 Java虛擬機(JVM)上。Kotlin 由 JetBrains 開發,並獲得谷歌的強力支持。java

1、從類開始

1.1 導包

與 Java 同樣,Kotlin 也含有默認導入的特性。Kotlin 的每一個文件都默認導入了以下經常使用包:編程

-- kotlin.*
-- kotlin.annotation.*
-- kotlin.collections.*
-- kotlin.comparisons.*
-- kotlin.io.*
-- kotlin.ranges.*
-- kotlin.sequences.*
-- kotlin.text.*

Kotlin 的導包方式和 Java 也相似,但有一點,Kotlin 不支持靜態導入。Kotlin 爲何不支持靜態導入?由於靜態導入會增長代碼的閱讀成本。api

1.2 函數聲明

fun Kotlin 中用關鍵字 fun 聲明函數。數組

override fun getRandom(type: String): Observable<JsonResult<List<FuckGoods>>> { return api.getRandom(type) }

Kotlin 爲何使用 fun 來聲明函數?爲何不是 function? 或者 def?安全

JetBrains 團隊說: 「We use ‘fun’ because we like it – and yes, we do know what the word means in English.」性能優化

咱們使用 「fun」 由於咱們喜歡它,並且咱們知道這個詞在英語中是啥意思!架構

「fun」 在英語中是什麼意思? 來自谷歌翻譯的 fun 的翻譯: 動詞 開玩笑,名詞 玩笑。併發

1.3 參數

參數聲明

Kotlin 的參數使用 Pascal 符號定義,參數之間和 java 相似經過 」 , 」 分隔,參數須要指明類型。app

fun test(count: Int, test2: Int) { }

爲何 Kotlin 像 Pascal 同樣,參數聲明類型要在參數名後面?count: Intdom

Rob Pike 曾解釋過這個問題: 由於這樣更加清晰易懂,固然,我以爲這樣存在很大的爭議,不過也和工程師自身的習慣有關係。

默認參數

Kotlin 參數能夠設置默認值,當須要忽略該參數的時候可使用參數的默認值。Like this:

off: Int = 0

fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size ) { ... }
空返回值

在 Java 中返回空關鍵字爲 void,在 Kotlin 中的空返回值爲 Unit,而且能夠省略 .Unit 和 void 不一樣,Unit 是個真實的類而且是個單例。

// 不省略
fun printHello(name: String?): Unit { ...}
// 省略
fun printHello(name: String?) { ...}

爲何使用Unit?

「Unit」 just stands for 「something that has only one value」, it’s a traditional name, comes from functional languages. I agree that this name is not very intuitive, but we failed to invent a better name.

「Unit」 表明 「只有一個值」,它是一個來自函數式語言的傳統的名稱。我贊成這個名字不是很直觀,但咱們沒有想到一個更好的名字。

1.4 局部變量

Kotlin 局部變量分爲 val 和 var。

var 關鍵字聲明可變屬性,和 Java 變量聲明相似;

val 關鍵字聲明只讀屬性,和 Java 中 final 變量相似,在初始化時須要賦值,之後不能改變。更多的應該使用 val 關鍵字。

val a: Int = 1 var x = 5

爲何使用 val 關鍵字?

val 具備 Immutable 或 readonly 的特性,一旦建立,不可改變。沒有競爭條件,沒有併發問題,無需去同步,保證了線程安全,不須要擔憂空安全問題。

爲何是 val 和 var?

由於 val 是 value 的縮寫,而 var 是 variable。

2、特性

2.1 有趣的冒號

從語法上來看,Kotlin 大量使用了冒號(:)這一符號,能夠總結一下,這個冒號在 Kotlin 中究竟表明什麼。

考慮下面四種場景:

  • 在變量定義中,表明變量的類型
  • 在類定義中,表明基類的類型
  • 在函數定義中,表明函數返回值的類型
  • 在匿名對象中,表明對象的類型

2.2 字符串模板

Kotlin 中容許字符串中包含 「$」 開頭嵌入表達式。

在 Java 中咱們可能須要這樣定義來拼接字符串:

String message = "n = " + n;

可是在 Kotlin 中,咱們能夠直接使用 「$」 拼接」:

val message = "n = $n"

很顯然,使用字符串模板,能夠提升咱們的開發效率。

2.3 條件表達式

這是一個普通的條件判斷語句。

fun maxOf(a: Int, b: Int): Int {
    if (a > b) {
        return a    
    } else {
        return b
    }
}

在 Kotlin 中,if 表達式具備返回值,故能夠表述成以下方式:

fun maxOf(a: Int, b: Int) = if (a > b) a else b

2.4 關於空安全

空安全性是 Kotlin 的一大特點,在 Java 中,NPE (NullPointerException) 是常客,可是在 Kotlin 中,咱們將會看到 NPE。

對於可爲空的變量,咱們必須用 「?」 將其特殊聲明爲一個具備空值的變量:

var b: String? = "abc"

而正常使用是這樣的

var b: String = "abc"

若是咱們直接調用 b 的話就會報錯

val l = b.length()

那麼,咱們該如何使用可空變量呢?

咱們可使用安全操做符 「?.」 對其進行方法調用,Like this:

b?.length()

若是 b 爲空,則返回空;不然,調用 b.length()。

爲何要使用空安全操做符呢?

這使得咱們解決了判空的問題,與 「!= null」 永遠說再見,並且,空安全符在鏈式調用中會顯得很是優美。

bob?.department?.head?.name

2.5 安全轉換

在 Java 中,類型轉換錯誤就會產生 ClassCastException,而在 Kotlin 中,咱們能夠經過安全轉換 「as?」 來避免這個問題。

val aInt: Int? = a as? Int

若是轉換失敗,則返回空,不然返回正確數據。

2.6 類型檢查

在 Java 中,校驗一個類型可使用 「instanceof」,在 Kotlin 中,咱們可使用 「is」

fun getStringLength(obj: Any): Int? {  if (obj is String) {    return obj.length  }  return null}

2.7 區間

在 kotlin 中,區間表示一個範圍,是 ClosedRange 的子類,IntRange 是最經常使用的。

寫法:

  • 0..100 表示 [0,100] 包括100
  • 0 until 表示 [0,100) 不包括100
  • i in 0..100 判斷 i 是否在區間 [0,100] 中 in

val range:IntRange = 0..100
val range_exculsive:IntRange = 0 until 100

2.8 集合

在 Kotlin 中,可使用 in 操做符對集合進行迭代遍歷。

for (item in items) {
    println(item)
}

Kotlin 更支持 lambda 對集合進行過濾等操做;

fruits .filter { it.startsWith("a") } .sortedBy { it } .map { it.toUpperCase() } .forEach { println(it) }

2.9 循環

for 循環

在 Kotlin 中,for 循環使用 in 關鍵字進行遍歷。

val items = listOf("apple", "banana", "kiwi")
for (item in items) {
    println(item)
}
while 循環

這是 while 循環的一個簡單示例

val items = listOf("apple", "banana", "kiwi")
var index = 0
while (index < items.size) {
    println("item at $index is ${items[index]}")
    index++
}
when 表達式

在 Kotlin 中使用 When 表達式來代替 Switch 語句,一個簡單的示例以下:

fun describe(obj: Any): String = when (obj) {
    1 -> "One"
    "Hello" -> "Greeting"
    is Long -> "Long" 
    !is String -> "Not a string" 
    else -> "Unknown"
}

3、Kotlin 與 Java 不同的地方

3.1 對象

Java 的寫法

MainActivity.this

Kotlin 的寫法

this@MainActivity

3.2 類

Java 的寫法

MainActivity.class

Kotlin 的寫法

MainActivity::class.java

3.3 繼承

Java 的寫法

public class MainActivity extends AppCompatActivity {

}

Kotlin 的寫法(在 Kotlin 中被繼承類必須被 open 關鍵字修飾)

class MainActivity : AppCompatActivity() {

}

3.4 變量

Java 的寫法

Intent intent = new Intent();

Kotlin 的寫法

var intent = Intent()

3.5 常量

Java 的寫法

final String text = "";

Kotlin 的寫法

val text = ""

3.6 靜態常量

Java 的寫法

public class MainActivity extends AppCompatActivity {

    static final String text = "";
}

Kotlin 的寫法(須要注意的是要把靜態變量定義在類上方)

const val text = ""

class MainActivity : AppCompatActivity() {

}

3.7 定義方法

Java 的寫法

public void test(String message) {

}

Kotlin 的寫法(Unit 跟 void 同樣效果)

fun test(message : String) : Unit {

}

// 在 Kotlin 能夠省略 Unit 這種返回值

fun test(message : String) {

}

3.8 重載方法

Java 的寫法

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

Kotlin 的寫法

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
}

3.9 基本數據類型

Java 的寫法

int i = 1;
long l = 2;
boolean b = true;
float f = 0;
double d = 0;
char c = 'A';
String s = "text";

Kotlin 的寫法

var i : Int = 1
var l : Long = 2
var b : Boolean = true
var f : Float = 0F
var d : Double = 0.0
var c : Char = 'A'
var s : String = "text"

更簡潔點能夠這樣,自動推倒類型

var i = 1
var l = 2
var b = true
var f = 0F
var d = 0.0
var c = 'A'
var s = "text"

3.10 比較類型

Java 的寫法

if ("" instanceof String) {

}

Kotlin 的寫法

if ("" is String) {

}

3.11 轉換符

Java 的寫法

int number = 100;
System.out.println(String.format("商品數量有%d", number));

Kotlin 的寫法

var number = 100
println("商品數量有${number}")

換種簡潔的寫法

var number = 100
println("商品數量有$number")

若是不想字符串被轉義可使用&dollar;

var number = 100
println("商品數量有\$number")

3.12 字符串比較

Java 的寫法

String s1 = "text";
String s2 = "text";
if (s1.equals(s2)) {

}

Kotlin 的寫法(Kotlin 對字符串比較的寫法進行優化了,其餘類型對象對比仍是要用 equals 方法)

var s1 = "text"
var s2 = "text"
if (s1 == s2) {

}

3.13 數組

Java 的寫法

int[] array1 = {1, 2, 3};
float[] array2 = {1f, 2f, 3f};
String[] array3 = {"1", "2", "3"};

Kotlin 的寫法

val array1 = intArrayOf(1, 2, 3)
val array2 = floatArrayOf(1f, 2f, 3f)
val array3 = arrayListOf("1", "2", "3")

3.14 循環

Java 的寫法

String[] array = {"1", "2", "3"};

for (int i = 0; i < array.length; i++) {
    System.out.println(array[i]);
}

Kotlin 的寫法

val array = arrayListOf("1", "2", "3")

for (i in array.indices) {
    println(array[i])
}

3.15 角標循環

Java 的寫法

String[] array = {"1", "2", "3"};

for (int i = 1; i < array.length; i++) {
    System.out.println(array[i]);
}

Kotlin 的寫法(這種寫法在 Kotlin 中稱之爲區間)

val array = arrayListOf("1", "2", "3")

for (i in IntRange(1, array.size - 1)) {
    println(array[i])
}

// 換種更簡潔的寫法

val array = arrayListOf("1", "2", "3")

for (i in 1..array.size - 1) {
    println(array[i])
}

// 編譯器提示要咱們換種寫法

val array = arrayListOf("1", "2", "3")

for (i in 1 until array.size) {
    println(array[i])
}

3.16 高級循環

Java 的寫法

String[] array = {"1", "2", "3"};

for (String text : array) {
    System.out.println(text);
}

Kotlin 的寫法

val array = arrayListOf("1", "2", "3")

for (text in array) {
    println(text)
}

3.17 判斷器

Java 的寫法

int count = 1;

switch (count) {
    case 0:
        System.out.println(count);
        break;
    case 1:
    case 2:
        System.out.println(count);
        break;
    default:
        System.out.println(count);
        break;
}

Kotlin 的寫法

var count = 1

when (count) {
    0 -> {
        println(count)
    }
    in 1..2 -> {
        println(count)
    }
    else -> {
        println(count)
    }
}

var count = 1

// 換種更簡潔的寫法

when (count) {
    0 -> println(count)
    in 1..2 -> println(count)
    else -> println(count)
}

3.18 構造函數

Java 的寫法

public class MyView extends View {

    public MyView(Context context) {
        this(context, null);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}

Kotlin 的寫法

class MyView : View {

    constructor(context : Context) : this(context, null) {

    }

    constructor(context : Context, attrs : AttributeSet?) : this(context, attrs, 0) {

    }

    constructor(context : Context, attrs : AttributeSet?, defStyleAttr : Int) : super(context, attrs, defStyleAttr) {

    }
}

// 換種更簡潔的寫法

class MyView : View {

    constructor(context : Context) : this(context, null)

    constructor(context : Context, attrs : AttributeSet?) : this(context, attrs, 0)

    constructor(context : Context, attrs : AttributeSet?, defStyleAttr : Int) : super(context, attrs, defStyleAttr)
}

// 只有一種構造函數的還能夠這樣寫

class MyView(context: Context?) : View(context) {

}

3.19 類建立

Java 的寫法

public class Person {

    String name;
    int age;

    public Person(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;
    }
}

Person person = new Person("Android輪子哥", 100);
person.setName("HJQ");
person.setAge(50);
System.out.println("name: " + person.getName() + ", age: " + person.getAge());

Kotlin 的寫法(若是不想暴露成員變量的 set 方法,能夠將 var 改爲 val )

class Person {

    var name : String? = null
    get() = field
    set(value) {field = value}

    var age : Int = 0
    get() = field
    set(value) {field = value}
}

// 換種更簡潔的寫法

class Person(var name : String, var age : Int)

var person = Person("Android輪子哥", 100)
person.name = "HJQ"
person.age = 50
println("name: {$person.name}, age: {$person.age}")

3.20 私有化 set 方法

Java 的寫法

public class Person {

    String name;
    int age;

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

Kotlin 的寫法

class Person {

    var name : String? = null
    private set

    var age : Int = 0
    private set
}

3.21 私有化 get 方法

Java 的寫法

public class Person {

    String name;
    int age;

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

    private String getName() {
        return name;
    }

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

    private int getAge() {
        return age;
    }

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

Kotlin 的寫法

class Person {

    private var name : String? = null

    private var age : Int = 0
}

3.22 枚舉

Java 的寫法

enum Sex {

    MAN(true), WOMAN(false);

    Sex(boolean isMan) {}
}

Kotlin 的寫法

enum class Sex (var isMan: Boolean) {

    MAN(true), WOMAN(false)
}

3.23 接口

Java 的寫法

public interface Callback {
    void onSuccess();
    void onFail();
}

Kotlin 的寫法(Kotlin 接口方法裏面能夠本身實現)

interface Callback {
    fun onSuccess()
    fun onFail()
}

3.24 匿名內部類

Java 的寫法

new Callback() {

    @Override
    public void onSuccess() {

    }

    @Override
    public void onFail() {

    }
};

Kotlin 的寫法

object:Callback {

    override fun onSuccess() {

    }

    override fun onFail() {

    }
}

3.25 內部類

Java 的寫法

public class MainActivity extends AppCompatActivity {

    public class MyTask {

    }
}

Kotlin 的寫法

class MainActivity : AppCompatActivity() {

    inner class MyTask {

    }
}

3.26 內部類訪問外部類同名變量

Java 的寫法

String name = "Xmamiga";

public class MyTask {

    String name = "CCHIP";

    public void show() {
        System.out.println(name + "---" + MainActivity.this.name);
    }
}

Kotlin 的寫法

var name = "Xmamiga"

inner class MyTask {

    var name = "CCHIP"

    fun show() {
        println(name + "---" + this@MainActivity.name)
    }
}

3.27 抽象類

Java 的寫法

public abstract class BaseActivity extends AppCompatActivity implements Runnable {

    abstract void init();
}

Kotlin 的寫法

abstract class BaseActivity : AppCompatActivity(), Runnable {

    abstract fun init()
}

3.28 靜態變量和方法

Java 的寫法

public class ToastUtils {

    public static Toast cToast;

    public static void show() {
        cToast.show();
    }
}

Kotlin 的寫法(在 Kotlin 將這種方式稱之爲伴生對象)

companion object ToastUtils {

    var cToast : Toast? = null

    fun show() {
        cToast!!.show()
    }
}

3.29 可變參數

Java 的寫法

public int add(int... array) {
    int count = 0;
    for (int i : array) {
        count += i;
    }
    return count;
}

Kotlin 的寫法

fun add(vararg array: Int) : Int {
    var count = 0
    //for (i in array) {
    //    count += i
    //}
    array.forEach {
        count += it
    }
    return count
}

3.30 泛型

Java 的寫法

public class Bean<T extends String> {

    T data;
    public Bean(T t) {
        this.data = t;
    }
}

Bean<String> bean = new Bean<>("666666");

Kotlin 的寫法

class Bean<T : Comparable<String>>(t: T) {
    var data = t
}

var bean = Bean<String>("666666")

// 換種更簡潔的寫法

var bean = Bean("666666")

3.31 構造代碼塊

Java 的寫法

public class MainActivity extends AppCompatActivity {

    int number;

    {
        number = 1;
    }
}

Kotlin 的寫法

class MainActivity : AppCompatActivity() {

    var number = 0

    init {
        number = 1
    }
}

3.32 靜態代碼塊

Java 的寫法

public class MainActivity extends AppCompatActivity {

    static int number;

    static {
        number = 1;
    }
}

Kotlin 的寫法

class MainActivity : AppCompatActivity() {

    companion object {

        var number = 0

        init {
            number = 1
        }
    }
}

3.33 方法代碼塊

Java 的寫法

void test(){
    {
        int a = 1;
    }
}

Kotlin 的寫法

fun test() {
    run {
        var a =1
    }
}

3.34 可見修飾符

Java 的寫法(默認爲 default)

修飾符 做用
public 全部類可見
protected 子類可見
default 同一包下的類可見
private 僅對本身類可見

Kotlin 的寫法(默認爲 public)

修飾符 做用
public 全部類可見
internal 同 Module 下的類可見
protected 子類可見
private 僅對本身類可見
    • *

須要更多相關的代碼源碼等等的能夠加我羣討論哦 本專欄爲那些想要進階成爲高級Android工程師所準備。 從初中級轉向高級工程師須要從技術的廣度,深度上都有必定的造詣。因此本專欄就主要爲你們分享一些技術,技術原理等。 包含源碼解析,自定義View,動畫實現,架構分享等。 內容難度適中,篇幅精煉,天天只需花上十幾分鍾閱讀便可。 你們能夠跟我一塊兒探討,歡迎加羣探討,有flutter—底層開發-性能優化—移動架構—資深UI工程師 —NDK-人工智能相關專業人員和視頻教學資料 。後續還有最新鴻蒙系統相關內容分享。羣號:892872246(進羣能夠選取以下部分資料分享)

clipboard.png

相關文章
相關標籤/搜索