自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Cocoa 繼承類

移動(dòng)開發(fā) iOS
一個(gè)類通常會(huì)完成很多低級(jí)別的、公用的代碼,而將工作的相當(dāng)一部分留下來(lái),或者以安全而又一般的“缺省”方式來(lái)完成。

Cocoa 繼承是本文要介紹的內(nèi)容,象Application Kit這樣的框架都定義某種程序模型。由于這個(gè)模型具有一般性,很多不同型的應(yīng)用程序都可以共享。也由于這個(gè)模型具有一般性,框架中的某些是抽象或有意沒有完成也并不奇怪。一個(gè)通常會(huì)完成很多低級(jí)別的、公用的代碼,而將工作的相當(dāng)一部分留下來(lái),或者以安全而又一般的“缺省”方式來(lái)完成。

應(yīng)用程序通常需要?jiǎng)?chuàng)建子來(lái)填充超留下的缺口,提供框架類缺少的東西。子是向框架添加具體應(yīng)用程序行為的基本途徑。定制子的實(shí)例在框架定義的對(duì)象網(wǎng)絡(luò)中代替其超的位置,并通過(guò)繼承從超得到與框架中其它對(duì)象協(xié)同工作的能力。舉例來(lái)說(shuō),如果您創(chuàng)建了一個(gè)NSCell的子,則這個(gè)新的實(shí)例可以出現(xiàn)在NSMatrix對(duì)象中,就象NSButtonCell、NSTextFieldCell、以及其它框架定義的cell對(duì)象一樣。

在制作子類時(shí),一個(gè)主要的任務(wù)就是實(shí)現(xiàn)一組由超類(或者超類采納的協(xié)議)聲明的具體方法。重新實(shí)現(xiàn)超類的方法被稱為對(duì)該方法進(jìn)行重載。

何時(shí)進(jìn)行方法的重載

框架類中定義的大多數(shù)方法都是完全實(shí)現(xiàn)的,您可以對(duì)其進(jìn)行調(diào)用,以得到它們提供的服務(wù)。您很少需要重載這種方法,而且也不應(yīng)該試圖這樣做。依賴于這些類的框架只是做它們應(yīng)該做的事—既不多,也不少。在某些場(chǎng)合下,您可以對(duì)這些方法進(jìn)行重載,但是沒有真正的原因需要這么做,框架版本的方法已經(jīng)足夠了。但是,正如您可能實(shí)現(xiàn)您自己的字符串比較函數(shù)、而不是使用strcmp函數(shù)那樣,如果您愿意,可以選擇重載框架的方法。

然而,有些框架方法的設(shè)計(jì)目的就是為了被重載的,您可以通過(guò)這種方式向框架加入程序的具體行為。這些方法在框架中的實(shí)現(xiàn)對(duì)應(yīng)用程序通常價(jià)值很小,或者沒有價(jià)值,但會(huì)在其它框架方法發(fā)出的消息中被調(diào)用。應(yīng)用程序必須實(shí)現(xiàn)自己的版本,為這些方法加入新的內(nèi)涵。

調(diào)用還是重載?

一般來(lái)說(shuō),您自己并不調(diào)用,至少不直接調(diào)用在子類中重載的框架方法。您只要簡(jiǎn)單地重新實(shí)現(xiàn)這些方法,然后將它留給框架就好了。實(shí)際上,越是那些實(shí)現(xiàn)應(yīng)用程序具體行為的版本,您自己的代碼對(duì)它調(diào)用的可能性就越小。這有一個(gè)很好的原因。在一般意義上,框架類負(fù)責(zé)聲明一些公共方法,您作為開發(fā)者可以有兩種使用方式:

調(diào)用這些方法,使類提供的服務(wù)為您所用

對(duì)這些方法進(jìn)行重載,將您的代碼引入到框架定義的程序模型中

有些時(shí)候,一個(gè)方法會(huì)同時(shí)符合上述兩種情況,既可以通過(guò)被調(diào)用提供有價(jià)值的服務(wù),也可以被策略性地重載。但是一般來(lái)說(shuō),一個(gè)方法如果可以被調(diào)用,就已經(jīng)由框架完全定義好了,不需要在您的代碼中進(jìn)行精化;如果該方法需要在子類中重新實(shí)現(xiàn),則說(shuō)明框架為該方法分派了特殊的工作,而且會(huì)在恰當(dāng)?shù)臅r(shí)候?qū)ζ溥M(jìn)行調(diào)用。圖3-2顯示了這兩種一般類型的框架方法。

圖 調(diào)用一個(gè)框架方法,該方法又通過(guò)消息調(diào)用一個(gè)重載了的方法

Cocoa 繼承類

