Kotlin基礎學習篇:各類關鍵字學習

android攻城獅獅獅 發佈 2022-06-03T16:20:14.407065+00:00

1、Kotlin 繼承open關鍵字//TODO Kotlin 基礎與重載的open關鍵字//所有的類默認是final修飾的,不能被繼承與Java相反//加open相當於移除finalopen class Person(val name:String){ pri

1、Kotlin 繼承open關鍵字

//TODO Kotlin 基礎與重載的open關鍵字

//所有的類默認是final修飾的,不能被繼承與Java相反
//加open相當於移除final
open class Person(val name:String){

    private fun showName() = "人類的名字是[$name]"

    //所有的函數默認也是final修飾,不能被重寫
    open fun myPrintlin() = println(showName())

}

class Student(val subName:String) : Person(subName){

    private fun showName() = "子類的姓名是[$subName]"

    override fun myPrintlin() = println(showName())

}

fun main() {
    val person:Person = Student("張三")
    person.myPrintlin()
}

2、Kotlin 類型轉換

//TODO Kotlin 類型轉換
import java.io.File
//所有的類默認是final修飾的,不能被繼承與Java相反
//加open相當於移除final
open class Person(val name: String) {

    fun showName() = "人類的名字是[$name]"

    //所有的函數默認也是final修飾,不能被重寫
    open fun myPrintlin() = println(showName())

}

class Student(val subName: String) : Person(subName) {

    fun showName2() = "子類的姓名是[$subName]"

    override fun myPrintlin() = println(showName2())

}

fun main() {
    val p: Person = Student("王五")
    p.myPrintlin()

    println(p is Person)

    println(p is Student)

    println(p is File)

    //is +as

    if (p is Student) {
        (p as Student).myPrintlin()
    }

    if (p is Person) {
//        (p as Person).myPrintlin()
        println((p as Person).showName())
    }
}

3、Kotlin智能轉換

import java.io.File

//TODO Kotlin 智能類型轉換

//所有的類默認是final修飾的,不能被繼承與Java相反
//加open相當於移除final
open class Person(val name:String){

    fun showName() = "人類的名字是[$name]"

    //所有的函數默認也是final修飾,不能被重寫
    open fun myPrintlin() = println(showName())

    fun methodPerson() = println("我是父類的方法...")

}

class Student(val subName:String) : Person(subName){

    fun showName2() = "子類的姓名是[$subName]"

    override fun myPrintlin() = println(showName2())
    fun methodStudent() = println("我是子類的方法...")

}

fun main() {
    val p:Person = Student("王五")

    //is +as

    (p as Student).methodStudent()
    //根據上面P as 說明已經轉過的類型,下面可以直接調用子類的方法
    p.methodStudent()

}

4、Kotlin 中Any類

//TODO Kotlin Any超類 相當於Java 的Object

//在Kotlin中類隱式繼承了Any(),不寫,默認也有
//Any 設計中,只提供標準,看不到實現
class obj1:Any()

fun main() {

    println(obj1().toString())

}

只提供標準,不會進行實現

5、Kotlin Object

object KtBase {
    /*
    object 類 背後做了什麼?

    public static final KtBase INSTANCE;

    private KtBase(){} //主構造廢除一樣的效果

    public final void show(){
        String var1 = "我是show函數";

        ...

        System.out.println(var1)

    }

    //這個區域是object不同點

    static{

        KtBase var0 = new KtBase();
        INSTANCE = var0;
        String var1 = "KtBase init..."
        System.out.println(var0)
    }

     */

    init {
        println("KtBase init...")
    }

    fun show() = println("我是show函數")

}

fun main() {
    // object KtBase既是單例的實類,也是類名
    //小結: 既然是單例的實例,又是類名,只有一個創建,這就是典型的單例

    println(KtBase) // 背後代碼println(KtBase.INSTANCE)
    println(KtBase)
    println(KtBase)

    //不需要帶() KTBase.INSTANCE
    println(KtBase.show())
}

INSTANCE在靜態代碼塊里進行初始化

6、Kotlin對象表達式

open class KtBase {

    open fun add(info: String) = println("add:$info")

    open fun del(info: String) = println("del:$info")

}

