2013-02-14 7 views
5

In Ziel-c?Was sind die Vor- und Nachteile der Verwendung von Protocol vs Vererbung?

Ich hatte eine Klasse gemacht und dann entschied ich, dass ich eine andere Klasse möchte, die wie die erste Klasse ist. Sollte ich das Protokoll verwenden und sicherstellen, dass beide Klassen dieses Protokoll unterstützen, oder sollte ich eine Elternklasse erstellen und entscheiden, dass die 2 Klassen von dieser Klasse erben?

Hinweis:

Die Klassen sind: Business, Katalog, AddressAnnotation (derzeit funktioniert nur nur auf Geschäftsreise) und AddressAnnotationView (derzeit funktioniert nur auf Business-only). Ich möchte, dass das Gleiche am Katalog funktioniert. Es gibt auch BGGoogleMapCacheForAllAnnotations, die verwaltet werden, wenn die Annotationen zusammengelegt werden (die nun AddressAnnotation für Catalog und Business verarbeiten können. Außerdem gibt es BGGoogleMap View Controller, den ich in eine Elternklasse umwandeln möchte.

+0

Was ist die erste Klasse und was ist die zweite Klasse? Wie viel haben sie gemeinsam? Diese Frage wäre besser, wenn nach einem oder mehreren spezifischen Szenarien gefragt würde. Ich möchte nicht schließen, sondern darauf hinweisen, dass die Frage etwas zu weit gefasst ist, um leicht beantwortet zu werden. – paulmelnikow

Antwort

7

Wenn Sie ein Protokoll verwenden, müssen Sie Methoden definieren, die von beiden Klassen gemeinsam verwendet werden. Protokolle sind in der Regel bestimmten Mustern vorbehalten, z. B. dem Delegationsmuster, um Sicherheit hinzuzufügen und es Ihnen schwerer zu machen, einen Fehler zu begehen, oder wenn mehrere bereits in einer Klassenhierarchie eingebettete Klassen gemeinsame Methoden verwenden und diese Freigabe dokumentiert werden muss irgendwie. Wenn eine Klasse als eine spezialisiertere Version einer anderen dargestellt werden kann, sollten Sie erben.

Zum Beispiel sagen Sie, Sie haben eine Vehicle Klasse in Ihrem Spiel, die weiß, wie man alle möglichen Sachen macht, wie sich bewegen. Wenn Sie eine Klasse Car erstellen möchten, würden Sie wahrscheinlich die Klasse Vehicle ableiten, sodass Sie alle Methodenimplementierungen erben können. entweder um sie zu nutzen, oder implementieren Sie Ihre eigene Version der Methoden, wahrscheinlich Durchführung einer bestimmten Aufgabe für die Unterklasse vor dem Aufruf der Superklasse-Implementierung. Subclassing ist, wenn Sie die Eigenschaften und Verhaltensweisen Ihrer Oberklasse erben wollen, während Sie sie in irgendeiner Weise modifizieren. Dies gilt insbesondere dann, wenn der Klasse zusätzliche Daten hinzugefügt werden müssen, z. B. Instanzvariablen, da dies mit Kategorien nicht möglich ist (obwohl Sie dies mit einer Class Extension, oft als eine Art private Schnittstelle angesehen werden können). Im Allgemeinen haben Unterklassen mehr spezialisierte Zwecke als ihre Oberklassen.

Protokolle sind nur das, Protokolle. Sie sind da, um Sie daran zu hindern, etwas zu vermasseln oder zu vergessen, und stellen sicher, dass jedes Objekt das tut, was es soll, und löst Compiler-Warnungen aus, wenn Klassen sich nicht so verhalten, wie sie es sollten. Dies ist wichtig für Muster wie die Delegierung, da nur so sichergestellt werden kann, dass der Delegierte die Methoden implementiert, die Sie benötigen, um die Kapselung zu unterbrechen und zu wissen, um welchen Objekttyp es sich bei Ihrem Delegaten handelt. Schauen Sie sich zum Beispiel den folgenden Code aus einem meiner Projekte an.

//SGSprite.h 
@protocol SGSpriteDelegate 
    - (BOOL) animation:(int)animationIndex willCompleteFrameNumber:(int)frame forSprite:(id)sender; 
@end 

@interface SGSprite : NSObject 
@property (nonatomic, assign) id<SGSpriteDelegate> delegate; 
@end 

//SGViewController.h 
@interface SGViewController : UIViewController <SGSpriteDelegate> 
    //...dreadfully boring stuff 
@end 

Viele Klassen nutzen meine SGSprite Klasse für strukturierte 2D-Quads machen. Manchmal müssen sie wissen, wann ein Sprite einen bestimmten Animationsrahmen erreicht, also müssen die Instanzen eine Methode für ihre Delegierten aufrufen, um sie wissen zu lassen, wenn bestimmte Frames erreicht werden. Die einzige Möglichkeit sicherzustellen, dass Delegaten an Instanzen dieser Klasse diese Methode implementieren, und mich sogar warnen, wenn jemand versucht, ein Objekt zuzuordnen, das nicht als Delegat fungiert, ist durch die Verwendung eines Protokolls. Sie werden bemerken, dass, wenn ich einfach den Delegaten eine einfache id mache, ich eine Warnung bekomme, wenn ich diese Methode auf meinem Delegaten aufrufen, da seine Implementierung nicht gefunden werden kann, während, wenn ich den delegate's-Header/statisch den Delegaten, den Klasse ist nicht mehr gut gekapselt.

Sie benötigen in den meisten Fällen keine Protokolle; Sie könnten alle Methoden ohne ein Protokoll in allen Klassen definieren, die sich normalerweise an das Protokoll halten würden, und alles würde gut funktionieren. Diese gängigen Methoden sind jedoch nicht mehr dokumentiert. Neben der Sicherheit, bestimmte Klassen oder anonyme Objekte zu kennen, implementieren Sie Methoden, die Sie implementieren müssen. So können Sie schnell sagen, was was und wie tut. Protokolle sind für, wenn Sie sicherstellen müssen, dass eine Klasse oder Instanz einer Klasse eine Methode implementiert, insbesondere wenn der Typ eines Objekts nicht bekannt sein sollte, eine Klasse gekapselt zu halten.

+0

Dieser ist eine viel bessere Antwort. –

+0

@JimThio Danke. Ich habe eine Weile damit verbracht. – Metabble

+0

Eine weitere Sache, die Sie über Protokolle beachten sollten, ist, wer mit Ihrem Code arbeiten wird. Als einzelner Entwickler, der an Ihren eigenen Projekten arbeitet, hängt die Wahl des Protokolls wesentlich von Ihren eigenen Arbeitsabläufen und Präferenzen ab. Wenn Sie an einem Team arbeiten oder Ihr Projekt später an jemand anderen weitergeben möchten, könnte es ein nützliches Tool für die Organisation sein, um anderen Entwicklern bei der Arbeit mit Ihrem Code zu helfen. –

3

Es gibt a Viele Faktoren, die diese Entscheidung beeinflussen könnten: Zum einen, wenn du sagst, dass die andere Klasse "wie die erste Klasse" ist, was bedeutet das? Bedeutet das, dass sie 90% der gleichen Dinge genau gleich machen werden? Was bedeutet es, dass sie eine Menge der gleichen Dinge tun, aber jeder auf eine etwas andere Art und Weise?

Wenn viele der vorhandenen Methoden in der ersten Klasse funktionieren wird wie es ist oder mit wenig Modifikation In der zweiten Klasse können Sie mit Subclassing alles bekommen Methoden "kostenlos", so können Sie nur auf die Unterschiede konzentrieren. Wenn Sie jedoch den Großteil des Codes neu schreiben müssten und nur die beiden Klassen als ähnliche Aktionen definieren möchten, könnte ein Protokoll sinnvoller sein.

Ich habe persönlich ausschließlich Subclassing verwendet, vor allem weil ich nicht in eine Situation geraten bin, in der ein Protokoll in meinem Code Sinn machte - natürlich ist es nach einer Weile eher Gewohnheit als bewusste Entscheidung. Als ich anfing, meine App in die Verwendung von Core Data zu konvertieren, passte sich Subclassing sehr gut an, da Core Data die Möglichkeit bietet, Untereinheiten mit geerbten Attributen und Beziehungen zu erstellen. Das erleichterte das konzeptionelle Verständnis.

Wenn Sie an Ihren aktuellen Code denken, sind Sie bereits Unterklassen (NSObject, View-Controller usw.) und verwenden möglicherweise Protokolle (NSCoding, Delegaten anzeigen usw.). Überlegen Sie, wie Sie diese vorhandenen Klassen und Protokolle verwenden und wie diese Anwendungsfälle auf Ihre eigenen Klassen angewendet werden.

+0

Das war leicht zu verstehen. Schön erklärt. – viral

Verwandte Themen