Kotlin學(xué)習(xí)筆記之 6 繼承

首發(fā)于公眾號: DSGtalk1989

6.Kotlin 繼承

  • Any

    Any是所有類的超類,就像java中的Object。但它并不等同于Object,除了equals()``hashCode()``toString()沒有其他任何成員。

  • 繼承和實現(xiàn)':'

    之前我們已經(jīng)知道了接口是interface,可被繼承的類是open,抽象類是abstract

    跟java不同的是,java中extends是繼承,implements是實現(xiàn)。而在kotlin中跟在:后面,不管是接口還是類,沒有先后順序。也就是說:既可以繼承也可以實現(xiàn),互相用,隔開

    open class Person3 {
         open var sex: String = "unknow"
     
         init {
             println("基類初始化")
         }
     }
     
     interface Grand {
         fun make()
     }
     
     class Student : Grand, Person3() {
         override fun make() {
         }
     
         override var sex: String = "male"
     }
    
  • 基類構(gòu)造和子類構(gòu)造

    首先我們先看下最基礎(chǔ)的構(gòu)造,在經(jīng)過編譯之后分別是什么情況的

    • 默認(rèn)定義

      ```js
      //kt
      class Person(name: String) {    
      }
      
      //decompiled
      public final class Person {
         public Person(@NotNull String name) {
            //無視,這段代碼之后會出現(xiàn)很多次
            Intrinsics.checkParameterIsNotNull(name, "name");
            super();
         }
      }
      ```
      

      我們看到經(jīng)過編譯之后,就是定義了一個final的class Personname只是一個構(gòu)造函數(shù)的傳參而已

    • var定義

      我們嘗試著在構(gòu)造傳參name前加一個var看看,會發(fā)現(xiàn)編譯之后的差別不是一點點。

      ```js
      //kt
      class Person(var name: String) {    
      }
      
      //decompiled
      public final class Person {
         @NotNull
         private String name;
      
         @NotNull
         public final String getName() {
            return this.name;
         }
      
         public final void setName(@NotNull String var1) {
            Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
            this.name = var1;
         }
      
         public Person(@NotNull String name) {
            Intrinsics.checkParameterIsNotNull(name, "name");
            super();
            this.name = name;
         }
      }
      ```
      

      編譯過程幫我們創(chuàng)建了一個同名的屬性name,并且提供了namesetget方法,也就是說一旦主構(gòu)造函數(shù)中出現(xiàn)了var(我這邊故意重點說了主構(gòu)造函數(shù),因為次構(gòu)造函數(shù)中無法使用var),那么所描述的這個參數(shù)就可以變得在類中可以被訪問和修改,name就變成了Person的一部分了。

OK,我們接下去看一下兩種情況下作為基類被繼承了之后會有什么地方的不同。

前面我們有提到,kotlin中無論使用什么修飾符,對于參數(shù)本身來說,編譯成java代碼之后始終是private的,只是通過getset方法來體現(xiàn)修飾符,

如果我們的子類是這么定義的:

//kt
class Sun(name : String): Person(name){   
}

//decompiled
public final class Sun extends Person {
    public Sun(@NotNull String name) {
       Intrinsics.checkParameterIsNotNull(name, "name");
       super(name);
    }
 }

看起來完全沒有問題。這時候我們把name寫上var,我們先不反編譯,直接按照上面的理解,應(yīng)該是這樣的

```js
//kt
class Sun(var name : String): Person(name){ 
}

//decompiled
public final class Sun extends Person {
   @NotNull
   private String name;

   @NotNull
   public final String getName() {
      return this.name;
   }

   public final void setName(@NotNull String var1) {
      Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
      this.name = var1;
   }

   public Sun(@NotNull String name) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.name = name;
   }
}
```

乍一看,沒有問題。但是實際上這么寫IDE直接會報錯。Sun的方法getNamesetNamepublic final的,由于父類也有相同的方法getNamesetName。犯了java的大忌,子類出現(xiàn)了父類的同名函數(shù),父類的函數(shù)還他么是final的。

也就是說,除了父類是非final字段,子類不能出現(xiàn)相同的字段。

綜上所述,只要不是open形容的字段,都不能在子類出現(xiàn)重復(fù)的字段名。無論是val還是var

  • varval復(fù)寫關(guān)系

    val無法復(fù)寫var,不要當(dāng)做概念去背。

    前面我們說過,一個屬性必須要用open來形容才能被子類復(fù)寫。這是其一

    其二,kotlin中我們是直接去操作屬性的,因為編譯成java文件是通過gettersetter方法做訪問和修改。var是可以訪問并修改,val只能訪問無法修改。

    父類中本身可以訪問并修改的,在子類中變得只能訪問了,是不允許的。繼承關(guān)系我們只能拓展而不能縮減,子類必須包含父類。

  • 子類構(gòu)造函數(shù)的影響

    首先,一個類class肯定會有一個構(gòu)造函數(shù)。那么對于子類來說需要注意什么呢。

    我們先來看一個隱式主構(gòu)造函數(shù)的類:

    open class Parent{
    }
    

    我們前面說到,一旦沒有顯式的跟在類名后面申明constructor,或者(),并且在類體中沒有出現(xiàn)次級構(gòu)造函數(shù)constructor。我們就認(rèn)為有一個隱式的無參的主構(gòu)造函數(shù)。

    這時候我們繼承一下,并且嘗試著什么都不做

    class Sun : Parent{
    }
    

    你會發(fā)現(xiàn)Person下面有根紅線報錯了,寫道

    This type has a constructor, and thus must be initialized here

    父類有構(gòu)造器,必須要進(jìn)行初始化。也就是說我們必須顯式或者隱式的去調(diào)一次Parent的無參的構(gòu)造函數(shù)。

    方式有很多種,我們先看第一種:

    class Sun : Parent(){
    }
    

    直接在父類后面來個括號即可。

    你會發(fā)現(xiàn)加()和不加的前后經(jīng)過編譯得到的java文件是一樣的,都是

    public final class Sun extends Parent {
    }
    

    實際上,這邊我們用有參構(gòu)造去講,會更加容易理解。比如我們針對Parent類添加一個有參的主構(gòu)造函數(shù),并且保留無參構(gòu)造函數(shù)。

    open class Parent(name : String){
    
    }
    

    子類分別調(diào)用和不調(diào)用父類的構(gòu)造函數(shù),所編譯出來的效果是明顯不同的。

    //kt
    class Sun1 : Parent{
    } 
    
    class Sun2 : Parent(){
    } 
    
    class Sun3 : Parent("tom"){
    }
    
    
    //decompiled
    public final class Sun1 extends Parent {
    }
    
    public final class Sun2 extends Parent {
    }
    
    public final class Sun3 extends Parent {
         public Sun3() {
            super("tom");
         }
    }
    

Sun1是無法編譯通過的,所以出來的decompiled實際上是沒有意義,上面說過調(diào)用父類的無參構(gòu)造和不調(diào)用最終出來的結(jié)果是一樣的,所以我們直接看Sun2即可

Sun2Sun3連在一起看,首先我們知道,在java中,每一個類如果沒有單獨的去申明他的構(gòu)造函數(shù),那么他們都將有一個默認(rèn)的無參構(gòu)造函數(shù)。并且又有繼承,所以Sun2實際上是這樣的

public final class Sun2 extends Parent {
      public Sun2() {
         super();
      }
 }

Kotlin學(xué)習(xí)筆記之 1 基礎(chǔ)語法

Kotlin學(xué)習(xí)筆記之 2 基本數(shù)據(jù)類型

Kotlin學(xué)習(xí)筆記之 3 條件控制

Kotlin學(xué)習(xí)筆記之 4 循環(huán)控制

Kotlin學(xué)習(xí)筆記之 5 類和對象

Kotlin學(xué)習(xí)筆記之 6 繼承

Kotlin學(xué)習(xí)筆記之 7 接口

Kotlin學(xué)習(xí)筆記之 8 擴(kuò)展

Kotlin學(xué)習(xí)筆記之 9 數(shù)據(jù)類與密封類

Kotlin學(xué)習(xí)筆記之 10 泛型

Kotlin學(xué)習(xí)筆記之 11 枚舉類

Kotlin學(xué)習(xí)筆記之 12 對象表達(dá)式和對象聲明

Kotlin學(xué)習(xí)筆記之 13 基礎(chǔ)操作符run、with、let、also、apply

Kotlin學(xué)習(xí)筆記之 14 包與導(dǎo)入

Kotlin學(xué)習(xí)筆記之 15 伴生對象

Kotlin學(xué)習(xí)筆記之 16 委托

Kotlin學(xué)習(xí)筆記之 17 可觀察屬性

Kotlin學(xué)習(xí)筆記之 18 函數(shù)

Kotlin學(xué)習(xí)筆記之 19 高階函數(shù)與 lambda 表達(dá)式

Kotlin學(xué)習(xí)筆記之 20 內(nèi)聯(lián)函數(shù)

Kotlin學(xué)習(xí)筆記之 21 解構(gòu)聲明

Kotlin學(xué)習(xí)筆記之 22 集合

Kotlin學(xué)習(xí)筆記之 23 相等判斷

Kotlin學(xué)習(xí)筆記之 24 操作符重載

Kotlin學(xué)習(xí)筆記之 25 異常捕捉

Kotlin學(xué)習(xí)筆記之 26 反射

Kotlin學(xué)習(xí)筆記之 27 類型別名

Kotlin學(xué)習(xí)筆記之 28 協(xié)程基礎(chǔ)

Kotlin學(xué)習(xí)筆記之 29 上下文與調(diào)度器

Kotlin學(xué)習(xí)筆記之 30 協(xié)程取消與超時

Kotlin學(xué)習(xí)筆記之 31 協(xié)程掛起函數(shù)的組合

Kotlin學(xué)習(xí)筆記之 32 協(xié)程異常處理

Kotlin學(xué)習(xí)筆記之 33 協(xié)程 & Retrofit

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內(nèi)容