協議的必要性是抽象不分級相關的類的方法。爲什麼我們需要目標C中的協議?
類似的事情也可以通過幫助一個類(接口)來完成,該類包含所有這些方法並對它們進行子類化? (這是不可能的,因爲多重繼承問題,因爲類必須已經從NSObject.ignore派生出NSProxy的情況)
協議可以做什麼特殊的事情比類?
協議是否試圖解決多重繼承問題?
協議的必要性是抽象不分級相關的類的方法。爲什麼我們需要目標C中的協議?
類似的事情也可以通過幫助一個類(接口)來完成,該類包含所有這些方法並對它們進行子類化? (這是不可能的,因爲多重繼承問題,因爲類必須已經從NSObject.ignore派生出NSProxy的情況)
協議可以做什麼特殊的事情比類?
協議是否試圖解決多重繼承問題?
協議的主要優點是,它們描述了一個對象應該能夠做什麼,而不需要實施子類。在沒有多重繼承的語言中,這種機制是必需的,如果你希望其他程序員能夠使用你的類。 (見delegation)
java的,即具有something similar, called interfaces.
這意味着一個巨大的優勢,因爲它是很容易建立動態的系統,我可以允許其他開發人員通過一個明確的協議,提高我的班。
一個實際的例子:
我只是設計了一個REST API,我正在提供一個Objective-C客戶端庫。
由於我的API需要有關用戶的信息,我想補充協議
@protocol VSAPIClientUser <NSObject>
-(NSString *)lastName;
-(NSString *)firstName;
-(NSString *)uuid;
@end
無論我需要這個用戶的信息,我將有一個基本的ID對象,必須符合該協議
-(void)addUserWithAttributes:(id<VSAPIClientUser>)user;
您可以閱讀這一行:「我不在乎,您提供什麼樣的對象,只要它知道lastName
,firstName
和uuid
」。所以我不知道該物體的其餘部分是怎樣的 - 我不在乎。 BTW
NSDictionary *userAttributes = @{@"last_name" : [user lastName],
@"first_name": [user firstName],
@"uuid": [user uuid]};
:
隨着庫的作者,我可以放心地使用這個我不會把沒有多繼承的問題。這只是另一種設計。
「[...]如果我今天重新審視這個決定,我甚至可能去除單一繼承。繼承並不重要。封裝是OOP的持久貢獻。「 - Brad Cox被問到,爲什麼Objective-C沒有多重繼承。 (編程的策劃者:與主要的編程語言的創造者對話,第259頁)
一個C++抽象類的許多用途之一是,他們的其他用途,來定義接口(可指定可重複使用的合同)。然而,還有其他的編程語言,比如Objective C,它在這個意義上具有單獨的接口概念;在Objective C中,它被稱爲協議。
這種構造的廣泛使用確實需要將多個契約附加到對象的方法;並且如果允許這樣的接口彼此繼承,則這必須是多重繼承纔有用。
但是,這與類之間的多重繼承不是一回事。
協議並不試圖解決多重繼承問題。他們試圖將合同規範與對象(數據+代碼)規範分開。實際上,他們可以比類更少的(如果您忽略多重繼承方面),這就是爲什麼它們作爲單獨的概念存在的原因。
實現一個協議通常是一個限制性更小(更安全)的提議,而不是從類繼承。
作爲另一種觀點....
面向對象編程的最基本的價值來自於能夠真實世界的關係建模直接,而不是把它們轉化爲抽象的,模糊的,相當於計算機世界結構體。無論哪種語言要求您以不同於用來描述問題的方式來思考解決方案的實施,它都會作爲OOP工具存在缺陷。 (請注意,我沒有說'無用':))
真實世界對象具有依賴於上下文的各種角色。這些角色可以有狀態。因此,我同意缺乏多重繼承是簡化建模的障礙。 Objective-C協議,Java接口以及聲稱你應該更喜歡組合來繼承都是否認OOP優勢的基本部分。
我看不到你的觀點:obj-c協議和java接口使得建模大型和動態系統比多重繼承更容易。實際上多重繼承可能會誤導人們把太多的東西放在一個類中,而不是使用好的模式。我確信這是C#作爲基於C的OOP語言的最新版本而設計時遺漏多重繼承的原因。 – vikingosegundo
意見分歧...特別是關於「簡單」。 :)我的觀點是,如果您重視問題空間元素和解決方案空間元素之間的一致性,那麼僅僅作爲實現便利而存在的任何語言構造都會干擾該目標。 (如果這個目標對你的開發並不重要,那麼顯然你可能不會在意)。至於把太多的東西放到一個單獨的類中,我從來沒有見過用C++完成的事情, iOS視圖控制器與他們的長實施協議列表。 –
一長串協議方法並不表示任何問題。只要他們屬於同一個任務。也只有2個tableviews的數據源和委託方法必須實現。其餘的都是可以用於任何類型定製的鉤子。只要你的控制器不從UITableView控制器繼承,這就允許你將tableView作爲一個黑盒子來處理,而繼承總是白色的拳擊:你需要知道父類的某些內部結構(就像UITableViewContoller:它有一個tableView連接到它) – vikingosegundo
你可以在google中找到答案 –