//具名方式實現
class KTBase1 : KtBase() {
    override fun add(info: String) {
//            super.add(info)
        println("我是具名對象add:$info")
    }

    override fun del(info: String) {
//            super.del(info)
        println("我是具名對象del:$info")
    }
}
fun main() {
    //匿名對象表達式
    val p = object : KtBase() {
        override fun add(info: String) {
//            super.add(info)
            println("我是匿名對象add:$info")
        }

        override fun del(info: String) {
//            super.del(info)
            println("我是匿名對象del:$info")
        }
    }

    p.add("李元霸")
    p.del("李連杰")

    //具名方式實現
    val p2 = KTBase1()
    p2.add("李元霸")
    p2.del("李連杰")

    //java 接口方式
    val p3 = object :Runnable {
        override fun run() {
            println("Runnable run ..")
        }
    }
    p3.run()

    //java最簡潔方式
    val p4 = Runnable {
        println("Runnable run2 ..")
    }
    p4.run()
}

7、Kotlin 伴生對象

//TODO Kotlin 伴生對象

class KtBase {

    //伴生對象由來:Kotlin中沒有static靜態,伴生很大程度上和Java的這種static靜態差不多
    companion object {
        val info = "testInfo"
        fun showInfo() = println("顯示:$info")
    }
    /* companion object{} 背後邏輯
     private static final String info = "testInfo";
     public static final KtBase.Companion campoanion = new Companion();

     */
}

//伴生對象只會初始化一次

fun main() {
    //背後代碼 KtBase.Companion.getInfo
    println(KtBase.info)
    //背後代碼 KtBase.Companion.showInfo()
    KtBase.showInfo()

    //new KtBase() ,無論構建多少次,伴生對象只有一次
    KtBase()
    KtBase()
    KtBase()
    KtBase()
}

8、Kotlin 內部類inner與嵌套類

//TODO Kotlin 嵌套類 和內部類

//內部類特點 :內部類能訪問外部的類
//外部的類 能訪問內部的類,加inner修飾符
class Body(_bodyInfo: String) {

    val bodyInfo = _bodyInfo

    //默認情況下:內部類不能訪問外部類,要加修飾符稱為內部類,才可以訪問外部類
    inner class Heart {
        fun run() = println("心臟訪問身體信息:$bodyInfo")
    }

    inner class Kidney {
        fun work() = println("腎臟訪問身體信息:$bodyInfo")
    }

    inner class Hand {
        inner class LeftHand {
            fun work() = println("左手訪問身體信息:$bodyInfo")
        }

        inner class RightHand {
            fun work() = println("右手腎臟訪問身體信息:$bodyInfo")
        }
    }
}

//嵌套類,默認情況下是嵌套類
//嵌套類特點:外部的類 能訪問內部的類 ,嵌套類不能訪問內部外部類的成員
class Outer {

    val info = "ok"

    fun show() {
        Nested().output()
    }

    class Nested {
        fun output() = println()

    }
}

fun main() {
    //內部類
    Body("isOk").Heart().run()
    Body("isOk").Hand().LeftHand().work()

    //嵌套類
    Outer.Nested().output()
}

9、Kotlin數據類data 修飾

//普通類
//生成的只有普通變量,set get方法
class ResponseResultBean(var msg: String, var code: Int, var data: String)

//數據量 ,一般情況下用於javaBean
//除了生成普通變量,set get方法,還有hashCode,equals(),解構操作,toString()
//數據類生成的方法更多
data class ResponseResultBean2(var msg: String, var code: Int, var data: String)

fun main() {

    //val (v1,v2,v3) = list

    //ResponseResultBean@610455d6 ,調用Any.toString(),只提供標準,windows實現列印的
    println(ResponseResultBean("loginSuccess", 200, "登錄成功的數據"))

    //data 數據類,額外生成toString(),重寫了父類的toString()函數
    //ResponseResultBean2(msg=loginSuccess, code=200, data=登錄成功的數據)
    println(ResponseResultBean2("loginSuccess", 200, "登錄成功的數據"))

    println()

    // == 值得比較,===引用的比較

    // == Any的父類 由平台實現,由兩個對象引用進行比較,所以返回false
    println(
        ResponseResultBean("loginSuccess", 200, "登錄成功的數據") ==
                ResponseResultBean("loginSuccess", 200, "登錄成功的數據")

    )

    // == Any的父類 ,會重寫父類的equals,進行的值得比較,返回為true
    println(
        ResponseResultBean2("loginSuccess", 200, "登錄成功的數據") ==
                ResponseResultBean2("loginSuccess", 200, "登錄成功的數據")

    )

}

