類
面向?qū)ο蟮某绦蛲ǔ6际怯懈鞣N各樣的對象構(gòu)成的坤候⌒灿基于Cocoa框架的程序可能用到了NSMatrix對象,NSWindow對象白筹,NSDictionary對象智末,NSFont對象,NSText對象以及其他的許多種類的對象徒河。程序中通常也是使用某個類的多個對象系馆,而不是一個。比如顽照,多個NSArray類的對象或者是多個NSWindow類的對象由蘑。
在Objective-C中,通過定義對象所屬的類來定義對象代兵。類是一種類型對象的原型尼酿。其中聲明了屬于該類的每個對象的成員變量,并定義了該類所有對象都能使用的方法奢人。
編譯器只會為一個類創(chuàng)建一個可以訪問的對象谓媒,那就是類對象。類對象知道如何去生成該類的對象何乎。正是基于這種原因句惯,類對象通常都會被稱為是工廠對象土辩。類對象是類在編譯時期的版本。類對象生成的對象才是類的實例抢野。程序中進(jìn)行實際工作的都是由該類對象創(chuàng)建出來的實例對象拷淘。
類的所有實例共有一套方法集,但是各自都含有自身的實例變量指孤。每一個對象的實例變量是自己獨有的启涯,但是所有方法是共享的。
按照慣例恃轩,類名稱首字母一般是大寫的结洼,例如Rectangle。實例變量的名稱首字母通常是小寫的叉跛,如myRectangle松忍。
繼承
類的定義是具有追加性的。每一個從其他類派生而來的新類都繼承了其中的方法和實例變量筷厘。新的類知識簡單地對這些繼承的東西進(jìn)行追加或者修改鸣峭,而不需要復(fù)制其對應(yīng)的代碼。
繼承把所有的類都關(guān)聯(lián)起來酥艳,從而形成一個具有唯一一個根節(jié)點的繼承關(guān)系圖摊溶。當(dāng)編寫基于“Foundation framework基礎(chǔ)框架”的程序的時候,這個跟類就是NSObject充石。繼承圖中出了跟類之外的所有類都有一個超類莫换,這個超類在繼承關(guān)系圖上距離跟類更進(jìn)一步。任何類赫冬,包括跟類都可以是多個類的超類浓镜,其子類在繼承關(guān)系圖上距離跟類更遠(yuǎn)一步。圖1-1展示了在繪圖程序中可能用到得類的繼承關(guān)系圖:
從上圖中可以看出Square類是Rectangle類的子類劲厌;Rectangle類Shape類的子類膛薛;Shape類是Graphic類的子類;Graphic類是NSObject類的子類补鼻。 繼承關(guān)系具有累積性哄啄。因此,Square類的對象擁有在Rectangle類风范,Shape類咨跌,Graphic類已經(jīng)NSObject類中定義的方法以及實例變量。當(dāng)然Square類的對象擁有在Sqaure類自身中定義的實例變量和方法硼婿。簡而言之锌半,一個Square類的對象不僅僅是一個方形(square),同時也是一個矩形(rectangle)寇漫,也是一個形狀(shape)刊殉,也是一個圖形(Graphic)殉摔,還是一個對象(NSObject)。
除了NSObject類之外的每一個類都可以被看做是對其超類的具體化记焊。其后的每一個子類都是對這種累積繼承的修改逸月。Square類中定義的只是把一個矩形rectangle變成是一個方形所需的最小修改。
在定義類的時候是通過聲明其超類來把該類連接到類的繼承關(guān)系圖中的遍膜。我們創(chuàng)建的每一個類都應(yīng)該是另外一個類的子類碗硬,除非我們想要定義的是跟類。其中可選的超類是很多的瓢颅。Cocoa中包含了NSObject以及幾個框架恩尾。其中就包含了超過250多種的類。其中有很多類是我們可以直接拿來在我們的程序中使用的惜索。還有一些其他的類特笋,我們可以根據(jù)我們的需要,通過定義其子類來對其進(jìn)行修改巾兆。
上面說到的一些框架類幾乎定義了我們所需的全部東西,但是把某些詳細(xì)的實現(xiàn)留個了子類虎囚。因此我們只需要根據(jù)我們的需要編寫少量的代碼角塑,而復(fù)用這些已有的東西來快速地編寫出可靠的代碼。
NSObject類
NSObject類是一個跟類淘讥,他不需要超類圃伶。其中定義了Objective-C中的對象以及對象交互所需的基本框架。通過繼承NSObject類蒲列,這種對象的行為能力以及與運行時交互的能力在其子類中傳播
開來窒朋。
不需要從別的類中繼承特殊行為的類至少應(yīng)該是NSObject類的子類。因為該類的實例至少在運行時應(yīng)該具有Objective-C對象所具有的基本能力蝗岖。從NSObject類繼承這種能力和在新類中重新定義這些能力先比則更簡單并且更可靠侥猩。
注意:實現(xiàn)一個全新的跟類是一件十分復(fù)雜的任務(wù),并且具有潛在的危險性抵赢。該類必須重復(fù)在NSObject類中已經(jīng)完成的大量工作欺劳。比如分配實例,并把它與對應(yīng)的類相關(guān)聯(lián)铅鲤,并在運行時對其進(jìn)行鑒別等划提。正是如此,我們應(yīng)該使用Cocoa中提供的NSObject類來作為跟類邢享。更多信息參見《NSObject 協(xié)議參考》一書中的“NSObject 類參考”章節(jié)鹏往。
繼承實例變量
當(dāng)一個類對象創(chuàng)建一個新的實例的時候,該實例不僅含有其類中所定義的實例變量骇塘,還含有其類的超類中所定義的實例變量伊履,還含有其超類的超類中所定義的實例變量袜漩,這樣依此類推知道根類。這樣以來NSObject類中定義的實例變量就成了所有對象都擁有的變量湾碎。正是isa 把一個對象和其對應(yīng)的類聯(lián)系起來了宙攻。
圖1-2展示了一種可能的Rectangle類的實現(xiàn),其中包含包含了Rectangle類中定義的變量介褥,Shape類中定義的變量座掘,Graphic類中定義的變量以及NSObject類中定義的變量。
類中定義實例變量并不是必要的柔滔。一個類可以只定義新的方法溢陪,而完全依靠繼承而來的那些實例變量。例如睛廊,Square類自身中就可以不用定義任何實例變量形真。
繼承方法
對象不僅可以訪問其類中定義的方法,還可以訪問其超類中定義的方法超全,以及其超類的超類中定義的方法咆霜,依此類推知道根類。例如嘶朱,Square類的對象就可以使用Rectangle類蛾坯,Shape類,Graphic類以及NSObject類中定義的方法疏遏。
因此脉课,程序中的新定義的類可以復(fù)用在繼承關(guān)系圖圖中位于其上方的所有超類的代碼。這種繼承機(jī)制是面型對象編程的一個很重要的好處财异。當(dāng)我們Cocoa提供的面向?qū)ο蟮目蚣茴惖臅r候倘零,我們的程序就可以利用這些已經(jīng)為該框架類編寫好的代碼功能。我們在程序中只需要根據(jù)需要增加一些代碼來完成特性的功能戳寸。
在繼承關(guān)系圖中呈驶,類對象也繼承了位于其上方的超類。但是由于類對象沒有實例變量庆揩,因此他們只是繼承了方法俐东。
方法的覆蓋
繼承機(jī)制中有一個很有用的特殊情況:在定義新的類的時候,我們可以在新的類中實現(xiàn)在繼承關(guān)系圖途中和其超類中同名的函數(shù)订晌。這個新的方法就覆蓋了原來的方法虏辫。新的類的實例將執(zhí)行的是該新的方法而不是原來的方法。該新類的派生類繼承的也將是該新的方法而不是原來的方法锈拨。
例如砌庄,Graphic類中定義了display方法,而在在Rectangle類中是可以通過定義新的display的實現(xiàn)而覆蓋繼承而來的原有的display方法。Graphic類中的方法對于它的所有派生類都是可用的娄昆,而Rectangle類除外佩微,Rectangle類將執(zhí)行的是自身的Rectangle類的display方法。
盡管這種覆蓋機(jī)制可以阻止原來的方法被繼承萌焰,但是新類中的其他方法卻是可以跳過這個新的方法而使用原來的方法的哺眯。更多信息參見“向self和super發(fā)送消息”章節(jié)。
新定義的方法中是可以使用被他覆蓋的原來的方法的扒俯。此時奶卓,新的方法是對原有方法的更新或者是修改,而不是對其進(jìn)行完全的替換撼玄。當(dāng)繼承關(guān)系圖中的多個類都定義了同樣的方法夺姑,但是如果每一個的實現(xiàn)都使用到了被覆蓋的原來的方法的話,原來方法中的實現(xiàn)便會在這些類中蔓延開來掌猛。
盡管派生類是可以覆蓋繼承而來的方法的盏浙,但是派生類不能覆蓋繼承而來的實例變量。這是因為在為對象分配空間的時候荔茬,是為對象的每個實例變量废膘,包括繼承而來的實例變量都要分配空間。因此不能企圖通過在派生類中定義與超類中同名的實例變量來覆蓋超類的實例變量兔院。如果確實遇到了這樣的代碼殖卑,編譯時,編譯器會報告告警或者錯誤的坊萝。
抽象類
一些類在設(shè)計的時候就是希望被別的類繼承。這種抽象的類只是方法和實例變量組合起來许起,以便于可以被更加通用的派生類使用十偶。這種抽象類自身是不完全的,但是含有能夠減輕其派生類代碼負(fù)擔(dān)的有用代碼园细。由于抽象類必須有派生類才顯得有意義惦积,因此它們有時會被成為抽象的超類。
與其他的語言不同的是Objective-C語言中沒有專門的語法來標(biāo)識一個類是抽象類猛频,因此也不會阻止我們在程序中創(chuàng)建抽象類的實例狮崩。
在Cocoa中,NSObject類就是公認(rèn)的這樣的抽象類鹿寻。在程序中我們是不會直接使用到NSObject類的實例的睦柴。因為這樣做沒有任何用,這樣的對象將是一個泛化的對象毡熏,他沒有任何具體的功能 ? ?坦敌。
NSView類也是抽象類的一個例子。該類的實例可能會被偶爾使用到。
抽象類中通常含有的是用于定義程序結(jié)構(gòu)的代碼狱窘。當(dāng)我們定義這些抽象類的派生類的以后杜顺,這些派生類可以很方便地適應(yīng)程序框架工作,并自動地相互配合工作蘸炸。
下圖為今年部分iOS開發(fā)的視頻教程躬络,因為不定時更新中故不做多的截圖,如果有iOS開發(fā)上的問題不懂或者需要視頻教程可以看我的個人簡介搭儒。
因為三月還沒結(jié)束穷当,故不截圖,不定時更新中。