使用Cocoa框架進(jìn)行面向?qū)ο缶幊痰拇蟛糠止ぷ魇菍?shí)現(xiàn)一些方法,而您的程序只是間接地、通過(guò)框架安排的消息使用這些方法。

重載方法的類型

您可以選擇在子類中定義幾個(gè)不同類型的方法:

某些框架方法是完全實(shí)現(xiàn)的,且其設(shè)計(jì)的目的是被別的框架方法調(diào)用。換句話說(shuō),即使您重新實(shí)現(xiàn)這些方法,通常也不在其它代碼的其它地方調(diào)用。它們提供特定的服務(wù)—數(shù)據(jù)或行為,這些服務(wù)是程序執(zhí)行過(guò)程中某些地方的代碼要求的。這些方法存在于公共接口中只有一個(gè)原因—就是讓您在需要的時(shí)候可以對(duì)其進(jìn)行重載,這使您有機(jī)會(huì)用自己的算法來(lái)替代框架使用的算法,或者對(duì)框架的算法進(jìn)行修改和擴(kuò)展。

這種類型的方法的一個(gè)例子是NSMenuView類定義的trackWithEvent:方法。NSMenuView類實(shí)現(xiàn)這個(gè)方法是為了滿足看得見的需求—處理菜單跟蹤和菜單項(xiàng)的選擇,但是如果您希望實(shí)現(xiàn)不同的行為,則可以對(duì)其進(jìn)行重載。

另一類方法負(fù)責(zé)做一些與具體對(duì)象有關(guān)的決定,比如是否打開某個(gè)屬性,或者是否讓特定的策略起作用??蚣転檫@種方法實(shí)現(xiàn)一個(gè)缺省版本,從而提供一種工作方式,如果您需要有所改變,就必須實(shí)現(xiàn)自己的版本。在大多數(shù)情況下,實(shí)現(xiàn)就是簡(jiǎn)單地返回YES或者NO,或者對(duì)某個(gè)值進(jìn)行計(jì)算,而不是使用缺省值。

NSResponder類的acceptsFirstResponder方法就是一個(gè)典型的例子。系統(tǒng)向視圖對(duì)象發(fā)送消息中包含acceptsFirstResponder消息,用于詢問它們是否響應(yīng)按鍵或鼠標(biāo)點(diǎn)擊事件。缺省情況下,NSView對(duì)象在這個(gè)方法中返回NO—大多數(shù)視圖對(duì)象并不接收按鍵輸入。但是某些視圖對(duì)象卻是可以的,因此它們必須重載acceptsFirstResponder方法,使之返回YES。

某些方法必須被重載,但只是增加一些處理,而不是完全取代框架的實(shí)現(xiàn)。這種方法的子類版本對(duì)超類版本的行為進(jìn)行增強(qiáng)。您的程序在實(shí)現(xiàn)這種方法時(shí),很重要的一點(diǎn)是要吸收被重載方法,即向super(超類)對(duì)象發(fā)送消息,調(diào)用框架為該方法定義的版本。

這類方法通常是繼承鏈中的每個(gè)類都希望有所貢獻(xiàn)的。舉例來(lái)說(shuō),可以自行歸檔的對(duì)象必須遵循NSCoding協(xié)議,并且實(shí)現(xiàn)initWithCoder:和encodeWithCoder:方法。但是,一個(gè)類在對(duì)自己特有的實(shí)例變量進(jìn)行編解碼的時(shí)候,必須調(diào)用相應(yīng)方法的超類版本。

有些時(shí)候,方法的子類版本希望“重用”超類的行為,然后在***的結(jié)果中加入一些小變化。比如NSView類的drawRect:方法,執(zhí)行某些復(fù)雜描畫的視圖子類可能希望在描畫結(jié)果中加上一個(gè)邊界,這樣就要首先調(diào)用super版本的方法。

某些框架方法什么事情都不做,或者只是返回一些試驗(yàn)性的缺省值(比如self),避免運(yùn)行時(shí)或編譯時(shí)的錯(cuò)誤。這些方法的設(shè)計(jì)目的就是為了被重載。即便是最基本的行為,框架也無(wú)法為它們定義,因?yàn)樗鼈儓?zhí)行的任務(wù)全部和具體程序相關(guān)。對(duì)于這種方法,沒有必要通過(guò)向super發(fā)送消息來(lái)調(diào)用框架的實(shí)現(xiàn)。

子類重載的大部分方法都是這種類型。比如NSDocument類的dataOfType:error:和readFromData:ofType:error:(還有其它)方法,在您創(chuàng)建基于文檔的應(yīng)用程序時(shí)必須被重載。

對(duì)一個(gè)方法進(jìn)行重載并不一定很難。通過(guò)認(rèn)真地重寫方法中的一兩行代碼,您常常就能顯著改變超類的行為。在實(shí)現(xiàn)自己版本的方法時(shí),也不是完全從頭開始,您可以借助Cocoa框架提供的類、方法、和類型。

什么時(shí)候需要使用子類

和了解類的哪些方法需要重載—并真正地實(shí)施重載—一樣重要的是,識(shí)別哪些類需要被繼承。有些時(shí)候,這些決定可能是很明顯的,而在另一些時(shí)候,做這樣的決定則相當(dāng)不簡(jiǎn)單。下面的一些設(shè)計(jì)上的考慮可以指導(dǎo)您做這樣的選擇。

首先,連接框架。您應(yīng)該熟悉每個(gè)框架類的目的和能力。您希望做的事情可能已經(jīng)在某個(gè)類中實(shí)現(xiàn)了,或者如果您發(fā)現(xiàn)希望完成的任務(wù)在某個(gè)類中已經(jīng)差不多完成了,那就很幸運(yùn)了,那個(gè)類很可能是您需要的定制類的超類。子類化是重用現(xiàn)有的類、并根據(jù)需要將它具體化的過(guò)程。有些時(shí)候,一個(gè)子類需要做的所有工作,就是對(duì)一個(gè)方法進(jìn)行重載,并使它的行為和超類版本輕微不同。其它子類可能在超類的基礎(chǔ)上增加一兩個(gè)屬性(以實(shí)例變量的形式),然后實(shí)現(xiàn)一些訪問和操作這些屬性的方法,從而將它們集成到超類的行為中。

在決定子類在類層次中的位置時(shí),還有其它一些有益的考慮。您希望開發(fā)的應(yīng)用程序、或者應(yīng)用程序的一部分的本質(zhì)是什么?有些Cocoa架構(gòu)對(duì)子類有些要求。舉例來(lái)說(shuō),如果您開發(fā)的是一個(gè)多文檔的應(yīng)用程序,則Cocoa基于文檔的架構(gòu)就要求您生成NSDocument類的子類,可能還有其它類。如果要讓您的應(yīng)用程序可以通過(guò)腳本進(jìn)行控制(也就是說(shuō),可以響應(yīng)AppleScript命令),可能必須生成諸如NSScriptCommand這樣的腳本類的子類。

另一個(gè)因素是子類的實(shí)例在應(yīng)用程序中發(fā)揮的作用。模型-視圖-控制器模式是Cocoa的主要設(shè)計(jì)模式,它將對(duì)象的角色做如下分配:出現(xiàn)在用戶界面上的對(duì)象屬于視圖對(duì)象,模型對(duì)象負(fù)責(zé)保存應(yīng)用程序數(shù)據(jù)(和對(duì)該數(shù)據(jù)進(jìn)行操作的算法),控制器對(duì)象則負(fù)責(zé)協(xié)調(diào)視圖對(duì)象和模型對(duì)象(詳細(xì)信息請(qǐng)參見"模型-視圖-控制器設(shè)計(jì)模式"部分)。

了解一個(gè)對(duì)象的作用可以收窄其超類的選擇范圍。如果您的類實(shí)例是實(shí)現(xiàn)定制描畫和事件處理的視圖對(duì)象,可能應(yīng)該選擇NSView作為超類;如果您的應(yīng)用程序需要一個(gè)控制器類,則可以使用某個(gè)復(fù)活類(比如NSObjectController類),或者如果您希望有不同的行為,也可以從NSController或NSObject派生出子類;如果您的類是一個(gè)典型的模型類—比如代表一個(gè)電子表格數(shù)據(jù)中的行的類—則可能應(yīng)該從NSObject派生出子類,或者使用Core Data框架。

然而生成子類有時(shí)并不是解決問題的***辦法,可能有更好的辦法可以選擇。如果您只是希望為某個(gè)類增加一些便利方法,就可以通過(guò)創(chuàng)建范疇來(lái)實(shí)現(xiàn),而不需要生成子類;或者,您也可以借助基于Cocoa開發(fā)“工具箱”資源的很多其它設(shè)計(jì)模式之一來(lái)實(shí)現(xiàn),比如委托、通告、和目標(biāo)-動(dòng)作模式(在"和對(duì)象進(jìn)行通訊"部分中描述)。在確定使用某個(gè)候選超類之前,先掃描一下它的頭文件(或參考文檔),看看是否有什么委托方法、通告、或者其它機(jī)制可以實(shí)現(xiàn)您需要的功能,而又不需要生成子類。

類似地,您也可以考察一下框架協(xié)議的頭文件或文檔。通過(guò)采納協(xié)議,您既可以完成目標(biāo),又可以規(guī)避復(fù)雜子類的困難工作。舉例來(lái)說(shuō),假定您希望管理菜單項(xiàng)的激活狀態(tài),則可以在定制的控制器子類中采納NSMenuValidation協(xié)議,而不必從NSMenuItem或NSMenu派生子類來(lái)得到這個(gè)行為。

