《Objective-C基礎編程》讀書筆記3—面向對象編程2

  1. 繼承
  類和對象協(xié)同工作才能使程序實現(xiàn)功能。處理類和對象的關系時,尤其要重視OOP的兩個方面。第一個方面是繼承,創(chuàng)建一個新類時,通常需要根據(jù)它與現(xiàn)有類的區(qū)別來定義。使用繼承可以定義一個具有父類所有功能的新類,即它繼承了父類的功能。另一個和類有關的OOP技術是復合,也就是在對象中可以再引用其他對象。對象引用其他對象時,可以引用其他對象提供的特性,這就是復合。
  1.1為何使用繼承
  UML(Unified Modeling Language, 統(tǒng)一建模語言)是一種用圖表來表示類、類的內容以及它們之間關系的常見方式。UML使用末端帶有箭頭的豎線表示繼承關系。
  編程時如果出現(xiàn)很多的重復內容,就意味著這是一個失敗的架構。OOP中的繼承表明一個類從另一個類—它的父類或超類(superclass)—中獲取了某些特性。
  1.2繼承的語法格式
  某些編程語言(例如C++)具有多繼承性,也就是一個類可以直接從兩個或多個類繼承而來。但是Objective-C不支持多繼承。如果你嘗試在Objective-C中使用多繼承(多繼承的形式類似于以下語句@interface Circle :  NSObject, PrintableObject) 是無法通過編譯器審核的。
  只有代碼精簡,Bug才無處藏身。
  在方法的定義中不寫任何內容或返回一個虛值都是可以通過編譯的。
  移植和優(yōu)化代碼的方式稱為重構。進行重構時,會通過移植某些代碼來改進程序的架構,而不必改變代碼的行為和運行結果。通常開發(fā)周期包括向代碼中添加某些特性,然后通過重構刪除所有重復的代碼。有時在面向對象的程序中添加新特性之后,程序反而變得更簡單。
  超類是繼承的類。父類是超類的另一種表達方式。子類是執(zhí)行繼承的類。孩子類是子類的另一種表達方式。如果要想改變方法的實現(xiàn),需要重寫(override)繼承的方法。代碼運行時,Objective-C會確保調用的是重寫過的方法。
  1.3 繼承的工作機制
  1.3.1 方法調度
  當代碼發(fā)送消息時,Objective-C的方法調度機制將在當前的類中搜索相應的方法。如果無法在接收消息的類文件中找到相應的方法,它就會在該對象的超類中進行查找。必要時這種機制將會在繼承鏈的每一個類重復地執(zhí)行此操作,一直找到最頂層的超類(NSObject)中。如果在最頂層的NSObject類中也沒有找到該方法,則會出現(xiàn)一個運行時錯誤,同時還會出現(xiàn)一個編譯時(Compile-time)警告信息。
  調度程序通過指針來查找正確的代碼。
  1.3.2 實例變量
  在創(chuàng)建一個新類時,其對象首先會從它的超類繼承實例變量,然后根據(jù)自身情況來添加自己的實例變量。
   NSObject類聲明了一個名為isa的實例變量,該變量保存一個指向對象當前類的指針。使用更具體種類的對象來代替一般類型,這種能力被稱為多態(tài)性。每個方法調用都獲得了一個名為self的隱藏參數(shù),它是一個指向接收消息的對象的指針,通過self參數(shù)來尋找所需要的實例變量。self指向繼承鏈中第一個類中的第一個實例變量,所以,self一般指向的是isa。
  編譯器使用“基地址加偏移”的機制實現(xiàn)奇妙的功能。有了對象的基地址,即第一個實例變量的首個字節(jié)在內存中的位置,再在該地址上加上偏移地址,編譯器就可以查找其他實例變量的位置。每個實例變量與對象的基地址都有一個偏移位置。
  1.4重寫方法
  在制作全新的子類時,經(jīng)常會添加自己的方法。有時你會添加一個能夠向類中引入特有功能的新方法,有時你會替換或改進某個超類定義的現(xiàn)有方法。你也可以選擇不添加新特性,而是創(chuàng)建一個子類并通過它重寫繼承自超類的行為。
  Objective-C提供了一種方法,讓你既可以重寫方法的實現(xiàn),又能調度超類中的實現(xiàn)方式。當需要超類實現(xiàn)自身的功能,同時在之前或之后執(zhí)行某些額外的工作時,這種機制非常有用。為了調用繼承的方法在父類中的實現(xiàn),需要使用super作為方法調用的目標。Super既不是參數(shù)也不是實例變量,而是由Objective-C編譯器提供的一種神奇的功能。當你向super發(fā)送消息時,實際上是在請求OC向該類的超類發(fā)送消息。如果超類中沒有定義該消息,OC會向平常一樣繼續(xù)在繼承鏈上一級中查找。
  調用繼承的方法可以確保獲得方法實現(xiàn)的所有特性。繼承是在兩個類之間建立關系的一種方式,可以避免許多重復的代碼。       
  復合(讓不同的對象協(xié)同工作的一種方式)— 建立類之間關系的另外一種方式。
  復合是通過包含作為實例變量的對象指針實現(xiàn)的。只有對象間的組合才能叫做復合。諸如int、float、enum和struct等基本類型只被認為是對象的一部分。
  如果在類中沒有包含實例變量,便可以省略掉接口定義中的花括號。
  2.1 自定義NSLog()   
  NSLog()可以使用%@格式說明符來輸出對象。
  NSLog()處理%@說明符時,會詢問參數(shù)列表中相應的對象以得到這個對象的描述。從技術上來講,也就是NSLog()給這個對象發(fā)送了description消息,然后對象的description方法生成一個NSString并將其返回。NSLog()就會在輸出結果中包含這個字符串。在類中提供description方法就可以自定義NSLog()會如何輸出對象。在自定義的description方法中,你可以選擇返回一個字面量值NSString ,  也可以構造一個用來描述該對象各類信息的字符串。
  在Cocoa中,NSArray類管理的是對象的集合,它的description方法提供了數(shù)組自身的信息,例如數(shù)組中對象的個數(shù)和每個對象所包含的描述。對象的描述是通過向數(shù)組中的每個對象分別發(fā)送description消息來獲得的。
  每一個類實例對象都會為指向它的實例變量的指針分配內存,真正包含在類實例對象中的并不是它的實例變量,只是內存中存在的其他對象的引用指針。
  使用new創(chuàng)建新對象時,系統(tǒng)其實在后臺執(zhí)行了兩個步驟:第一步,為對象分配內存,即對象獲得一個用來存放實例變量的內存塊;第二步,自動調用init方法,使該對象進入可用狀態(tài)。
  為了讓超類將所有需要的初始化工作一次性完成,你需要調用[super init]。init方法返回的值(id類型數(shù)據(jù),即泛型對象指針)就是被初始化的對象。將[super init]返回的結果賦給self是OC的慣例。這樣做的目的是為了防止超類在初始化過程中返回的對象與一開始創(chuàng)建的不一致。
  2.2 存取方法
  存取方法是用來讀取或改變某個對象屬性的方法。為對象中的變量賦值的方法稱為setter方法。mutator方法是用來更改對象狀態(tài)的。getter方法為代碼提供了通過對象自身訪問對象屬性的方式。
  如果要對其他對象中的屬性進行操作,應該盡量使用對象提供的存取方法,絕對不能直接改變對象里面的值。存儲方法是程序間接工作的另一個例子。(通過對象自身訪問對象屬性或者對對象屬性進行設置)
  存取方法總是成對出現(xiàn)的。一個用來設置屬性的值,另一個用來讀取屬性的值。有時只有一個getter方法(用于只讀屬性,例如磁盤上文件的大小)或者只有一個setter方法(例如設置密碼)也是合理的。
  對于存取方法的命名,Cocoa有自己的慣例。setter方法根據(jù)它所更改的屬性的名稱來命名,并加上前綴set。getter方法則以其返回的屬性名稱命名。
  2.2.1 設置對象屬性的存取方法
  在OC中所有對象間的交互都是通過指針實現(xiàn)的。
  防御式編程是一種很好的編程思想。防御式編程能夠在開發(fā)早期發(fā)現(xiàn)錯誤。例如用通用代碼來檢查數(shù)組的索引下表是否超出范圍。數(shù)組越界是程序開發(fā)中常見的一種錯誤。數(shù)組的下表范圍(0~數(shù)組長度-1),若使用超出這個范圍內的索引值便會訪問到內存中的隨機值,由此產(chǎn)生的Bug會導致程序crash。
  重構(重構程序,改進內部結構,并不影響它的外部行為)。
  2.3 復合還是繼承?
  繼承的類之間建立的關系為“is a”(是一個)。如果可以說“X是一個Y”, 那就可以使用繼承。復合的類之間建立的關系為“has a”(有一個)。如果可以說“X有一個Y”,那么就可以使用復合。應當在適當?shù)臅r機使用繼承和復合特性。
  復合是OOP的基礎概念,我們通過這種技巧來創(chuàng)建引用其他對象的對象。存取方法,既為外部對象提供了改變其屬性的途徑,同時又能保護實例變量本身。  存取方法和復合是密不可分的,因為我們通常都會為復合的對象編寫存取方法。有兩種類型的存取方法:setter方法和getter方法,前者告訴對象將屬性改為什么,后者要求對象提供屬性的值。對于返回屬性值的存取方法,名稱中不能使用get這個詞。       
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 一.條件語句 1.條件語句體應該總是被大括號包圍來避免錯誤,即使可以不用。 推薦: 不推薦: 不推薦: 2.不要使...
    愛抽煙的芭比閱讀 157評論 0 2
  • 工廠方法模式 定義創(chuàng)建對象的接口,讓子類決定實例化哪一個類。工廠方法使得一個類的實例化延遲到其子類。 生成器模式 ...
    herui201211閱讀 1,468評論 0 2
  • 像一部蹩腳的諜戰(zhàn)劇 以白描的方式鋪開 沒有臥底 沒有偽裝 也沒有情報交換 有的只是噴薄的渴望 和直奔主題的慌張 兩...
    微語素心閱讀 287評論 0 1
  • 參加30天寫作計劃,我一天都沒有違規(guī)。 寫作計劃進行到一半的時候,有個群友私信說,她覺得沒有找到她想要的,不想繼續(xù)...
    傻狍子616閱讀 641評論 0 0
  • 《荷塘心事》(外一組) 1、 初荷尖尖,顰首低吟, 誰是歇在額頭的蜻蜓, 誰是伴在身邊嬉戲的游魚? 2、 蓮花從綠...
    不語不問閱讀 194評論 0 3

友情鏈接更多精彩內容