Kotlin 數據類data使用場景

1:伺服器請求回來的響應 JavaBean 基本上可以使用數據類

2、條件類至少必須有一個參數的主構造函數

3、數據類必須有參數, var val 的參數

4、 數據類不能使用abstract ,不能open saled ,inner等等修飾, 數據類只做數據載入的事情

5、需求; 比較,copy. toString,結構等豐富功能,可以使用數據類

10、Kotlin copy函數

//TODO Kotlin copy函數

data class KtBase(var name: String,var age :Int){

    var coreInfo:String = ""

    //次構造
    constructor(name: String) :this(name,99){
        println("次構造被調用")
        coreInfo = "增加非常核心的內容信息"
    }

    override fun toString(): String {
        return "toString name:$name,age:$age,coreInfo:$coreInfo"
    }

}

/*
//默認生成的toString ,hashCode(),equals(),只管主構造,不管次構造
@NotNull
public String toString() {
    return "KtBase(name=" + this.name + ", age=" + this.age + ")";
}
*/

fun main() {
    val p1 = KtBase("李元霸")//調用次構造初始化

    println(p1)

    val newP2 = p1.copy("李連杰",78)
    println(newP2)

    // copy toString hashCode equals
    //注意事項:使用copy時,只考慮主構造,copy調用的也是主構造, 必須考慮次構造內容
}

11、Kotlin 解構函數

//TODO Kotlin 解構聲明  component
//數據類自己就解構

class Student(var name:String,var age:Int,var sex:Char){

    //注意:順序必須是component1 ,component2 ,component3 和成員一一對應
    operator fun component1() = name
    operator fun component2() = age
    operator fun component3() = age
}

/*
//默認生成的toString ,hashCode(),equals(),只管主構造,不管次構造
@NotNull
public String toString() {
    return "KtBase(name=" + this.name + ", age=" + this.age + ")";
}
*/

data class Student2(var name:String,var age: Int,var sex: Char)

fun main() {
    val(name,age,sex) = Student("李四",89,'男')
    println("普通類 解構後:name:$name,age:$age,sex:$sex")

    val(name1,age1,sex1) = Student2("李四",89,'男')
    println("數據類 解構後:name:$name1,age:$age1,sex:$sex1")

    val (_,age2,_) = Student("李四",89,'男')
    println("數據類 解構後:age:$age2")

}

12、Kotlin 運算符重載

//TODO Kotlin 運算符重載

class AddClass(number1:Int,number2:Int)

data class AddClass2(var number1: Int,var number2: Int){
    operator fun plus(p1:AddClass2) : Int{
        return (number1+p1.number1) + (number2 + p1.number2)
    }

}

fun main() {

    //運算符重載 C++ 里 +
    //KT中plus代表+
//    AddClass2(1,1)+AddClass2(2,2)
    println( AddClass2(1,1)+AddClass2(2,2))

}

查看所有可用的運算符重載

13、Kotlin 中枚舉

//枚舉也是一個class
enum class Week {
    星期一,
    星期二,
    星期三,
    星期四,
    星期五,
    星期六,
    星期日

}

//枚舉類學習
fun main() {

    //枚舉的值等價於枚舉本身
    println(Week.星期一)
    println(Week.星期五)

    println(Week.星期二 is Week)
}

14、Kotlin中枚舉詳細使用

//TODO Kotlin 枚舉類詳細使用

data class LimbsInfo(var LimbsInfo:String,var length: Int){
    fun show(){
        println("${LimbsInfo}的長度是:$length")
    }
}

//枚舉是一個class,就是為了枚舉有更好的功能
enum  class Limbs(private var limbsInfo: LimbsInfo){
    LETF_HAND(LimbsInfo("左手",88)),//左手
    RIGHT_HAND(LimbsInfo("右手",88)),//右手

