Kotlin 類和繼承
類宣告
Kotlin使用class
關鍵字宣告類:
class Foo {
}
宣告分為宣告頭和宣告體。其中宣告體是可選的,如下:
class Bar
建構函式
Kotlin建構函式分為主建構函式(primary constructor)和輔助建構函式(secondary constructor)。
主建構函式
主建構函式在類頭中,緊跟類名之後。如果不修改主建構函式的可見性也不為主建構函式添加註解,那麼constructor
關鍵字是可選的。主建構函式不包含任何程式碼,但是主建構函式將會執行init
關鍵字標記的程式碼塊。並且主建構函式的形參可以在init
程式碼塊中訪問,並用於初始化類成員變數:
class Person(name: String) {
init {
this.name = name.toUpperCase()
}
}
// 帶有可見性宣告或者是註解的主建構函式,contructor 關鍵字不能省略!!!
class Person private @Inject constructor(name: String) {
// ...
}
我們甚至可以直接在主建構函式中宣告並初始化類屬性(能做的也僅止於此了~)。如下:
class Person(val firstName: String, val lastName: String, var age: Int) {
// ...
}
輔助建構函式
類可以在類體中定義若干個輔助建構函式。輔助建構函式使用constructor
標記:
class Person(name: String) {
constructor(parent: Person, name: String): this(name) {
parent.children.add(this)
}
}
如上,如果函式定義了一個主建構函式,那麼所有的輔助建構函式必須使用this
呼叫主建構函式(直接呼叫或者通過呼叫其他輔助建構函式間接呼叫)。
如果沒有主建構函式或者輔助建構函式被定義,編譯器將自動生成無參主建構函式。主建構函式的預設訪問許可權為public
class DontCreateMe private constructor() {
}
如果執行在JVM上,類的主建構函式的所有引數都有預設值,編譯器將會自動生成無參建構函式,並使用預設引數值初始化。這有益於Kotlin類用於某些Java庫中。
建立類的例項
Kotlin中沒有new
關鍵字。所以相對於Java,省略掉new
就可以了~ 如下:
val apple = Apple()
val person = Person("Tom")
類繼承
類似於Java中的Object類,Any
類是Kotlin中所有其它類的預設基類。Any
類不是Java中的Object類,Any
類只包含equals()
、hashCode()
和toString()
方法。
描述繼承關係的方法與C++類似使用冒號,而不是使用Java中的“extend”或“implement”,Kotlin中沒有這倆關鍵字。
Koltin中的類預設是final
不可以被繼承,對於需要被繼承的類,必須顯式地標記為open
。
- 如果派生類有主建構函式,那麼必須在派生類主建構函式呼叫基類的建構函式完成基類初始化。
- 如果派生類沒有主建構函式,那麼就必須在派生類的每一個建構函式中都呼叫
super()
函式完成基類的初始化。
// 需要被繼承的基類,必須用open標記!
open class Base(p: Int)
// 派生類有主建構函式,必須在主建構函式之後呼叫基類的建構函式
class Derived_1(p: Int): Base(p)
// 派生類沒有主建構函式,必須在所有的輔助建構函式中呼叫基類的建構函式
class Derived_2 {
constructor(p: Int): super(p)
constructor(): super(0)
}
方法覆蓋(override)
不同於Java中可選的註解,Kotlin中方法覆蓋需要強制使用關鍵字open
和override
。
基類中被覆蓋的方法必須使用open
關鍵字標記,而派生類中覆蓋基類方法的新方法必須使用override
關鍵字標記:
open class Base {
open fun f1() {}
fun f2() {}
}
class Derived(): Base() {
override fun f1() {}
}
如上,基類中只有f1()
是可以被覆蓋的,並且在派生類中覆蓋f1()
必須使用override
關鍵字。
方法的標記總是不能和類的標記衝突,也即含有open
函式的類必須也是open
的!
如果派生類是open
的,含有override標記的方法會預設成為open
,這與之前的預設規則不同。如果不想讓派生類中覆蓋的方法進一步被覆蓋,那就需要新增final
關鍵字。如下:
open AnotherDerived(): Base() {
final override fun f1() {}
}
屬性覆蓋
屬性覆蓋和方法覆蓋差不多,同樣的open
和override
使用規則!
可以通過指定新的 get 方法,或提供初始值來覆蓋屬性。
可以使用var
屬性覆蓋val
屬性,這相當於在派生類中新增一個 set 方法;但是不能使用val
屬性覆蓋var
屬性,這相當於繼承了基類的 set 方法卻無法再派生類中使用。
interface Foo {
val count: Int
val x: Int
}
class Bar1(override val count: Int) : Foo
class Bar2 : Foo {
override var count: Int = 0
override val x: Int get {...}
}
呼叫基類的方法
一句話!使用 super
~
如果是內部類需要訪問外部類的基類。假設外部類名為 Outer
,那麼呼叫方法為[email protected]
。如下:
class Bar : Foo() {
override fun f() { /* ... */ }
override val x: String get() = "..."
inner class Baz {
fun g() {
super@Bar.f() // Calls Foo's implementation of f()
println(super@Bar.x) // Uses Foo's implementation of x's getter
}
}
}
覆蓋規則
- 如果繼承來的多個名稱(來自介面或者基類)衝突,派生類必須覆蓋這個方法;
- 在派生類中訪問基類(或者介面)名稱的實現,如果存在多個實現那麼必須使用
super<BaseType>
語法指定基類。
open class A {
open fun f() { print("A") }
fun a() { print("a") }
}
interface B {
fun f() { print("B") } // interface members are 'open' by default
fun b() { print("b") }
}
class C() : A(), B {
// The compiler requires f() to be overridden:
override fun f() {
super<A>.f() // call to A.f()
super<B>.f() // call to B.f()
}
}
抽象類
包含抽象方法的類必須是抽象類。
抽象類和抽象方法都是用abstract
關鍵字標記。
和介面一樣,抽象類和抽象介面預設為open
!
可以用一個抽象方法覆蓋非抽象方法。
相關推薦
Kotlin 類和繼承
類宣告 Kotlin使用class關鍵字宣告類: class Foo { } 宣告分為宣告頭和宣告體。其中宣告體是可選的,如下: class Bar 建構函式 Kotlin建構函式分為主建構函式(primary constructor)和輔助
Android知識體系梳理筆記五:Kotlin學習筆記一:類和繼承以及Anko(全)的基本使用
前言 對於kotlin,我是邊寫專案邊學的方式來學習的,這些都是在做專案的時候遇到的問題及擴充套件學習的時候記錄的,雖然有些內容不會涉及,但是我認為這種邊寫程式碼邊學習的方式特別有助於記憶,畢竟紙上得來終覺淺! 類和繼承 Kotlin較Java在繼承和實現
Kotlin-2.1-類和繼承
Kotlin-2.1-Classes and Inheritance 標籤:Kotlin 本節介紹了Kotlin中類和繼承的內容。類中包含首要構造器和次要構造器,還有類成員:屬性(Java中成員變數)和函式(Java中方法)。繼承主要講解的是如何過載
Kotlin程式設計之父類和繼承父類
Kotlin程式設計相關知識點介紹: 1. 預設繼承Any超類: 在Kotlin程式設計中,Any類是超類. public open class Any { public o
《C#圖解教程》讀書筆記之四:類和繼承
intern html pan 類中訪問 ted obj 小寫 his new 本篇已收錄至《C#圖解教程》讀書筆記目錄貼,點擊訪問該目錄可獲取更多內容。 一、萬物之宗:Object (1)除了特殊的Object類,其他所有類都是派生類,即使他們沒有顯示基類定義。
ts-類和繼承
world end spa nbsp moved move clas let new class Greeter { greeting: string; constructor(message: string) { this.greetin
Kotlin類與繼承
kotlin類Kotlin使用class關鍵字聲明類,類聲明由類名、類頭(指定其類型參數、主 構造函數等)和由大括號包圍的類體組成。類頭和類體都是可選的,如果一個類沒有類體大括號可省略class NoBody類的構造函數一類可以有一個主構造函數和一個或多個次構造函數。主構造函數是類頭的一部分:它跟在類名(和可
C#圖解 類和繼承
類的方法 png gpo 派生類 引用調用 有一個 圖解 匹配 關於 ---恢復內容開始--- 一:類繼承: 派生類成員組成如下: 1:自己聲明的成員 基類的成員 2:派生類不能刪除他所繼承的任何成員 例如:展示了名為OtherClass的類的聲明,他繼承的名
從零開始學Kotlin-類和對象(5)
int 文件中 cls 間接 main dcl this 調用 定義類 從零開始學Kotlin基礎篇系列文章 定義一個類 定義一個類,使用關鍵字class聲明,後面跟類名(不使用new) class demo5 {//定義一個類,使用關鍵字class聲明,後面跟類名
(轉載)【笨木頭Lua專欄】基礎補充20:面向對象——類和繼承
笑話 ava span 生成 code BE 手機 情況 忽略 終於來了,在Lua中的面向對象編程,相信目前學習Lua的大部分人都是為了開發手機網遊吧。而且基本都是奔著腳本語言的熱更新特性去的,所以全腳本開發變得十分流行。 對於普及不太廣的Lua(相對於C++、Java等主
子類和繼承
局部變量 不能 訪問權限 abs bstr 允許 fin 構造 個數 任何類都是Object類(java.lang包中的類)的子孫類。 子類和父類在同一個包中:不繼承private成員變量和private方法。 子類和父類不在同一個包中:不繼承private和友好訪問權限
How Javascript works (Javascript工作原理) (十五) 類和繼承及 Babel 和 TypeScript 代碼轉換探秘
屬性集 重寫 details 函數調用 有趣的 feature 性能優化 mage 轉化 個人總結:讀完這篇文章需要15分鐘,文章主要講解了Babel和TypeScript的工作原理,(例如對es6 類的轉換,是將原始es6代碼轉換為es5代碼,這些代碼中包含著類似於 _c
類和繼承
代碼 ret 包含 protect 轉換成 intern mas obj int 所有的類都派生自Object; 派生類引用可以轉換成基類; 屏蔽基類成員使用關鍵字new則可以屏蔽基類成員; 虛方法和覆寫方法 基類的方法被標記為virtual 在派生類中有匹配的ove
Kotlin類和物件
“用Kotlin開發android更簡潔( ̄_, ̄ )” 官方文件 翻譯文件 類和繼承 類的申明 和java一樣可以用這種方式 class Empty { } //kotlin提供了一種更為簡潔的方式建立無實體型別 class Empt
探究Java中的類和繼承--------Java的系列學習之路(15)
前言—— 今天是軍訓的第5天,昨天打了一天的軍體拳(哈哈哈,好好看本篇博文,不然博主一套軍體拳下去你可能會殘疾 :) 明天是最後一天了,今晚繼續做自己手頭上的事,避免碌碌無為。今天講解的內容——類和繼承,也是跟上一篇一樣,基礎且重要。 第5天沒把這篇文章寫完,今天第六
kotlin 類的繼承
與Java不同,kotlin 使用冒號,而Java 中使用extends, 注意冒號後面需要呼叫夫類的構造器。屬於單繼承,使用open 關鍵字允許繼承class package loaderman.demo open class Person (name:String){ prot
ES6類和繼承
首先看程式碼 class Person { constructor(name){ console.log(`建構函式執行了,${name}`) } } let p1=
Python3 類和繼承
1 import random as r 2 3 class Fish: 4 def __init__(self): 5 self.x = r.randint(0,10) 6 self.y = r.randint(0,10) 7 8 d
【原型和原型鏈】類和繼承
一、定義“類” ——建構函式 我們知道,JavaScript中沒有類的概念,我們只是通過函式來模仿類的行為,我們將它稱之為建構函式 建構函式分兩類,原生建構函式和自定義建構函式。原生建構函式像Array、Object,是執行環境自動提供的;
python中的類和繼承學習筆記
與C++和JAVA一樣,python也是一種面向物件的語言,但具體使用和C++有一些不同之處。下面按照封裝、繼承、多型的順序對python面向物件程式設計進行一個總結。封裝class testclass1: def __init__(self): pr