# Swift 繼承
繼承我們可以理解為一個類獲取了另外一個類的方法和屬性。
當一個類繼承其它類時,繼承類叫子類,被繼承類叫超類(或父類)
在 Swift 中,類可以調用和訪問超類的方法,屬性和下標腳本,并且可以重寫它們。
我們也可以為類中繼承來的屬性添加屬性觀察器。
## 基類
沒有繼承其它類的類,稱之為基類(Base Class)。
以下實例中我們定義了基類 StudDetails ,描述了學生(stname)及其各科成績的分數(mark1、mark2、mark3):
```
class StudDetails {
var stname: String!
var mark1: Int!
var mark2: Int!
var mark3: Int!
init(stname: String, mark1: Int, mark2: Int, mark3: Int) {
self.stname = stname
self.mark1 = mark1
self.mark2 = mark2
self.mark3 = mark3
}
}
let stname = "swift"
let mark1 = 98
let mark2 = 89
let mark3 = 76
print(stname)
print(mark1)
print(mark2)
print(mark3)
```
以上程序執行輸出結果為:
```
swift
98
89
76
```
```
swift
98
89
76
```
## 子類
子類指的是在一個已有類的基礎上創建一個新的類。
為了指明某個類的超類,將超類名寫在子類名的后面,用冒號(:)分隔,語法格式如下
```
class SomeClass: SomeSuperclass {
// 類的定義
}
```
### 實例
以下實例中我們定義了超類 StudDetails,然后使用子類 Tom 繼承它:
```
class StudDetails
{
var mark1: Int;
var mark2: Int;
init(stm1:Int, results stm2:Int)
{
mark1 = stm1;
mark2 = stm2;
}
func show()
{
print("Mark1:\(self.mark1), Mark2:\(self.mark2)")
}
}
class Tom : StudDetails
{
init()
{
super.init(stm1: 93, results: 89)
}
}
let tom = Tom()
tom.show()
```
以上程序執行輸出結果為:
```
Mark1:93, Mark2:89
```
## 重寫(Overriding)
子類可以通過繼承來的實例方法,類方法,實例屬性,或下標腳本來實現自己的定制功能,我們把這種行為叫重寫(overriding)。
我們可以使用 override 關鍵字來實現重寫。
### 訪問超類的方法、屬性及下標腳本
你可以通過使用super前綴來訪問超類的方法,屬性或下標腳本。
| 重寫 | 訪問方法,屬性,下標腳本 |
| --- | --- |
| 方法 | super.somemethod() |
| 屬性 | super.someProperty() |
| 下標腳本 | super[someIndex] |
## 重寫方法和屬性
### 重寫方法
在我們的子類中我們可以使用 override 關鍵字來重寫超類的方法。
以下實例中我們重寫了 show() 方法:
```
class SuperClass {
func show() {
print("這是超類 SuperClass")
}
}
class SubClass: SuperClass {
override func show() {
print("這是子類 SubClass")
}
}
let superClass = SuperClass()
superClass.show()
let subClass = SubClass()
subClass.show()
```
以上程序執行輸出結果為:
```
這是超類 SuperClass
這是子類 SubClass
```
### 重寫屬性
你可以提供定制的 getter(或 setter)來重寫任意繼承來的屬性,無論繼承來的屬性是存儲型的還是計算型的屬性。
子類并不知道繼承來的屬性是存儲型的還是計算型的,它只知道繼承來的屬性會有一個名字和類型。所以你在重寫一個屬性時,必需將它的名字和類型都寫出來。
注意點:
* 如果你在重寫屬性中提供了 setter,那么你也一定要提供 getter。
* 如果你不想在重寫版本中的 getter 里修改繼承來的屬性值,你可以直接通過super.someProperty來返回繼承來的值,其中someProperty是你要重寫的屬性的名字。
以下實例我們定義了超類 Circle 及子類 Rectangle, 在 Rectangle 類中我們重寫屬性 area:
```
class Circle {
var radius = 12.5
var area: String {
return "矩形半徑 \(radius) "
}
}
// 繼承超類 Circle
class Rectangle: Circle {
var print = 7
override var area: String {
return super.area + " ,但現在被重寫為 \(print)"
}
}
let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("Radius \(rect.area)")
```
以上程序執行輸出結果為:
```
Radius 矩形半徑 25.0 ,但現在被重寫為 3
```
## 重寫屬性觀察器
你可以在屬性重寫中為一個繼承來的屬性添加屬性觀察器。這樣一來,當繼承來的屬性值發生改變時,你就會監測到。
**注意:**你不可以為繼承來的常量存儲型屬性或繼承來的只讀計算型屬性添加屬性觀察器。
```
class Circle {
var radius = 12.5
var area: String {
return "矩形半徑為 \(radius) "
}
}
class Rectangle: Circle {
var print = 7
override var area: String {
return super.area + " ,但現在被重寫為 \(print)"
}
}
let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("半徑: \(rect.area)")
class Square: Rectangle {
override var radius: Double {
didSet {
print = Int(radius/5.0)+1
}
}
}
let sq = Square()
sq.radius = 100.0
print("半徑: \(sq.area)")
```
```
半徑: 矩形半徑為 25.0 ,但現在被重寫為 3
半徑: 矩形半徑為 100.0 ,但現在被重寫為 21
```
## 防止重寫
我們可以使用 final 關鍵字防止它們被重寫。
如果你重寫了final方法,屬性或下標腳本,在編譯時會報錯。
你可以通過在關鍵字class前添加final特性(final class)來將整個類標記為 final 的,這樣的類是不可被繼承的,否則會報編譯錯誤。
```
final class Circle {
final var radius = 12.5
var area: String {
return "矩形半徑為 \(radius) "
}
}
class Rectangle: Circle {
var print = 7
override var area: String {
return super.area + " ,但現在被重寫為 \(print)"
}
}
let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("半徑: \(rect.area)")
class Square: Rectangle {
override var radius: Double {
didSet {
print = Int(radius/5.0)+1
}
}
}
let sq = Square()
sq.radius = 100.0
print("半徑: \(sq.area)")
```
由于以上實例使用了 final 關鍵字不允許重寫,所以執行會報錯:
```
error: var overrides a 'final' var
override var area: String {
^
note: overridden declaration is here
var area: String {
^
error: var overrides a 'final' var
override var radius: Double {
^
note: overridden declaration is here
final var radius = 12.5
^
error: inheritance from a final class 'Circle'
class Rectangle: Circle {
^
```
- Swift 簡介
- Swift 環境搭建
- Swift 基本語法
- Swift 數據類型
- Swift 變量
- Swift 可選(Optionals)類型
- Swift 常量
- Swift 字面量
- Swift 運算符
- Swift 條件語句
- Swift if 語句
- Swift if...else 語句
- Swift if...else if...else 語句
- Swift 嵌套 if 語句
- Swift switch 語句
- Swift 循環
- Swift for-in 循環
- Swift for 循環
- Swift While 循環
- Swift repeat...while 循環
- Swift Continue 語句
- Swift Break 語句
- Swift Fallthrough 語句
- Swift 字符串
- Swift 字符(Character)
- Swift 數組
- Swift 字典
- Swift 函數
- Swift 閉包
- Swift 枚舉
- Swift 結構體
- Swift 類
- Swift 屬性
- Swift 方法
- Swift 下標腳本
- Swift 繼承
- Swift 構造過程
- Swift 析構過程
- Swift 可選鏈
- Swift 自動引用計數(ARC)
- Swift 類型轉換
- Swift 擴展
- Swift 協議
- Swift 泛型
- Swift 訪問控制