Swift2.1-繼承

繼承

蘋果官方文檔

原帖地址


一個類可以從另一個類繼承方法肿孵,屬性和其他的特性垒手。當(dāng)一個類從另一個類繼承的時候习柠,繼承類被稱為子類匀谣,這個類繼承的類被稱為父類。在Swift中津畸,繼承是基本的振定,從Swift中的其他類型來區(qū)分類的一種行為必怜。

在Swift中類可以調(diào)用和訪問方法肉拓,屬性和屬于它們父類的下標(biāo)腳本,并且提供它們自己重寫的方法梳庆,屬性和下標(biāo)腳本來定義或修改它們的行為暖途。Swift會確保你的重寫是正確的,通過檢查膏执,重寫定義都有一個與之匹配的父類定義驻售。

類也可以向繼承的屬性添加屬性監(jiān)聽者,當(dāng)屬性的值改變了以便通知欺栗〕偌福可以添加任何屬性到屬性監(jiān)聽者中消请,不管它是被定義為存儲或是計算屬性类腮。

定義基類

任何不從另一個類繼承的類都稱為基類。


注意:

Swift類不從一個通用基類繼承蚜枢。你定義的類不會自動地指定一個父類,你定義了沒有指定父類的類需频,在你創(chuàng)建時會自動成為基類筷凤。


下面的例子定義了一個叫做 Vehicle 的基類嵌施。這個基類定義了一個存儲屬性稱為 currentSpeed吗伤,它有一個默認(rèn)值0足淆。0(推斷為一個Double類型的屬性)巧号。currentSpeed屬性的值被用在一個稱為descriptionString類型的只讀計算屬性來創(chuàng)建一個vehicle的描述丹鸿。

Vehicle基類也定義了一個稱為makeNoise的方法靠欢。這個方法實(shí)際上不會為這個基類的實(shí)例做任何事门怪,但是后面它可以被Vehicle的子類自定義:

class Vehicle {
    var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    func makeNoise() {
        // do nothing - an arbitrary vehicle doesn't necessarily make a noise
    }
}

你使用初始化語法創(chuàng)建了一個新的Vehicle實(shí)例掷空,寫為類型名后面跟著一個空括號:

let someVehicle = Vehicle()

創(chuàng)建了一個新的Vehicle實(shí)例之后囤锉,你可以訪問它的description屬性來輸出一個人類可讀的,vehicle的當(dāng)前速度的描述:

print("Vehicle: \(someVehicle嚼锄。description)")
// Vehicle: traveling at 0.0 miles per hour

Vehicle類為任意的車輛定義了共同的特點(diǎn)区丑,但是對它本身沒有太大用處沧侥。為了讓它更有用宴杀,你需要重定義它來描述更具體的車輛種類。

子類化

子類化是基于現(xiàn)有類的新類的行為扁达。子類從現(xiàn)有的類繼承了一些特性跪解,你可以重新定義它們叉讥。你也可以為子類添加新的特性图仓。

為了表示子類有父類,要把子類寫在父類的前面帚豪,用冒號隔開:

class SomeSubclass: SomeSuperclass {
    // subclass definition goes here
}

下面的例子定義了一個稱為Bicycle的子類,繼承于Vehicle:

class Bicycle: Vehicle {
    var hasBasket = false
}

新的Bicycle類獲得了Vehicle的所有特性昌执,例如它的currentSpeeddescription屬性和makeNoise()方法煤禽。

除了繼承的特點(diǎn)檬果,Bicycle類定義了一個新的存儲屬性hasBasket选脊,并且默認(rèn)值為false(推斷它的類型為Bool)恳啥。

默認(rèn)情況钝的,任何你新建的Bicycle實(shí)例都都不會有籃子。在一個特定的Bicycle類實(shí)例創(chuàng)建之后亿柑,你可以為這個實(shí)例設(shè)置hasBasket屬性為true:

let bicycle = Bicycle()
bicycle望薄。hasBasket = true

你也可以在Bicycle類實(shí)例中修改繼承的currentSpeed屬性,或是查詢實(shí)例的繼承description屬性:

bicycle卧须。currentSpeed = 15.0
print("Bicycle: \(bicycle.description)")
// Bicycle: traveling at 15.0 miles per hour

子類也可以被繼承花嘶。下個例子創(chuàng)建了一個Bicycle類的子類,一個兩座的自行車稱為"tandem":

class Tandem: Bicycle {
    var currentNumberOfPassengers = 0
}

TandemBicycle繼承了所有的屬性和方法隘击,也依次從Vehicle繼承了所有屬性和方法埋同。Tandem子類也添加了一個新的稱為currentNumberOfPassengers的存儲屬性凶赁,并且有一個默認(rèn)值0:

let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print("Tandem: \(tandem.description)")
// Tandem: traveling at 22.0 miles per hour

重寫

一個子類可以提供它自己的實(shí)例方法楼熄,類型方法可岂,實(shí)例屬性,類型屬性或下標(biāo)腳本的自定義實(shí)現(xiàn)平斩,否則绘面,它將會從父類繼承揭璃。這就是重寫。

為了重寫一個被繼承的特性情组,你要在你的重寫定義前面加上override關(guān)鍵詞院崇。這樣做說明你打算提供一個重寫,如果不這樣做就會匹配一個錯誤的定義濒持。意外的重寫可能導(dǎo)致意意想不到的行為柑营,并且當(dāng)你編譯的時候官套,對于任意沒有override關(guān)鍵詞的重寫都會被視為錯誤。

override關(guān)鍵詞也提供Swift編譯器檢查站刑,你的重寫類的父類(或者父類的父類)有一個聲明來匹配你提供的重寫绞旅。檢查確保你重寫的定義是是正確的。

訪問父類方法晃琳,屬性和下標(biāo)腳本

當(dāng)你為子類提供了一個方法卫旱,屬性或者下標(biāo)腳本,有時那是有用的暴构,來使用現(xiàn)有的父類實(shí)現(xiàn)作為你重寫的一部分取逾。例如,你可以重定義現(xiàn)有實(shí)現(xiàn)的行為晴埂,或者在現(xiàn)有的繼承變量中存儲一個修正值儒洛。

這是適當(dāng)?shù)呢酝#憧梢酝ㄟ^使用super前綴惊完,訪問父類的方法,屬性或下標(biāo)腳本:

  • 一個命名為someMethod()的重寫方法可以通過super凿跳。someMethod()在重寫的方法實(shí)現(xiàn)中拄显,調(diào)用父類的someMethod()方法。
  • 一個命名為someProperty的重寫屬性當(dāng)通過super承边。someProperty在重寫的getter或setter實(shí)現(xiàn)中,可以訪問父類的someProperty屬性富岳。
  • 一個命名為someIndex的重寫下標(biāo)腳本當(dāng)使用super[someIndex]在重寫的下標(biāo)腳本實(shí)現(xiàn)中,可以訪問父類中相同的腳本萝喘。

重寫方法

你可以在你的子類中爬早,重寫一個繼承的實(shí)例或類型方法來提供定制的或是可選的方法實(shí)現(xiàn)筛严。

下面的例子定義了一個新的Vehicle子類脑漫,稱為Train吨拍,重寫了makeNoise()方法:

class Train: Vehicle {
    override func makeNoise() {
        print("Choo Choo")
    }
}

如果你創(chuàng)建了一個新的Train實(shí)例伊滋,并且調(diào)用了makeNoise()方法笑旺,你可以看到Train子類的方法被調(diào)用了:

let train = Train()
train.makeNoise()
// prints "Choo Choo"

重寫屬性

你可以提供一個繼承實(shí)例或類型來為你自己的屬性提供你自己自定義的getter和setter,或者添加屬性監(jiān)聽者確保當(dāng)?shù)讓訉傩灾蹈淖儠r來監(jiān)聽重寫的屬性乌妙。

重寫屬性getter和setter

