Swift 继承
能够以更多形式表现的能力被定义为继承。一般来说,一个类可以从另一个类继承方法、属性和功能。类可以进一步分为子类和超类。
- 子类 − 当一个类从另一个类继承属性、方法和函数时,它被称为子类
-
超类 − 包含属性、方法和函数的类可以从其他类继承,它被称为超类
Swift 4的类包含超类,它调用和访问方法、属性、函数和重写方法。此外,还可以使用属性观察器来添加属性和修改存储或计算属性的方法。
基类
一个不从另一个类继承方法、属性或函数的类被称为“基类”。
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 4"
let mark1 = 98
let mark2 = 89
let mark3 = 76
print(stname)
print(mark1)
print(mark2)
print(mark3)
当我们在playground中运行上面的程序时,我们会得到以下结果 −
Swift 4
98
89
76
在这里,以类名为StudDetails的类被定义为一个基类,用于包含学生的姓名,以及三个科目的成绩如mark1,mark2和mark3。使用’let’关键字来初始化基类的值,并且借助’print’函数在playground中显示基类的值。
子类
基于已有类创建一个新类的行为被定义为’子类’。子类继承其基类的属性、方法和函数。要定义子类,在基类名称前面使用’:’。
class StudDetails {
var mark1: Int;
var mark2: Int;
init(stm1:Int, results stm2:Int) {
mark1 = stm1;
mark2 = stm2;
}
func print() {
print("Mark1:\(mark1), Mark2:\(mark2)")
}
}
class display : StudDetails {
init() {
super.init(stm1: 93, results: 89)
}
}
let marksobtained = display()
marksobtained.print()
当我们在playground上运行上述程序时,我们得到以下结果−
Mark1:93, Mark2:89
类’ StudDetails ‘被定义为超类,声明了学生的分数,子类 ‘display’用于从其超类继承分数。子类定义学生的分数并调用print()方法显示学生的分数。
覆盖
通过访问超类实例、类型方法、实例属性和子脚本子类提供了覆盖的概念。使用’override’关键字来覆盖在超类中声明的方法。
访问超类的方法、属性和子脚本
使用’super’关键字作为前缀来访问在超类中声明的方法、属性和子脚本。
重写 | 访问方法、属性和下标 |
---|---|
方法 | super.somemethod() |
属性 | super.someProperty() |
下标 | super[someIndex] |
方法重写
继承的实例和类型方法可以通过在子类中定义的方法使用’override’关键字进行重写。在子类中,print()被重写以访问超类print()中提到的类型属性。同时,创建了一个新的cricket()超类的实例,命名为’cricinstance’。
class cricket {
func print() {
print("Welcome to Swift 4 Super Class")
}
}
class tennis: cricket {
override func print() {
print("Welcome to Swift 4 Sub Class")
}
}
let cricinstance = cricket()
cricinstance.print()
let tennisinstance = tennis()
tennisinstance.print()
当我们在运行playground上述程序时,我们得到以下结果-
Welcome to Swift Super Class
Welcome to Swift Sub Class
属性重写
您可以重写继承的实例或类属性,以提供自定义的getter和setter,或添加属性观察者以使重写的属性在基础属性值更改时观察。
重写属性的getter和setter
Swift 4允许用户为继承的属性提供自定义的getter和setter,无论它是存储属性还是计算属性。子类不知道继承的属性的名称和类型。因此,在子类中,用户需要指定重写属性的名称和类型,这是至关重要的。
有两种方法可以实现:
- 当定义了重写属性的setter时,用户必须同时定义getter。
-
当我们不想修改继承属性的getter时,我们可以通过语法’super.someProperty’将继承的值传递给超类。
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)")
当我们在playground上运行上述程序时,我们得到如下结果-
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 4引入了“final”属性来阻止重写。一旦声明了“final”属性,下标将不允许重写超类的方法、属性和其下标。在“超类”中没有提供“final”属性的规定。当声明了“final”属性后,用户将受限制于创建更多的子类。
final class Circle {
final 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上运行上述程序时,我们将得到以下结果 –
<stdin>:14:18: error: var overrides a 'final' var
override var area: String {
^
<stdin>:7:9: note: overridden declaration is here
var area: String {
^
<stdin>:12:11: error: inheritance from a final class 'Circle'
class Rectangle: Circle {
^
<stdin>:25:14: error: var overrides a 'final' var
override var radius: Double {
^
<stdin>:6:14: note: overridden declaration is here
final var radius = 12.5
由于超类被声明为’final’,而且其数据类型也被声明为’final’,程序将不允许进一步创建子类,并且会抛出错误。