    LETF_FOOT(LimbsInfo("左腳",88)),//左腳
    RIGHT_FOOT(LimbsInfo("右腳",88))//右腳
    ;//結束枚舉值

    // 1、WEEK() 這時候再定義單調的枚舉值,就報錯了,必須所有枚舉值,保持一致效果
    //2、枚舉主構造的參數必須和枚舉(參數) 保持一致

    fun show() = "四肢是:${limbsInfo.LimbsInfo}的長度是:${limbsInfo.length}"

    fun updateData(limbsInfo: LimbsInfo){
        println("更新前的數據是:${this.limbsInfo}}")
        this.limbsInfo.LimbsInfo = limbsInfo.LimbsInfo
        this.limbsInfo.length = limbsInfo.length
        println("更新後的數據是:${this.limbsInfo}}")
    }
}

//枚舉類學習
fun main() {
    //顯示枚舉值
    //一般不會這麼用
    /*println(Limbs().show())
    println(Limbs.show())*/

    //一般用法如下
    println(Limbs.LETF_HAND.show())
    println(Limbs.RIGHT_HAND.show())
    println(Limbs.LETF_FOOT.show())
    println(Limbs.RIGHT_FOOT.show())

    //更新枚舉值
    Limbs.RIGHT_HAND.updateData(LimbsInfo("右手2",99))
    Limbs.LETF_FOOT.updateData(LimbsInfo("左腳2",99))

}

//TODO Kotlin 枚舉類詳細使用

enum class Exam{
    Eraction1,//分數差
    Eraction2,//分數及格
    Eraction3,//分數良好
    Eraction4,//分數優秀
    ;//枚舉結束

    //得到優秀學生的名字 ,枚舉類做到此需求,很麻煩 //引出密封類
    var studentName:String? = null
}

class Teacher(private val exam: Exam){
    fun show() :String=
        when(exam){
            Exam.Eraction1 -> "該學生分數很差"
            Exam.Eraction2 -> "該學生分數及格"
            Exam.Eraction3 -> "該學生分數良好"
            Exam.Eraction4 -> "該學生分數優秀"
            //else -> 由於show函數是使用枚舉類型來判斷處理,這個屬於代數數據類型,不需要寫else
            //因為when表達式很明確,就這四種類型,不會出現其他,所以可以不寫

        }

}

//枚舉類學習
fun main() {

    println(Teacher(Exam.Eraction1).show())
    println(Teacher(Exam.Eraction3).show())

}

15、Kotlin密封類

import sun.security.util.Length
import kotlin.math.E

//TODO Kotlin 密封類詳細使用
//密封類成員 必須有類型且繼承本類 sealed

sealed class Exam {
    //不需要任何成員,寫成object
    object Eraction1 : Exam()//分數差
    object Eraction2 : Exam()//分數及格
    object Eraction3 : Exam()//分數良好

    class Eraction4(val studentName2: String) : Exam()//分數優秀

    //得到優秀學生的名字 ,枚舉類做到此需求,很麻煩 //引出密封類
    var studentName: String? = null
}

class Teacher(private val exam: Exam) {
    fun show(): String =
        when (exam) {
            is Exam.Eraction1 -> "該學生分數很差"
            is Exam.Eraction2 -> "該學生分數及格"
            is Exam.Eraction3 -> "該學生分數良好"
            is Exam.Eraction4 -> "該學生分數優秀:該學生的姓名是:${(this.exam as Exam.Eraction4).studentName2}"
            else -> " error"
        }

}

//枚舉類學習
fun main() {

    println(Teacher(Exam.Eraction1).show())
    println(Teacher(Exam.Eraction2).show())
    println(Teacher(Exam.Eraction3).show())
    println(Teacher(Exam.Eraction4("李四")).show())
    println(Teacher(Exam.Eraction4("王五")).show())

    println(Exam.Eraction1 === Exam.Eraction1)
    println(Exam.Eraction4("AAA") === Exam.Eraction4("AAA")) //class 有兩個不同的對象是false,不是object
}

作者:胖胖狼
連結:https://juejin.cn/post/7101308364562366471

關鍵字: