- 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',因此程序不允许进一步创建子类,并将抛出错误。