OC類別和繼承

OC中protocol、category和繼承的區(qū)別以前還是有點迷糊,現(xiàn)在結(jié)合一些 資料總結(jié)一下。 利用繼承,多態(tài)是一個很好的保持“對擴展開放、對更改封 閉”(OCP)的辦法,也是最常見的一種方法。Objective C還支持另外兩種語 法來支持OCP:Protocol和Category。Protocol只能定義一套接口,而不能提供實現(xiàn),變相的也是一種Abstract class的實現(xiàn)方式(oc 語法上本身不支持抽象基類)。Category可以為類提供額外的接口和實現(xiàn)。那么到底三者(繼承, Protocol,Category)在使用上到底有什么本質(zhì)的區(qū)別呢?在我看來,protocol的作用是為一些列類僅僅提供一套公用的接口,而完全沒 有辦法也沒可能去提供具體的一些實現(xiàn)情況;category則是為一個已有的類提供一些額外的接口和具體實現(xiàn);而繼承則基于兩者之間,既可以想 protocol一樣提供只是純粹提供接口,也可以像Category一樣提供完整的實現(xiàn),而且繼承還能對類以后的功能進(jìn)行改寫,所以說繼承的力量是最強 大的。那么具體在使用的時候各自都適合什么樣的情況呢? .

Protocol是定義行為而不管誰去怎么實現(xiàn),這是一種比較灑脫和不負(fù)責(zé)的情況,就好像在外包項目中的客戶一樣,他只是他需要什么什么東西,具體實現(xiàn)他不會也不能給出一樣。delegate datasource這樣的就用protocol實現(xiàn)比較好 .

Category是對一個功能完備的類的一種補充,就像是一個東西的主要基本功能都完成了,可以用category為這個類添加不同的組件,使得 這個類能夠適應(yīng)不同情況的需求(但是這些不同需求最核心的需求要一致)。找個就像你已經(jīng)有了一輛能夠開動的汽車一樣,我們可以用Category為你的汽 車添加各種之前沒有的功能,最后讓這輛汽車變成超級跑車一樣. 當(dāng)某個類非常大的時候,Category可以按不同的功能將類的實現(xiàn)分在不同的模塊中實現(xiàn)。

繼承則是都可以完成上面的工作,但是繼承有很大的代價問題,一是通過繼承來進(jìn)行擴展是一種耦合很高的行為,對父類可以說是完全依賴;二是繼承由于 對父類依賴,所以開發(fā)代價相對大,要求對父類的工作流程相對熟悉;三是繼承體系如果太復(fù)雜會導(dǎo)致整個系統(tǒng)混亂,難以維護(hù)。所以在能夠用上面兩種方法完成擴 展的時候,就千萬不要使用繼承。什么情況才是迫不得已要使用繼承呢?那就是如果你既想提供一系列接口的定義,同時又想提供一些但是又不能提供全部的實現(xiàn)的 時候,這種情況就要使用繼承了。所以這么看來繼承是對上面兩種功能的一個黏合劑。 關(guān)于category的另外一些見解: . 雖然category可以訪問類的實例變量,去不能創(chuàng)建新的實例變量,如果要創(chuàng)新的實例變量,請使用繼承; .

在category中,不提倡對原有方法進(jìn)行重載。原因非常簡單,在category中進(jìn)行重載,無法對原方法進(jìn)行訪問,而繼承中可以使用super。如果真的需要對原方法進(jìn)行重載,請考慮繼承,比如我要定義一個繼承自UIViewController的類,就不能用Category,因為,這我定義的這個類中,我要實現(xiàn)UIViewController中的viewDidLoad、init等方法,用了category后父UIViewController中的這些方法將無法被調(diào)用一個類可以定義多個category,但是如果不同category中存在相同方法,編譯器無法決定使用哪個category;

在定義category時,我們可以僅僅給出方法定義,而不需要給出具體的實現(xiàn)。這在程序增量開發(fā)時是非常有幫助的;category是可以被繼承的。在某個父類中定義了category,那么他所有的子類都具有該category;在需要為某個類創(chuàng)建私有成員方法時,也用category的方式來實現(xiàn)。 Category不能完全代替子類,有以下幾個最大的缺點: 當(dāng)在Category中覆蓋一個繼承的方法,在Category中的方法可以通過向super類發(fā)送一個消息來調(diào)用被繼承的方法。但是,如果Category中覆蓋的那個方法已經(jīng)在這個類的其它Category定義過了,則之前定義的方法將沒有機會被程序調(diào)用 在Category中無法確定其能夠可靠的覆蓋某個方法,而這個方法已經(jīng)在其它的Category中定義過。這個問題在使用Cocoa框架時尤其 突出。當(dāng)你想覆蓋某個框架已經(jīng)定義好的方法時,該方法已經(jīng)在其它Category中實現(xiàn),這樣就無法確定哪個定義和實現(xiàn)會被最先使用,帶來很大的不確定 性。
.
如果你重新覆蓋定義了一些方法,往往會導(dǎo)致這個方法在整個框架中實現(xiàn)發(fā)生了變化。舉例來說,如果你增加了NSObject中 windowWillClose:的實現(xiàn),這會導(dǎo)致所有的窗口調(diào)用那個新實現(xiàn)的方法,從而改變所有NSWindows實例的行為。這會帶來很多不確定性, 并很有可能導(dǎo)致程序的崩潰

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,938評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,538評論 19 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,185評論 4 61
  • 月落臨滄雁,睡夢尤思念,遙遙千里來相見,奔走急如電。 日落紅光炫,天昏不知倦,悠悠長醉把君勸,莫學(xué)哀婦怨。
    理想者的執(zhí)念閱讀 408評論 0 6
  • 世界上最遙遠(yuǎn)的距離,是我再也見不到你,是再也握不到手,感覺不到溫度,是那再也說不出口的對不起。 世界上最遙遠(yuǎn)的距離...
    風(fēng)行不戀竹清閱讀 601評論 1 1

友情鏈接更多精彩內(nèi)容