三,Kotlin-類型初步

1,類和接口

<1>類的相關概念

類的簡介

  • 類是一個抽象的概念
  • 類是具體某些特性的事物的概括
  • 不特定指代任何一個具體的事物
  • 例如:人,車,書 ;數(shù)字,字符串,字符也都是類
  • 寫法 class<類名>{成員}

對象的簡介

  • 對象是一個具體的概念,與類相對
  • 指代某一種類的具體個體

類和對象的關系

  • 一個類通常可以有很多個具體的對象
  • 一個對象的本質只能從屬于一個類
  • 對象經常被稱為類的對象或類的實例

<2>類的定義

class simpleClass1 {}
//一般的構造器寫法兒
class simpleClass2 {
    var string: String

    constructor(string: String) {
        this.string = string
    }
}

//主構造器
class simpleClass3(var string: String) {}

//主構造器和副構造器同時存在
class simpleClass4(var string: String) {
    var arg: Int = 0

    constructor(string: String, arg: Int) : this(string) {
        this.arg = arg
    }
}
//多個副構造器
class simpleClass5 {
    var name: String = ""
    var age: Int = 0
    constructor(name: String) {
        this.name = name
    }
    constructor(age: Int) {
        this.age = age
    }
}

Kotlin中有主構造器和副構造器的概念,主構造器會提取到類名的后面進行聲明,這樣每次構建該類時這必須通過主構造器,也可以在類中定義其他副構造器,但是所定義的副副構造器必須也有主構造器的聲明

<3>類的實例化
    val testClass = simpleClass3("wjf")
    println(testClass.string)
    val testClass2 = simpleClass5(1)
    println("${testClass2.age},${testClass2.name}")
<4>接口

接口的定義和實現(xiàn)

interface simpleInterface1 {
    fun simpleMethod(age: Int): Int
}

class simpleImi : simpleInterface1 {
    override fun simpleMethod(age: Int): Int {
        return 1
    }
}

與Java中不同的是Kotlin中override是一個關鍵字,當類實現(xiàn)接口時必須帶有該關鍵字

<5>抽象類

抽象類的定義

abstract class simpleABSClass {
    abstract fun absfun()
    open fun canBeOverride() {}
    fun cannotBeOverride() {}
}

open class simpleAbsIme(name: String, age: Int) : simpleABSClass() {
    override fun absfun() {
    }

    final override fun canBeOverride() {
        super.canBeOverride()
        println()
    }
}

class childSimpleAbsIme(name: String, age: Int) : simpleAbsIme(name, age) {
    //父類中的方法加了final 所以該子類不能被復寫
//    override fun canBeOverride() {
//        super.canBeOverride()
//        println()
//    }
}
這里有幾點需要注意
  • 除了接口和抽象類外定義的類,默認是final類型的不能被繼承,如果想繼承該類必須在類上加"open"字段
  • 除了接口和抽象類的類必須實現(xiàn)的方法外,默認定義的方法也是final類型的,如果子類想要復寫該方法,則必須在該方法前面加"open"字段
  • 如果實現(xiàn)了接口或抽象的方法,不想再被子類復寫那么可以在該方法前面加"final"字段
<6>類的屬性和類的屬性引用
class Person(name: String, age: Int) {
    //類的屬性,kotlin中自動生成getter和setter
    var name: String = name
    //    get() {
//        return field
//    }
//    set(value) {
//        field=value
//    }
    var age: Int = age
//    get() {
//        return age
//    }
//    set(value) {
//        field=value
//    }
}
fun main(args: Array<String>) {
    val aPerson = Person("WJF", 25)
    //由于該引用沒有具體的實現(xiàn)類所以調用set的時候需要傳入具體的receiver
    //類的屬性引用
    val testNoClass = Person::name
    testNoClass.set(aPerson, "WWJJFF")
    //有具體實現(xiàn)類的屬性引用
    val testHadClass = aPerson::name
    testHadClass.set("WJF")
}

2,擴展方法和擴展屬性

  • 一個類中沒有的方法可以通過擴展增加該方法
  • 定義形式為:fun receiver.<方法名>(參數(shù)列表):<返回值類型>
  • 調用:receiver.<方法名>(參數(shù)列表)
   println("WWJJFF".padding(5, '_'))
   println("_".times(10))

