以下是 Kotlin 繼承 的基礎概念,包括類別的定義、open 關鍵字、覆寫方法、屬性、多型(Polymorphism)、抽象類別等。
1. 繼承的基本概念#
在 Kotlin 中:
- 類別預設為
final,無法被繼承。如果需要繼承,父類別必須使用 open 關鍵字修飾。 - 子類別使用
: 語法繼承父類別。 - 子類別必須直接或間接呼叫到父類別的建構函數。
1
2
3
4
5
6
7
| open class 父類別名稱 {
// 父類別內容
}
class 子類別名稱 : 父類別名稱() {
// 子類別內容
}
|
2. 簡單範例#
範例:定義父類別和子類別#
1
2
3
4
5
6
7
8
9
10
11
12
| open class Animal {
fun eat() {
println("This animal is eating.")
}
}
class Dog : Animal()
fun main() {
val dog = Dog()
dog.eat() // 輸出:This animal is eating.
}
|
3. 覆寫方法#
父類別的方法或屬性如果要被覆寫,必須用 open 關鍵字修飾,而子類別需要用 override 關鍵字進行覆寫。
範例:#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| open class Animal {
open fun sound() {
println("Some generic animal sound.")
}
}
class Dog : Animal() {
override fun sound() {
println("The dog barks.")
}
}
fun main() {
val animal: Animal = Dog()
animal.sound() // 輸出:The dog barks.
}
|
4. 覆寫屬性#
與方法類似,屬性必須使用 open 關鍵字修飾才能被覆寫。
範例:#
1
2
3
4
5
6
7
8
9
10
11
12
| open class Animal {
open val sound: String = "Some generic animal sound"
}
class Dog : Animal() {
override val sound: String = "Bark"
}
fun main() {
val dog = Dog()
println(dog.sound) // 輸出:Bark
}
|
5. 呼叫父類別方法#
使用 super 關鍵字來呼叫父類別的方法或存取屬性。
範例:#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| open class Animal {
open fun sound() {
println("Some generic animal sound.")
}
}
class Cat : Animal() {
override fun sound() {
super.sound() // 呼叫父類別的 sound 方法
println("The cat meows.")
}
}
fun main() {
val cat = Cat()
cat.sound()
// 輸出:
// Some generic animal sound.
// The cat meows.
}
|
6. 呼叫父類別的建構函數#
- 子類別必須直接或間接呼叫到父類別的建構函數。
- 子類別的主建構函數使用
: 父類別名稱(...) 語法,呼叫父類別的建構函數。 - 子類別的次建構函數使用
: super(...) 語法,呼叫父類別的建構函數。
範例 1:子類別主建構函數呼叫父類別#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| open class Animal(val name: String) {
init {
println("Animal initialized with name: $name")
}
}
class Dog(name: String, val breed: String) : Animal(name) {
init {
println("Dog initialized with breed: $breed")
}
}
fun main() {
val dog = Dog("Buddy", "Golden Retriever")
// 輸出:
// Animal initialized with name: Buddy
// Dog initialized with breed: Golden Retriever
}
|
- 父類別
Animal 的建構函數需要 name 參數。 - 子類別
Dog 使用 : Animal(name) 呼叫父類別建構函數。 - 父類別的
init 區塊先執行,接著執行子類別的 init 區塊。
範例 2:子類別次建構函數呼叫父類別#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| open class Animal {
val name: String
constructor(name: String) {
this.name = name
println("Animal initialized with name: $name")
}
}
class Dog : Animal {
val breed: String
constructor(name: String, breed: String) : super(name) {
this.breed = breed
println("Dog initialized with breed: $breed")
}
}
fun main() {
val dog = Dog("Buddy", "Labrador")
// 輸出:
// Animal initialized with name: Buddy
// Dog initialized with breed: Labrador
}
|
- 父類別
Animal 提供了一個次建構函數(constructor)。 - 子類別
Dog 在其次建構函數中,使用 : super(name) 呼叫父類別的次建構函數。 - 初始化順序仍然是先執行父類別的初始化邏輯,然後執行子類別的初始化邏輯。
7. 抽象類別#
抽象類別無法直接實例化,通常用於定義通用行為,由子類別實作具體內容。
範例:#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| abstract class Animal {
abstract fun sound()
}
class Dog : Animal() {
override fun sound() {
println("The dog barks.")
}
}
fun main() {
val dog = Dog()
dog.sound() // 輸出:The dog barks.
}
|
8. 多型(Polymorphism)#
多型允許父類別型別的變數指向子類別的實例,並執行子類別覆寫的行為。
範例:多型應用#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| open class Animal {
open fun sound() {
println("Some generic animal sound.")
}
}
class Dog : Animal() {
override fun sound() {
println("The dog barks.")
}
}
class Cat : Animal() {
override fun sound() {
println("The cat meows.")
}
}
fun main() {
val animals: List<Animal> = listOf(Dog(), Cat())
for (animal in animals) {
animal.sound()
}
// 輸出:
// The dog barks.
// The cat meows.
}
|
9. 繼承與可見性修飾符#
可見性修飾符#
public(預設):所有地方可見。protected:僅子類別可見。internal:同一模組內可見。private:僅限類別內部可見。
範例:使用 protected#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| open class Animal {
protected fun protectedMethod() {
println("This is a protected method.")
}
}
class Dog : Animal() {
fun callProtected() {
protectedMethod() // 可以存取 protected 方法
}
}
fun main() {
val dog = Dog()
dog.callProtected() // 輸出:This is a protected method.
}
|
10. 繼承的限制:final 關鍵字#
使用 final 關鍵字可以禁止繼承或覆寫。
範例:禁止繼承或覆寫#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| open class Animal {
final fun sound() {
println("This sound cannot be overridden.")
}
}
class Dog : Animal() {
// override fun sound() { } // 錯誤:無法覆寫被 final 修飾的方法
}
fun main() {
val dog = Dog()
dog.sound() // 輸出:This sound cannot be overridden.
}
|
Reference#
https://kotlinlang.org/docs/inheritance.html