kotlin-2-類

1、kotlin 可見性修飾符

Java有四種:

  • public:包內(nèi)及包外的任何類均可以訪問(wèn)
  • protected:包內(nèi)的任何類,及包外的那些繼承了此類的子類才能訪問(wèn)
  • 默認(rèn):包內(nèi)的任何類都可以訪問(wèn)它,包外的任何類都不能訪問(wèn)
  • private:包內(nèi)包外的任何類均不能訪問(wèn)

Kotlin也是有四種:

  • public:默認(rèn)值,什么都不寫表示是public。
  • protected:和Java不同的是,即使在同一個(gè)包內(nèi),也不能訪問(wèn)protected方法。比private多了子類可以調(diào)用這一范圍。
  • internal:所在的整個(gè) module 可見
  • private:只在這個(gè)類內(nèi)部可見。
2、kotlin 主構(gòu)造函數(shù)

主構(gòu)造函數(shù) 寫在類頭中 如果你不希望別的類訪問(wèn)到這個(gè)變量,可以用private修飾

class Person constructor(firstName: String) {
}

如果主構(gòu)造函數(shù)沒有注解或可見性說(shuō)明,則 constructor 關(guān)鍵字是可以省略:
class Person (firstName: String) {
}

如果構(gòu)造函數(shù)有注解或可見性聲明,則 constructor 關(guān)鍵字是不可少的,并且可見性應(yīng)該在前
class Customer public @inject constructor (name: String) {...}

主構(gòu)造函數(shù)不能包含任意代碼。初始化代碼可以放在以 init 做前綴的初始化塊內(nèi)
class Person (firstName: String) {
  init {
        logger,info("Customer initialized with value ${firstName}")
    }
}

總結(jié)

  • 主構(gòu)造函數(shù) constructor寫在類頭中 ,沒有修飾符或者注解修飾可以省略constructor關(guān)鍵字
  • 主構(gòu)造函數(shù)中,如果參數(shù)加var會(huì)自動(dòng)生成對(duì)應(yīng)的屬性
  • 主構(gòu)造函數(shù)中,如果你不希望別的類訪問(wèn)到這個(gè)變量,可以用private修飾
  • init代碼塊也屬于主構(gòu)造器的一部分,也可以引用主構(gòu)造函數(shù)中的變量
  • 如果沒有主構(gòu)造函數(shù),也會(huì)隱式地創(chuàng)建一個(gè)無(wú)參構(gòu)造函數(shù),
  • 創(chuàng)建對(duì)象不需要 new
3、kotlin 次構(gòu)造函數(shù)

類也可以有二級(jí)構(gòu)造函數(shù),需要加前綴 constructor:

  • 次級(jí)構(gòu)造函數(shù)不能直接將參數(shù)轉(zhuǎn)換為屬性(不能加var)
  • 如果有主構(gòu)造器,那么次構(gòu)造器必須直接或者間接引用到主構(gòu)造器
    在同一個(gè)類中代理另一個(gè)構(gòu)造函數(shù)使用 this 關(guān)鍵字:
class Person(var firstName: String) {

    init {
        println("Customer initialized with value ${firstName}")
    }
    //var firstName: String? = null

    constructor() : this("Xiao ming")

    //不能直接將參數(shù)轉(zhuǎn)換為字段,
    constructor(firstName: String, lastName: String) : this(firstName) {
        this.lastName = lastName
    }

    var lastName: String? = null

}
4、 重寫get set方法

聲明一個(gè)屬性的完整語(yǔ)法是
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]

其初始器(initializer)、getter 和 setter 都是可選的。屬性類型如果可以從初始器 (或者從其 getter 返回值,如下文所示)中推斷出來(lái),也可以省略。

var allByDefault: Int?    *錯(cuò)誤:需要顯式初始化器,隱含默認(rèn) getter 和 setter
var initialized = 1  * 類型 Int、默認(rèn) getter 和 setter

在主構(gòu)造函數(shù)中 初始器(initializer) 才可以省略
class User {

    constructor(name: String, sex: Int) {
        this.name = name
        this.sex = sex
    }

    var name: String? = null
    var sex: Int? = null
        set(value) {
            // 此處 如果調(diào)用 sex 賦值 會(huì)造成死循環(huán) sex=0
            if (0 == value) { // 正確
                sexStr = "男"
            } else {
                sexStr = "女11"
            }
        }
    var sexStr: String? = null
//        get() {
//            // 此處 如果調(diào)用 sexStr 取值 會(huì)造成死循環(huán) if ("".equals(sexStr))
//            if (0 == sex) { // 正確
//                return "男"
//            }
//            return "女"
//        }

}

一般不需要重寫get set方法,在某些特定場(chǎng)景下重寫即可,但注意避免死循環(huán)

5、 繼承