fun String.padding(cont: Int, char: Char = ' '): String {

   val padding = (1..cont).joinToString("") { char.toString() }
   return "${padding}${this}${padding}"
}

fun String.times(count: Int): String {
   return (1..count).joinToString("") { this }
}

除了給類增加擴展方法之外,還可以給類增加擴展屬性

如果類中沒有接收該擴展屬性的屬性,則只能定義成val形式的 只取返回值

class PoorGuy
//類的屬性=backing filed +getter +setter
//增加擴展屬性money類型為Double
val PoorGuy.money: Double
    get() {
        return 1.0
    }

val guy: PoorGuy = PoorGuy()
val aa = PoorGuy::money//正常的屬性引用
val bb = guy::money//具體對象的屬性引用
注意:接口中可以定義屬性,但是該屬性不能有backing filed;因為接口不能存儲東西,只能定義行為,接口中可以默認實現(xiàn),只能是行為,不能持有狀態(tài)

擴展方法的類型和普通方法的類型一樣

3,空類型安全

空類型安全:任意類型都有可空和不可空兩種;Kotlin提供了編譯級別的預防.

  • 每個方法的返回值或者每個變量在被使用到時如果可為null則編譯器會提示使用該值時需要進行null判斷;
  • 如果方法的返回則不可為null,則該使用到時可不進行判斷;
  • 如果已經確認可為null返回值的 已經為null,可使用'!!'直接調用
fun getNameNotNull(): String {
    return "not Null"
}
fun getNameCanNull(): String? {
    return null
}
fun getNameRealOne(): String? {
    return "A Real name"
}
fun main(args: Array<String>) {
    //不用判斷,因為肯定不為null
    println(getNameNotNull().length)
    //此時需要判斷,可能為null,若不判斷編譯不過,加?標示不為null時調用.length
    //若為為null則返回null
    println(getNameCanNull()?.length)
    //已經知道了結果肯定不為null,但是此時編譯器不認,需要使用!!告訴
    //編譯器我已經確定結果肯定不為null
    println(getNameRealOne()!!.length)
    val aName: String = getNameCanNull() ?: return
    //等同于if (aName==null) return
    println(aName.length)
}

任意類型 String Int Any Person等作為變量或者返回值類型時加"?"表示可為空類型,這樣在用到該變量或者返回值時需要進行判斷

例如:
var abc:String?=null
var p:Any?=null

安全訪問和elvis運算符

  1. "?." 安全訪問:如果變量為null則直接返回null
  2. "?:" elvis 運算符,如果前面的表達式返回為null 則返回后面的值
    val str:String?="Hellos"
    var len=str?.length?:0
String?和String是什么關系呢?String是String?的子類
平臺類型

Kotlin在訪問其他語言的對象或者方法時,如果返回String!或者Any!表示,返回的是平臺類型,這個時候需要開發(fā)者自己判斷null or not null

4,智能類型轉換

智能類型轉換:如果通過已知條件判斷出某個類所屬類型,可直接使用某類的特性即可,編譯器會盡可能的推導類型,遠離無用的類型轉換

open class Parent {}
class Child : Parent() {
    fun getName(): String {
        return "000";
    }
}
fun main(args: Array<String>) {
    val test: Parent = Child()
    if (test is Child) {
        //不用在使用時再次進行轉換
        println(test.getName())
    }
test.getName()
}
智能類型轉換是有作用范圍的,超過作用范圍后其類型還是原來定義的類型

如上例中最后的getName是沒有該方法的

安全類型轉換:在Java中如果類型轉換失敗則會拋出類型轉換異常,Kotlin中也有這種情況,為了避免它,可使用"as?"如果轉換失敗則返回null

open class Parent {}
class Child : Parent() {
    fun getName(): String {
        return "000";
    }
}
fun main(args: Array<String>) {
    val test2: Parent = Parent()
    //如果轉換失敗則返回null,不會拋出異常
    val child: Child? = test2 as? Child
    println(child?.getName())
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374