关于 继承、扩展和协议,深度好文
生活随笔
收集整理的這篇文章主要介紹了
关于 继承、扩展和协议,深度好文
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
OC中protocol、category和繼承的區(qū)別以前還是有點(diǎn)迷糊,面試的時(shí)候說(shuō)的有點(diǎn)混亂,現(xiàn)在結(jié)合一些資料總結(jié)一下。 利用繼承,多態(tài)是一個(gè)很好的保持“對(duì)擴(kuò)展開(kāi)放、對(duì)更改封閉”(OCP)的辦法,也是最常見(jiàn)的一種方法。Objective C還支持另外兩種語(yǔ)法來(lái)支持OCP:Protocol和Category。Protocol只能定義一套接口,而不能提供實(shí)現(xiàn),變相的也是一種Abstract class的實(shí)現(xiàn)方式(oc 語(yǔ)法上本身不支持抽象基類)。Category可以為類提供額外的接口和實(shí)現(xiàn)。那么到底三者(繼承, Protocol,Category)在使用上到底有什么本質(zhì)的區(qū)別呢?在我看來(lái),protocol的作用是為一些列類僅僅提供一套公用的接口,而完全沒(méi) 有辦法也沒(méi)可能去提供具體的一些實(shí)現(xiàn)情況;category則是為一個(gè)已有的類提供一些額外的接口和具體實(shí)現(xiàn);而繼承則基于兩者之間,既可以想 protocol一樣提供只是純粹提供接口,也可以像Category一樣提供完整的實(shí)現(xiàn),而且繼承還能對(duì)類以后的功能進(jìn)行改寫,所以說(shuō)繼承的力量是最強(qiáng) 大的。那么具體在使用的時(shí)候各自都適合什么樣的情況呢? ? ? ? ? .? ? ? ? Protocol是定義行為而不管誰(shuí)去怎么實(shí)現(xiàn),這是一種比較灑脫和不負(fù)責(zé)的情況,就好像在外包項(xiàng)目中的客戶一樣,他只是他需要什么什么東西,具體實(shí)現(xiàn)他不會(huì)也不能給出一樣。delegate datasource這樣的就用protocol實(shí)現(xiàn)比較好 ? ? ? ? .? ? ? ? Category是對(duì)一個(gè)功能完備的類的一種補(bǔ)充,就像是一個(gè)東西的主要基本功能都完成了,可以用category為這個(gè)類添加不同的組件,使得 這個(gè)類能夠適應(yīng)不同情況的需求(但是這些不同需求最核心的需求要一致)。找個(gè)就像你已經(jīng)有了一輛能夠開(kāi)動(dòng)的汽車一樣,我們可以用Category為你的汽 車添加各種之前沒(méi)有的功能,最后讓這輛汽車變成超級(jí)跑車一樣。 ? ? ? ? .? ? ? ? 當(dāng)某個(gè)類非常大的時(shí)候,Category可以按不同的功能將類的實(shí)現(xiàn)分在不同的模塊中實(shí)現(xiàn)。 ? ? ? ? .? ? ? ? 繼承則是都可以完成上面的工作,但是繼承有很大的代價(jià)問(wèn)題,一是通過(guò)繼承來(lái)進(jìn)行擴(kuò)展是一種耦合很高的行為,對(duì)父類可以說(shuō)是完全依賴;二是繼承由于 對(duì)父類依賴,所以開(kāi)發(fā)代價(jià)相對(duì)大,要求對(duì)父類的工作流程相對(duì)熟悉;三是繼承體系如果太復(fù)雜會(huì)導(dǎo)致整個(gè)系統(tǒng)混亂,難以維護(hù)。所以在能夠用上面兩種方法完成擴(kuò) 展的時(shí)候,就千萬(wàn)不要使用繼承。什么情況才是迫不得已要使用繼承呢?那就是如果你既想提供一系列接口的定義,同時(shí)又想提供一些但是又不能提供全部的實(shí)現(xiàn)的 時(shí)候,這種情況就要使用繼承了。所以這么看來(lái)繼承是對(duì)上面兩種功能的一個(gè)黏合劑。 關(guān)于category的另外一些見(jiàn)解: ? ? ? ? .? ? ? ? 雖然category可以訪問(wèn)類的實(shí)例變量,去不能創(chuàng)建新的實(shí)例變量,如果要?jiǎng)?chuàng)新的實(shí)例變量,請(qǐng)使用繼承; ? ? ? ? .? ? ? ? 在category中,不提倡對(duì)原有方法進(jìn)行重載。原因非常簡(jiǎn)單,在category中進(jìn)行重載,無(wú)法對(duì)原方法進(jìn)行訪問(wèn),而繼承中可以使用super。如果真的需要對(duì)原方法進(jìn)行重載,請(qǐng)考慮繼承,比如我要定義一個(gè)繼承自UIViewController的類,就不能用Category,因?yàn)?#xff0c;這我定義的這個(gè)類中,我要實(shí)現(xiàn)UIViewController中的viewDidLoad、init等方法,用了category后父UIViewController中的這些方法將無(wú)法被調(diào)用; ? ? ? ? .? ? ? ? 一個(gè)類可以定義多個(gè)category,但是如果不同category中存在相同方法,編譯器無(wú)法決定使用哪個(gè)category; ? ? ? ? .? ? ? ? 在定義category時(shí),我們可以僅僅給出方法定義,而不需要給出具體的實(shí)現(xiàn)。這在程序增量開(kāi)發(fā)時(shí)是非常有幫助的; ? ? ? ? .? ? ? ? category是可以被繼承的。在某個(gè)父類中定義了category,那么他所有的子類都具有該category; ? ? ? ? .? ? ? ? 在需要為某個(gè)類創(chuàng)建私有成員方法時(shí),也用category的方式來(lái)實(shí)現(xiàn)。 Category不能完全代替子類,有以下幾個(gè)最大的缺點(diǎn): ? ? ? ? .? ? ? ? 當(dāng)在Category中覆蓋一個(gè)繼承的方法,在Category中的方法可以通過(guò)向super類發(fā)送一個(gè)消息來(lái)調(diào)用被繼承的方法。但是,如果Category中覆蓋的那個(gè)方法已經(jīng)在這個(gè)類的其它Category定義過(guò)了,則之前定義的方法將沒(méi)有機(jī)會(huì)被程序調(diào)用 ? ? ? ? .? ? ? ? 在Category中無(wú)法確定其能夠可靠的覆蓋某個(gè)方法,而這個(gè)方法已經(jīng)在其它的Category中定義過(guò)。這個(gè)問(wèn)題在使用Cocoa框架時(shí)尤其 突出。當(dāng)你想覆蓋某個(gè)框架已經(jīng)定義好的方法時(shí),該方法已經(jīng)在其它Category中實(shí)現(xiàn),這樣就無(wú)法確定哪個(gè)定義和實(shí)現(xiàn)會(huì)被最先使用,帶來(lái)很大的不確定 性。 ? ? ? ? .? ? ? ? 如果你重新覆蓋定義了一些方法,往往會(huì)導(dǎo)致這個(gè)方法在整個(gè)框架中實(shí)現(xiàn)發(fā)生了變化。舉例來(lái)說(shuō),如果你增加了NSObject中 windowWillClose:的實(shí)現(xiàn),這會(huì)導(dǎo)致所有的窗口調(diào)用那個(gè)新實(shí)現(xiàn)的方法,從而改變所有NSWindows實(shí)例的行為。這會(huì)帶來(lái)很多不確定性, 并很有可能導(dǎo)致程序的崩潰。
http://bbs.itheima.com/thread-117162-1-1.html
http://bbs.itheima.com/thread-117162-1-1.html
總結(jié)
以上是生活随笔為你收集整理的关于 继承、扩展和协议,深度好文的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Hadoop2.6.0的FileInpu
- 下一篇: swift水波效果