你可以提供一個自定義的getter(和setter,如果合適的話)來重寫任意的繼承屬性泽艘,不管在開始時繼承屬性是否實(shí)現(xiàn)了存儲屬性或計算屬性。一個繼承屬性的存儲或計算性質(zhì)不被看做一個子類--它僅被看做繼承屬性有某個名字或類型焕盟。你必須聲明你重寫的屬性名字和類型灼卢,來確保編譯器可以檢查你的重寫匹配了父類中有相同名字和類型的屬性鞋真。

通過在你的子類重寫屬性里提供getter和setter方法,你可以把一個繼承為只讀的屬性重寫為讀寫的屬性檩互。然而闸昨,你不能把繼承為讀寫的屬性重寫為只讀屬性。


注意:

如果你提供了一個setter作為一個屬性重寫的部分循诉,你也必須為重寫提供一個getter。如果你不想在重寫getter時修改繼承屬性的值募疮,那么你可以簡單通過從getter返回super。someProperty繼承的值芭毙,someProperty就是你重寫的屬性的名字。


下面的例子定義了一個新類Car卸耘,繼承自Vehicle類退敦。Car類介紹了一個新的存儲屬性gear,并且有一個默認(rèn)的整型值 1蚣抗。 Car類也重寫了description屬性侈百,它繼承自Vehicle,提供了一個自定義的描述钝域,介紹了當(dāng)前的gear:

class Car: Vehicle {
    var gear = 1
    override var description: String {
        return super.description + " in gear \(gear)"
    }
}

重寫的description屬性通過調(diào)用super讽坏。description開始,返回了Vehicle類的description屬性例证。Car類的description之后就添加了一些額外的文本到描述的末尾路呜,提供了關(guān)于當(dāng)前的gear信息。

如果你創(chuàng)建一個Car類的實(shí)例织咧,并且設(shè)置了它的settercurrentSpeed屬性胀葱,你可以看到它的description屬性在Car類的定義里返回了定制的描述:

let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")
// Car: traveling at 25.0 miles per hour in gear 3

重寫屬性監(jiān)聽者

你可以使用屬性重寫來添加屬性監(jiān)聽者為繼承的屬性。這就可以當(dāng)繼承的屬性值改變的時候通知你笙蒙,不管這個屬性最初是如何實(shí)現(xiàn)的抵屿。對于屬性監(jiān)聽者上更多的信息,可以看屬性監(jiān)聽者手趣。


注意:

你不能添加屬性監(jiān)聽者來繼承常量的存儲屬性或者繼承只讀的計算屬性晌该。這些屬性的值不能被set
(設(shè)置)肥荔,所以提供willSetdidSet實(shí)現(xiàn)作為重寫的一部分是不恰當(dāng)?shù)摹?/p>

也要注意绿渣,你不能為相同的屬性提供一個重寫的setter和一個重寫的屬性監(jiān)聽者。如果你想要監(jiān)聽屬性值的改變燕耿,并且你已經(jīng)為那個屬性提供了一個自定義的setter中符,那么你可以從自定義的setter里簡單地監(jiān)聽任意值的改變。


下面的例子定義了一個新類AutomaticCar誉帅,繼承自Car淀散。AutomaticCar類代表一輛車有一個自動的變速箱(gearbox),可以根據(jù)當(dāng)前的速度自動地選擇一個合適的gear:

class AutomaticCar : Car {
    override var currentSpeed: Double {
        didSet {
            gear = Int(currentSpeed / 10.0) + 1
        }
    }
}

無論你在什么時候設(shè)置了AutomaticCar實(shí)例的currentSpeed屬性蚜锨,這個屬性的didSet監(jiān)聽者都會設(shè)置實(shí)例的gear屬性給新的速度一個合適的值档插。具體地說,屬性監(jiān)聽者選擇了一個gear亚再,它是新的currentSpeed值除以10郭膛,四舍五入到最近整數(shù),然后加1氛悬。例如则剃,速度是35,那么gear就是4:

let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic如捅。description)")
// AutomaticCar: traveling at 35.0 miles per hour in gear 4

阻止重寫