kotlin 中所有的類和方法默認(rèn)都是final,不能直接繼承或者重寫,如果要繼承或重寫,需要加上open 關(guān)鍵字

open class Parent(var name: String) {

    var sex: String? = null

    init {
        this.name = "人"
    }

    // 沒有加open關(guān)鍵字,不能重寫
    fun showParent() {

    }

    // 加open關(guān)鍵字可以重寫
    open fun showSelf() {

    }
}

class Child( name: String):Parent (name){

    // 沒有加open關(guān)鍵字,不能重寫
//    fun showParent(){
//
//    }
    // 重寫加 override  一般寫法不換行
    override  fun showSelf(){

    }
}
6、 接口

接口用關(guān)鍵字 interface 來(lái)定義:
個(gè)類或?qū)ο罂梢詫?shí)現(xiàn)一個(gè)或多個(gè)接口

interface TestInterface {

    //可以在接口中聲明屬性,但屬性必須是抽象的 或 提供訪問(wèn)實(shí)現(xiàn)。
    //private var name: Int   //這種寫法錯(cuò)誤
    //var name: String? = null  //這種寫法錯(cuò)誤
    var name: String
    abstract var sex: Int
    fun test()
}
class TestInterfaceImpl(override var name: String, override var sex: Int) : TestInterface {
    override fun test() {
        println(name+"--"+sex)
    }
}

接口中聲明的,必須是抽象的 或 提供訪問(wèn)實(shí)現(xiàn)

7、 抽象
abstract class A {
    //abstract val  name: String ? = null   寫法錯(cuò)誤
    //val  name: String ? = null    寫法正確
    abstract val  name: String     //寫法正確

    //抽象類里已經(jīng)提供實(shí)現(xiàn)的方法 要想被重寫必須加open
    open fun test() {
        println(name)
    }
    abstract fun testNobody()
    //抽象類里的方法,可以不提供提供實(shí)現(xiàn)的時(shí)候需要用abstract關(guān)鍵字來(lái)描述 抽象的方法默認(rèn)是open的
}
class B:A() {

    override val  name: String=""
    override fun test() {
        println(name)
    }
    override fun testNobody(){
    }
}

抽象類里,抽象的方法默認(rèn)是open的,非抽象方法是final的
可以不提供提供實(shí)現(xiàn)的時(shí)候需要用abstract關(guān)鍵字來(lái)描述
抽象類里 可以有屬性,屬性必須是非null的或者抽象的

8、可以使用默認(rèn)參數(shù)來(lái)實(shí)現(xiàn)java重載類似的功能
    //函數(shù)參數(shù)可以設(shè)置默認(rèn)值,當(dāng)參數(shù)被忽略時(shí)會(huì)使用默認(rèn)值。這樣相比其他語(yǔ)言可以減少重載
    fun reformat(name: String, sex: Boolean = true,age: Int= 18) {

    }
    reformat("TOM")
    reformat("Tom", true, 18)
9、data

在Kotlin中一些只保存數(shù)據(jù)的類,稱為數(shù)據(jù)類(data class),
為了確保自動(dòng)生成的代碼一致性和有意義,數(shù)據(jù)類(data class)必須滿足以下要求:

  • 主構(gòu)造函數(shù)至少有一個(gè)參數(shù);
  • 主構(gòu)造函數(shù)的所有參數(shù)需標(biāo)記為val 或 var;
  • 數(shù)據(jù)類不能是抽象、開放、密封或者內(nèi)部的;

編譯器會(huì)為數(shù)據(jù)類(data class)自動(dòng)生成以下函數(shù):

  • equals()/hashCode()
  • toString() 默認(rèn)輸出"User(name=John, age=42)"
  • componentN() 按聲明順序?qū)?yīng)于所有屬性
  • copy()
10、copy
  • 當(dāng)要復(fù)制一個(gè)對(duì)象,只改變一些屬性,但其余不變,copy()就是為此而生:
        data class DataUser(val name: String, val age: Int)
        val u = DataUser(name = "lioil", age = 1)
        val u1 = u.copy("win")   //傳遞第一參數(shù),第二參數(shù)默認(rèn)
        val u2 = u.copy("win",2) //傳遞所有參數(shù)
        val u3 = u.copy(age = 3) //命名參數(shù),傳遞指定參數(shù)
        println("$u1,$u2,$u3")

DataUser(name=win, age=1),DataUser(name=win, age=2),DataUser(name=lioil, age=3)
11、apply
  • apply函數(shù),在函數(shù)范圍內(nèi),可以任意調(diào)用該對(duì)象的任意方法,并返回該對(duì)象
data class DataUser(val name: String, var age: Int){
    fun test (){
        println("test")
    }
}

val u = DataUser(name = "lioil", age = 1)
val u1 =  u.apply {
       age = 15
       test()
}
println("$u1")

mame 是無(wú)法修改的 因?yàn)槭莢al
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容