
- Swift 教程
- Swift - 首頁
- Swift - 概述
- Swift - 環境
- Swift - 基本語法
- Swift - 變數
- Swift - 常量
- Swift - 字面量
- Swift - 註釋
- Swift 運算子
- Swift - 運算子
- Swift - 算術運算子
- Swift - 比較運算子
- Swift - 邏輯運算子
- Swift - 賦值運算子
- Swift - 位運算子
- Swift - 其他運算子
- Swift 高階運算子
- Swift - 運算子過載
- Swift - 算術溢位運算子
- Swift - 恆等運算子
- Swift - 範圍運算子
- Swift 資料型別
- Swift - 資料型別
- Swift - 整數
- Swift - 浮點數
- Swift - Double
- Swift - 布林值
- Swift - 字串
- Swift - 字元
- Swift - 類型別名
- Swift - 可選值
- Swift - 元組
- Swift - 斷言和前提條件
- Swift 控制流
- Swift - 決策
- Swift - if 語句
- Swift - if...else if...else 語句
- Swift - if-else 語句
- Swift - 巢狀 if 語句
- Swift - switch 語句
- Swift - 迴圈
- Swift - for in 迴圈
- Swift - while 迴圈
- Swift - repeat...while 迴圈
- Swift - continue 語句
- Swift - break 語句
- Swift -貫穿語句
- Swift 集合
- Swift - 陣列
- Swift - 集合
- Swift - 字典
- Swift 函式
- Swift - 函式
- Swift - 巢狀函式
- Swift - 函式過載
- Swift - 遞迴
- Swift - 高階函式
- Swift 閉包
- Swift - 閉包
- Swift - 轉義和非轉義閉包
- Swift - 自動閉包
- Swift 面向物件程式設計
- Swift - 列舉
- Swift - 結構體
- Swift - 類
- Swift - 屬性
- Swift - 方法
- Swift - 下標
- Swift - 繼承
- Swift - 方法重寫
- Swift - 初始化
- Swift - 析構
- Swift 高階特性
- Swift - ARC 概述
- Swift - 可選鏈
- Swift - 錯誤處理
- Swift - 併發
- Swift - 型別轉換
- Swift - 巢狀型別
- Swift - 擴充套件
- Swift - 協議
- Swift - 泛型
- Swift - 訪問控制
- Swift - 函式與方法
- Swift - SwiftyJSON
- Swift - 單例類
- Swift 隨機數
- Swift 不透明型別和裝箱型別
- Swift 有用資源
- Swift - 線上編譯
- Swift - 快速指南
- Swift - 有用資源
- Swift - 討論
Swift - 方法重寫
重寫是面向物件程式語言中一個非常常見的概念。使用重寫,我們可以重新實現超類中的方法或屬性在子類中。它允許我們擴充套件繼承的行為。在重寫方法或屬性時,我們提供子類中的新實現,而不是使用超類中的實現。在 Swift 中,我們可以重寫超類的方法或屬性。
訪問超類的方法、屬性和下標
“super”關鍵字用作字首來訪問在超類中宣告的方法、屬性和下標。
方法重寫 | 訪問方法、屬性和下標 |
---|---|
方法 | super.somemethod() |
屬性 | super.someProperty() |
下標 | super[someIndex] |
Swift 中重寫的規則
以下是一些你在重寫時應該遵循的規則:
子類中重寫的方法或屬性必須具有與超類中相同的簽名(名稱、引數和返回型別)。
使用super關鍵字從重寫方法中的超類呼叫重寫的實現。
使用override關鍵字重寫屬性。我們可以重寫儲存屬性和計算屬性。
重寫方法或屬性的訪問級別不能比基類中重寫方法或屬性的訪問級別更嚴格。不允許使用私有方法重寫公共方法。因此,在重寫之前始終檢查訪問修飾符。
Swift 中的方法重寫
在 Swift 中,我們可以重寫方法。重寫方法意味著子類可以為在基類中已定義的方法提供不同的實現。或者我們可以說,我們可以在子類中自定義超類方法的行為。
子類中重寫的方法必須具有與基類相同的簽名(名稱、引數和返回型別),編譯器將根據物件的型別確定呼叫哪個方法。此外,子類中重寫方法的訪問級別必須與超類中方法的訪問級別相同或更寬鬆。
重寫方法是透過在子類中使用override關鍵字來定義的。此關鍵字放置在函式定義的開頭。它告訴編譯器該方法將重寫超類的方法。如果我們沒有指定override關鍵字,則編譯器將給出錯誤。
語法
以下是方法重寫的語法:
override func methodName(Parameters) -> returntype { Statement return parameters }
示例
Swift 方法重寫的程式。
// Super class class cricket { // Method func show() { print("Welcome to Swift Super Class") } } // Sub class class tennis: cricket { // Overriden Method override func show() { print("Welcome to Swift Sub Class") } } // Creating instance of subclass let tennisinstance = tennis() // Accessing the override method tennisinstance.show()
輸出
它將產生以下輸出:
Welcome to Swift Sub Class
屬性重寫
Swift 支援屬性重寫。與方法重寫一樣,屬性重寫也為子類提供了一種自定義在基類中已定義的屬性實現的方式。我們可以說,使用屬性重寫,我們可以為該屬性提供我們自己的 getter 和 setter,或者新增屬性觀察器,這使得重寫屬效能夠觀察屬性值何時更改。
子類中重寫屬性的型別必須與基類中屬性的名稱和型別相同。這樣編譯器就可以根據物件的型別確定呼叫哪個屬性(超類屬性或重寫屬性)。子類中重寫方法的訪問級別必須與超類中屬性的訪問級別相同或更寬鬆。
重寫屬性是透過在子類中使用override關鍵字來定義的。此關鍵字放置在屬性定義的開頭。它告訴編譯器該屬性將重寫超類的屬性。如果我們沒有指定override關鍵字,則編譯器將給出錯誤。
語法
以下是屬性重寫的語法:
override var propertyName: type{ // Statement }
示例
Swift 屬性重寫的程式。
// Superclass class mySuperClass { // Property var language: String{ return "C++" } } // Subclass class mySubClass: mySuperClass { // Override Property override var language: String{ return "Swift" } } // Creating an instance of a subclass let obj = mySubClass() // Accessing the overridden property print(obj.language)
輸出
它將產生以下輸出:
Swift
重寫屬性 getter 和 setter
Swift 允許使用者重寫子類屬性的 getter 和 setter,無論該屬性是儲存屬性還是計算屬性。重寫屬性的名稱和型別必須與基類中存在的屬性相同。這樣編譯器就知道你正在重寫基類的屬性。
在 Swift 中,我們可以透過在子類中重寫時同時提供 getter 和 setter,將只讀繼承屬性表示為讀寫屬性。而我們不允許將讀寫繼承屬性表示為只讀屬性。當為重寫屬性定義 setter 時,使用者也必須定義 getter。如果我們不希望在重寫 getter 中修改繼承屬性的值,則可以使用 'super.PropertyName' 從 getter 傳遞繼承的值,其中 PropertyName 表示重寫屬性的名稱。
示例
Swift 重寫屬性 getter 和 setter 的程式。
// Base Class class Circle { var radius = 12.5 // Property with getter var area: String { return "of rectangle for \(radius) " } } // Subclass class Rectangle: Circle { var print = 7 // Overriding the getter override var area: String { return super.area + " is now overridden as \(print)" } } // Creating instance let rect = Rectangle() // Accessing the properties rect.radius = 25.0 rect.print = 3 print("Radius \(rect.area)")
輸出
它將產生以下輸出:
Radius of rectangle for 25.0 is now overridden as 3
重寫屬性觀察器
當需要為繼承屬性新增新屬性時,Swift 4 中引入了“屬性重寫”的概念。這會在繼承屬性值更改時通知使用者。但是,重寫不適用於繼承的常量儲存屬性和繼承的只讀計算屬性。
示例
class Circle { var radius = 12.5 var area: String { return "of rectangle for \(radius) " } } class Rectangle: Circle { var print = 7 override var area: String { return super.area + " is now overridden as \(print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("Radius \(rect.area)") class Square: Rectangle { override var radius: Double { didSet { print = Int(radius/5.0)+1 } } } let sq = Square() sq.radius = 100.0 print("Radius \(sq.area)")
輸出
當我們使用 playground 執行上述程式時,我們將得到以下結果:
Radius of rectangle for 25.0 is now overridden as 3 Radius of rectangle for 100.0 is now overridden as 21
阻止 Swift 中的重寫
Swift 提供了一個特殊的關鍵字來阻止重寫方法、屬性、下標甚至類,這個關鍵字被稱為final關鍵字。final 關鍵字明確指示指定的 方法、屬性、下標或類不能被子類重寫。如果使用者仍然嘗試重寫,則編譯器將給出錯誤。
final 關鍵字始終用於方法、屬性、下標或類的宣告之前。
語法
以下是阻止重寫的語法:
// For methods final func methodName(Parameters) -> returntype{} // For property final var propertyName : type // For subscript final subscript(index: Int)->Elemnt{} // For class final class className{}
示例
阻止重寫的 Swift 程式。
// Base class final class Circle { final var radius = 12.5 var area: String { return "of rectangle for \(radius) " } } // Sub class class Rectangle: Circle { var print = 7 override var area: String { return super.area + " is now overridden as \(print)" } } // Creating instance let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("Radius \(rect.area)")
錯誤
main.swift:12:17: error: property overrides a 'final' property override var area: String { ^ main.swift:4:8: note: overridden declaration is here var area: String { ^ main.swift:10:7: error: inheritance from a final class 'Circle' class Rectangle: Circle { ^ main.swift:21:17: error: ambiguous use of 'area' print("Radius \(rect.area)") ^ main.swift:12:17: note: found this candidate override var area: String { ^ main.swift:4:8: note: found this candidate var area: String { ^
由於超類宣告為 'final',其資料型別也宣告為 'final',因此程式不允許進一步建立子類,並將丟擲錯誤。