和某些框架方法不用于被重載一樣,一些框架類(比如NSFileManager、NSFontPanel、和NSLayoutManager)也不用于生成子類。如果您確實(shí)希望有這樣的子類,則應(yīng)該謹(jǐn)慎處理。某些框架類的實(shí)現(xiàn)是相當(dāng)復(fù)雜的,和其它類的實(shí)現(xiàn)、甚至是操作系統(tǒng)的不同部分緊密結(jié)合在一起。通常情況下,我們很難正確復(fù)制框架方法的行為,或者預(yù)期這種方法可能有的依賴性和效果。您對(duì)一些方法實(shí)現(xiàn)的修改,可能帶來(lái)深遠(yuǎn)的、不可預(yù)見的、以及不希望的結(jié)果。

在某些情況下,您可以通過(guò)對(duì)象的合成來(lái)克服這種困難。對(duì)象的合成是一種將多個(gè)對(duì)象裝配到一個(gè)“宿主”對(duì)象中的通用技術(shù),宿主對(duì)象負(fù)責(zé)管理這些對(duì)象,并獲得復(fù)雜而又高度定制的行為(參見圖 3-3)。您不必直接從一個(gè)復(fù)雜的框架超類繼承子類,而是創(chuàng)建一個(gè)定制類,然后將超類的實(shí)例作為類的一個(gè)實(shí)例變量。定制類自身可能相當(dāng)簡(jiǎn)單,可能直接從NSObject根類繼承就可以了。雖然從繼承的角度來(lái)看是簡(jiǎn)單了,但是該類負(fù)責(zé)對(duì)嵌入的實(shí)例進(jìn)行操作、擴(kuò)展、和增強(qiáng)。對(duì)于客戶對(duì)象來(lái)說(shuō),該類在某些方面就象是復(fù)雜超類的子類,雖然它可能并不共享超類的接口。

Foundation框架中的NSAttributedString類就是對(duì)象合成的一個(gè)實(shí)例。NSAttributedString以實(shí)例變量的形式保有一個(gè)NSString對(duì)象,并通過(guò)string方法將它暴露給客戶代碼。NSString是一個(gè)具有復(fù)雜行為的類,包括字符串編碼、字符串檢索、以及路徑處理。NSAttributedString則在這些行為的基礎(chǔ)上加入了新的能力,可以將字體、顏色、對(duì)齊、以及段落風(fēng)格這樣的信息附加到某個(gè)范圍的字符中,而且在不生成NSString子類的前提下實(shí)現(xiàn)這個(gè)增強(qiáng)。

圖  對(duì)象合成

Cocoa 繼承類

有些時(shí)候,看起來(lái)很明顯的超候選者其實(shí)并不是***的選擇。您可能知道,Cocoa在大多數(shù)情況下都用NSView對(duì)象來(lái)進(jìn)行描畫。但是如果您正在設(shè)計(jì)的描畫程序或CAD程序可能具有成千上萬(wàn)個(gè)圖形元素,則應(yīng)該考慮使用您自行定制的圖形元素,而不是從NSView繼承。從對(duì)象尺寸的角度看,一個(gè)NSView對(duì)象攜帶很多實(shí)例數(shù)據(jù),而您定制的的圖形元素實(shí)例可以是“輕量級(jí)”的,但又包含NSView對(duì)象中用于描畫的所有信息。

責(zé)任編輯:zhaolei 來(lái)源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-08-08 09:51:52

Cocoa 框架

2011-07-07 13:59:49

Cocoa Objective- 根類

2012-05-21 09:58:30

動(dòng)態(tài)創(chuàng)建類Cocoa

2011-08-11 15:46:55

CocoaCocoa Touch框架

2012-05-21 09:51:25

對(duì)象Cocoa

2011-08-10 18:37:32

CocoaMac OS X

2011-05-11 15:27:58

Windows OOPCocoa MVCCocoa

2011-07-07 13:51:24

Cocoa 框架

2011-05-25 16:23:35

Javascript類繼承

2009-07-08 17:42:26

this屬性

2011-07-07 13:30:32

Cocoa Core

2011-08-12 14:54:45

iPhone委托

2009-12-08 17:29:26

PHP extends

2009-08-31 18:46:05

繼承System.Ob

2010-01-21 13:48:30

C++基類

2009-07-08 17:51:45

constructor

2009-07-08 17:48:18

prototype屬性

2011-07-07 14:22:27

Cocoa 對(duì)象 生命周期

2009-09-09 11:28:40

Scala類

2011-06-17 16:23:49

Cocoa蘋果
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)