取而不是定義更多形式的能力被定義為繼承。 通常,類可以從另一個類繼承方法,屬性和功能。 類可以進一步分類為子類和超類。
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()
中的type
屬性。 另外,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
,因此程式將不允許建立子類,並且丟擲錯誤。