你可以通過標(biāo)記為final來阻止一個方法棍现,屬性或者下標(biāo)腳本被重寫。通過在方法镜遣,屬性或者下標(biāo)腳本的關(guān)鍵字前寫final修飾符(例如己肮,final varfinal funcfinal class func谎僻,fianl subscript)窖剑。

任何想要在子類里重寫final方法,屬性或下標(biāo)腳本都會報一個編譯時錯誤戈稿。在擴(kuò)展中添加到一個類中的方法西土,屬性或下標(biāo)腳本也可以子擴(kuò)展的定義里被標(biāo)記為final债鸡。

你可以標(biāo)記一個額外的類通過在class關(guān)鍵字前面寫final修飾符為final(final class)凄鼻。任何想要子類為一個final類都會報一個編譯時錯誤。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姓迅,一起剝皮案震驚了整個濱河市般甲,隨后出現(xiàn)的幾起案子肋乍,更是在濱河造成了極大的恐慌,老刑警劉巖敷存,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件墓造,死亡現(xiàn)場離奇詭異,居然都是意外死亡锚烦,警方通過查閱死者的電腦和手機(jī)觅闽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涮俄,“玉大人蛉拙,你說我怎么就攤上這事〕骨祝” “怎么了孕锄?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長苞尝。 經(jīng)常有香客問我畸肆,道長,這世上最難降的妖魔是什么宙址? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任轴脐,我火速辦了婚禮,結(jié)果婚禮上曼氛,老公的妹妹穿的比我還像新娘豁辉。我一直安慰自己,他們只是感情好舀患,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布徽级。 她就那樣靜靜地躺著,像睡著了一般聊浅。 火紅的嫁衣襯著肌膚如雪餐抢。 梳的紋絲不亂的頭發(fā)上现使,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天,我揣著相機(jī)與錄音旷痕,去河邊找鬼碳锈。 笑死,一個胖子當(dāng)著我的面吹牛欺抗,可吹牛的內(nèi)容都是我干的售碳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼绞呈,長吁一口氣:“原來是場噩夢啊……” “哼贸人!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起佃声,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤艺智,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后圾亏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體十拣,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年志鹃,在試婚紗的時候發(fā)現(xiàn)自己被綠了夭问。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡弄跌,死狀恐怖甲喝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情铛只,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布糠溜,位于F島的核電站淳玩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏非竿。R本人自食惡果不足惜蜕着,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望红柱。 院中可真熱鬧承匣,春花似錦、人聲如沸锤悄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽零聚。三九已至袍暴,卻和暖如春些侍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背政模。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工岗宣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人淋样。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓耗式,卻偏偏與公主長得像,于是被迫代替她去往敵國和親趁猴。 傳聞我的和親對象是個殘疾皇子纽什,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 官方文檔 初始化 Initialization是為準(zhǔn)備使用類,結(jié)構(gòu)體或者枚舉實(shí)例的一個過程躲叼。這個過程涉及了在實(shí)例里...
    hrscy閱讀 1,136評論 0 1
  • 本章將會介紹 下標(biāo)語法下標(biāo)用法下標(biāo)選項(xiàng)定義一個基類子類生成重寫防止重寫 下標(biāo) 下標(biāo)可以定義在類枫慷、結(jié)構(gòu)體和枚舉中让蕾,是...
    寒橋閱讀 438評論 0 1
  • 我懷念的,是歲月有你這首歌曲 我珍惜的或听,是年華里我們的相知相惜 當(dāng)涼意浸透大地探孝,落紅化作春泥, 當(dāng)秋風(fēng)吹起有沒有另...
    六7閱讀 379評論 12 12
  • Day19: 不自律的人誉裆,都是相似的顿颅;自律的人,各有各的過人之處足丢。你見過最自律的人是怎樣的粱腻? 自律...
    謹(jǐn)姐姐閱讀 278評論 0 0
  • 一個人懂的東西越少, 看到的東西越少斩跌, 往往容易自我膨脹绍些。 反而看的多了,懂的東西越多的人耀鸦,更加的謙虛柬批。 謙虛并不...
    伊豆2011閱讀 224評論 0 1