繼承我們可以理解為一個(gè)類獲取了另外一個(gè)類的方法和屬性球拦。
當(dāng)一個(gè)類繼承其他類時(shí),繼承類叫子類续搀,被繼承類叫超類塞琼。(或父類)
在Swift中,類可以調(diào)用和訪問(wèn)超類的方法禁舷,屬性和下表腳本彪杉,并且可以重寫它們毅往。
我們也可以為類中繼承來(lái)的屬性添加屬性觀察器。
基類
沒(méi)有繼承其他類的類派近,稱之為基類(Base Class)攀唯。
以下實(shí)例中我們定義了基類StudentDetails,描述了學(xué)生(studentName)及其各科成績(jī)的分?jǐn)?shù)(mark1渴丸、mark2侯嘀、mark3):
class StudentDetails {
var studentName: String!
var mark1: Int!
var mark2: Int!
var mark3: Int!
init(studentName: String, mark1: Int, mark2: Int, mark3: Int) {
self.studentName = studentName
self.mark1 = mark1
self.mark2 = mark2
self.mark3 = mark3
}
}
let studentName = "Swift"
let mark1 = 100
let mark2 = 95
let mark3 = 90
let sds = StudentDetails(studentName: studentName, mark1: mark1, mark2: mark2, mark3: mark3);
print(sds.StudentName)
print(sds.mark1)
print(sds.mark2)
print(sds.mark3)
以上程序執(zhí)行輸出結(jié)果為:
Swift
100
95
90
子類
子類指的是在一個(gè)已有類的基礎(chǔ)上創(chuàng)建一個(gè)新的類。
為了指明某個(gè)類的超類谱轨,將超類名寫在子類名的后面戒幔,用冒號(hào)(:)分隔,語(yǔ)法格式如下
class SomeClass: SomeSuperclass {
//類的定義
}
實(shí)例
以下實(shí)例中我們定義了超類StudentDetails土童,然后使用子類Tom繼承它:
class StudentDetails {
var mark1: Int
var mark2: Int
init(stm1: Int, results stm2: Int) {
mark1 = stm1
mark2 = stm2
}
func show() {
print("Mark:\(self.mark1), Mark2:\(self.mark2)")
}
}
class Tom : StudentDetails {
init() {
super.init(stm1: 93, results: 89)
}
}
let tom = Tom()
tom.show()
以上程序執(zhí)行輸出結(jié)果為:
Mark: 93, Mark: 89
重寫(Overriding)
子類可以通過(guò)繼承來(lái)的實(shí)例方法溪食,類方法,實(shí)例屬性娜扇,或下標(biāo)腳本來(lái)實(shí)現(xiàn)自己的定制功能,我們把這種行為叫重寫(overriding)栅组。
我們可以使用override關(guān)鍵字來(lái)實(shí)現(xiàn)重寫雀瓢。
訪問(wèn)超類的方法、屬性及下標(biāo)腳本
你可以通過(guò)使用super前綴來(lái)訪問(wèn)超類方法玉掸,屬性或下標(biāo)腳本刃麸。
重寫方法和屬性
重寫方法
在我們的子類中我們可以使用override關(guān)鍵字來(lái)重寫超類的方法。
以下實(shí)例中我們重寫了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()
以上程序執(zhí)行輸出結(jié)果為:
這是超類 SuperClass
這是子類 SubClass
重寫屬性
你可以提供定制的getter(或setter)來(lái)重寫任意繼承來(lái)的屬性司浪,無(wú)論繼承來(lái)的屬性是存儲(chǔ)型的還是計(jì)算型的屬性泊业。
子類并不知道繼承來(lái)的熟悉感是存儲(chǔ)型的還是計(jì)算型的,它只知道繼承來(lái)的屬性會(huì)有一個(gè)名字和類型啊易。所以你在重寫一個(gè)屬性時(shí)吁伺,必須將它的名字和類型都寫出來(lái)。
注意點(diǎn):
1租谈、如果你在重寫屬性中提供了setter篮奄,那么你也一定要提供getter。
2割去、如果你不想在重寫版本中的getter里修改繼承來(lái)的屬性值窟却,你可以直接通過(guò)super.someProperty來(lái)返回繼承來(lái)的值,其中someProperty是你要重寫的屬性的名字呻逆。
以下實(shí)例我們定義了超類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 + ",但現(xiàn)在被重寫為\(print)"
}
}
let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("Radius\(rect.area)")
以上程序執(zhí)行輸出結(jié)果為:
Radius 矩形半徑 25.0咖城,但現(xiàn)在被重寫為 3
重寫屬性觀察器
你可以在屬性重寫中為一個(gè)繼承來(lái)的屬性添加屬性觀察器茬腿。這樣一來(lái)呼奢,當(dāng)繼承來(lái)的屬性值發(fā)生改變時(shí),你就會(huì)監(jiān)測(cè)到滓彰。
注意:你不可以為繼承來(lái)的常量存儲(chǔ)型屬性或繼承來(lái)的只讀計(jì)算型屬性添加屬性觀察器控妻。
class Circle {
var radius = 12.5
var area: String {
return "矩形半徑為\(radius)"
}
}
class Rectangle: Circle {
var print = 7
override var area: String {
return super.area + ",但現(xiàn)在被重新寫為\(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揭绑,但現(xiàn)在被重寫為3弓候。
半徑:矩形半徑為100.0,但現(xiàn)在被重寫為21他匪。
防止重寫
我們可以使用final關(guān)鍵字防止它們被重寫菇存。
如果你重寫了final方法,屬性或下標(biāo)腳本邦蜜,在編譯時(shí)會(huì)報(bào)錯(cuò)依鸥。
你可以通過(guò)在關(guān)鍵字class前添加final特性(final class)來(lái)將整個(gè)類標(biāo)記final的,這樣的類是不可被避免繼承的悼沈,否則會(huì)報(bào)編譯錯(cuò)誤贱迟。
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 = Reatangle()
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)")
由于以上實(shí)例使用了final關(guān)鍵字不允許重寫絮供,所以執(zhí)行會(huì)報(bào)錯(cuò):
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 {
^