This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Understanding #Protocols in Objective-C
Objective C protocols usage
I just started learning objective C and I do not seem to get my head around protocols very well. My understanding of Protocols in objective-C is that, you specify some method definition without actually writing the code for it. What that means is that, whoever decides to inherit my class must implement all my required methods.
My question here is that, Isn't protocols creating an extra over-head which is not really needed. If I need a method in my new class I can just implement it. Why do I need to inherit from a protocol?
Why cant I just ignore using protocols and just create methods as I need them.
Among other things, protocols are a way of letting the compiler help you avoid common errors. In this case, you can specify that one class will be calling specific methods on another class (often a delegate). The compiler will then check to make sure the other class (delegate) actually implements those methods and, if not, give you a warning message. Getting a message at compile time is preferable to crashing at runtime due to an undefined selector (method).
My question here is that, Isn't protocols creating an extra over-head which is not really needed.
there is no added overhead.
If I need a method in my new class I can just implement it. Why do I need to inherit from a protocol?
well, you can certainly declare a subclass for your common implementation, if that is an ideal path for your needs. if you try this, you will likely run into the issues i outline below.
protocols are often used because they are not actual physical types. it is an interface of methods and/or other protocols. usually, they are small and specialized. since objc does not offer multiple inheritance, protocols come in really handy for short extensions.
look at types which are complex subclasses and inherit one or more protocols; take NSString <NSCoding, NSCopying, NSMutableCopying, NSObject> as an example. knowing that objc uses single inheritance, consider how you would implement this class and 'inherit' from all those protocols - then consider the effect it would have on clients when passing those types after you have implemented this for all Foundation types. the class hierarchy and interfaces get very messy. the number of variations in many classes would explode to accommodate all those types as parameters. most people would stop before that point, and just drop type safety -- also a very bad idea. with a protocol, you can have "implements this interface" and type safety all in a simple language feature (multiple inheritance gets quite ugly quite quickly).
Related
This question already has answers here:
What is a Protocol?
(2 answers)
Closed 10 years ago.
Why would I want to use a protocol rather than create a subclass and inherit the methods..?
Please explain it to me, i'm to confused about this topic, i'm not very pleased with the explanation in the book im reading.
Where do I use protocols instead of other ways to get the methods..? if I can subclass a class and get the methods why would i want to use a protocol where i need to define the methods?
Why would I want to use a protocol rather than create a subclass and
inherit the methods..?
Protocols make it possible for unrelated classes to all implement the same interface. Instances of each of those classes can then be used by a client of the protocol. For example, UITableViewDataSource is a protocol that provides an interface by which a table can ask for data from any object that implements the protocol. The table view doesn't care what the type of the object is so long as it implements the data source interface.
Imagine how unpleasant things would be if all table data sources had to inherit from a common class! Objective-C only provides single inheritance, so you'd effectively be constrained to using only a single kind of object for your data source. With protocols, though, a data source can be a view controller, a model object, or perhaps even a remote object.
To be more specific, protocols allow a form of polymorphism. That means that a single object can take several forms: e.g. view controller, table data source, table delegate, scroll view delegate. Because Objective-C is a single-inheritance language, you only get one of those interfaces via inheritance. The rest you implement yourself, but that often makes sense because you generally adopt a given protocol in order to customize some other object's behavior anyway.
Because subclassing and protocols are two different things. Subclassing extends a class with new functionality while inheriting all previous functionality of a specific class while a protocol, when applied to a class, simply adds functionality to it and doesn't inherit anything from it; what that class is usually doesn't matter.
Protocols are most frequently used for the delegate pattern in Objective-C whereby an object can send a message to another object without caring WHAT that object is (i.e. it's class).
Often times, a delegate is declared as:
#property(nonatomic, assign) id < MyObjectDelegate > delegate;
Notice that the class of the property is id -- in essence, you don't care if the object is a car or a turtle -- all you need to know is that it is an object (id) and that it contractually subscribes to the functions you need it to. So if your delegate is type turtle, you can call [delegate myStateChanged]; or, if your delegate is a car, you can call [delegate myStateChanged]. All you need to know is that, if you send a message to it, it will accept it.
I would look up and read about the use of Objective-C delegates as I think it will really help you understand protocols better and how it's different than subclassing. I don't know if you're familiar with other, object-oriented programming languages, but if so, protocols are most similar to Interfaces in other languages.
Protocols are useful because you can implement many protocols, instead you can only extend a single class.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
In objective-c?
I had a class made and then I decided that I want another class that's like the first class. Should I use protocol and ensure that both classes support that protocol or should I create a parent class and decide that the 2 classes inherit from that one class?
Note:
The classes are: Business, Catalog, AddressAnnotation (currently works only on business only) and AddressAnnotationView (currently works only on business only). I want the same thing to work on Catalog. There is also BGGoogleMapCacheForAllAnnotations that manage when the annotations are clumped together (which now should be able to handle both AddressAnnotation for Catalog and Business. Also there is BGGoogleMap View Controller that I want to turn into a parent class.
If you use a protocol, then you have to define methods shared by both class types twice. Protocols are generally reserved for specific patterns, such as the delegation pattern, to add security and make it harder for you to make a mistake, or when several classes already embedded in a class hierarchy need to share common methods and have this sharing be documented in some way. If one class can be represented as a more specialized version of another, you should inherit.
For instance, let's say you you have a Vehicle class in your game that knows how to do all sorts of stuff, such as move around. If you wanted to make a Car class, you'd probably subclass the Vehicle class so that you could inherit all of its method implementations; either to utilize them wholesale or implement your own version of the methods, probably performing some task specific to the subclass before calling the superclass's implementation as well. Subclassing is for when you want to inherit the traits and behaviors of your superclass while modifying it in some way. This is especially true when additional data must be added to the class, such as instance variables, because you can't do that with categories (although you can with a Class Extension, often seen as a sort of private interface). Generally, subclasses have more specialized purposes than their superclasses as a result.
Protocols are just that, protocols. They're there to prevent you from screwing up or forgetting something, and ensure that every object does what it's supposed to, triggering compiler warnings when classes aren't behaving like they are supposed to. This is important for patterns such as delegation, since it's the only way to ensure that the delegate implements the methods you need beyond breaking encapsulation and knowing what type of object your delegate is. For instance, look at the the code below, from one of my projects.
//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
Many classes utilize my SGSprite class for rendering textured 2D quads. Sometimes, they need to know when a sprite reaches a certain frame of animation, so SGSprite instances need to call a method on their delegates to let them know when certain frames are reached. The only way to ensure that delegates to instances of this class implement this method, and, indeed, warn me if someone tries to assign an object that doesn't as a delegate, is through the use of a protocol. You'll notice that if I simply make the delegate a plain id I'll get a warning whenever I call this method on my delegate, since its implementation cannot be found, while if I import the delegate's header/statically type the delegate, the class is no longer well encapsulated.
You don't technically need protocols in most cases; you could define all of the methods without a protocol in all of the classes that would ordinarily adhere to said protocol, and everything would work fine. However, these common methods are no longer documented. Thus, beyond the security of knowing certain classes or anonymous objects implement methods you need them to implement, you can also quickly tell what does what and how. Protocols are for when you need to ensure that a class, or instance of a class, implements some method, especially when an object's type shouldn't be known to keep a class encapsulated.
There are a lot of factors that could influence that decision. For one, when you say that the other class is "like the first class", what does that mean? Does it mean that they'll do 90% of the same things in exactly the same way? Does it mean that they'll do a lot of the same kinds of things, but each in a slightly different way?
If many of the existing methods in the first class will work as-is or with little modification in the second class, subclassing lets you get all of those methods "for free" so you can just focus on the differences. If you would need to rewrite most of the code, however, and just want to define the two classes as performing similar actions then a protocol might make more sense.
I've personally used subclassing exclusively, primarily because I haven't run into a situation where a protocol made sense to me in my code - of course, after a while it's more out of habit than conscious decision. When I began converting my app to using Core Data, subclassing fit in very nicely because Core Data offers the ability to create subentities with inherited attributes and relationships. That made it easier to grasp conceptually.
If you think about your current code, you're already subclassing (NSObject, view controllers, etc.) and possibly using protocols (NSCoding, view delegates, etc.). Think about how you use those existing classes and protocols and how those use cases would apply to your own classes.
The necessity for protocols are to abstract the methods of classes which are not hierarchically related.
The similar things also can be done with the help a class (interface) which encompasses all those methods and subclass them ? (This is not really possible due to the Multiple inheritance problem since a class has to be derived already from NSObject.ignore the NSProxy case)
What special things that protocols can do than a class?
Are protocols trying to solve only the multiple inheritance problem?
Protocols main advantage is, that they describe what a object should be able to do, without enforcing subclassing. In languages that dont have multiple inheritance such a mechanism is needed, if you want others programmers be able to use your classes. (see delegation)
For an instance Java has something similar, called interfaces.
This means a huge advantage, as it is very easy to build dynamic systems, as I can allow other developers to enhance my classes via a clearly defined protocol.
A practical example:
I am just designing a REST API and I am providing a Objective-C client library.
As my api requires information about the user, I add a protocol
#protocol VSAPIClientUser <NSObject>
-(NSString *)lastName;
-(NSString *)firstName;
-(NSString *)uuid;
#end
Anywhere I need this user information, I will have an basic id-object, that must conform to this protocol
-(void)addUserWithAttributes:(id<VSAPIClientUser>)user;
You can read this line as: "I don't care, what kind of object you provide here, as long as it knows about lastName, firstName and uuid". So I have no idea, how the rest of that object looks like — and I don't care.
As the library author I can use this safely:
NSDictionary *userAttributes = #{#"last_name" : [user lastName],
#"first_name": [user firstName],
#"uuid": [user uuid]};
BTW: I wouldn't call the absence of multi-inheritance a problem. It is just another design.
“[…] If I revisited that decision today, I might even go so far as to remove single inheritance as well. Inheritance just isn’t all that important. Encapsulation is OOP’s lasting contribution.” — Brad Cox was asked, why Objective-C doesn’t have multiple inheritance. (Masterminds of Programming: Conversations with the Creators of Major Programming Languages, p. 259)
As an alternative view....
Object-oriented programming's most basic value comes from being able to model real-world relationships directly as opposed to translating them into abstract and vaguely-equivalent computer-world constructs. Wherever a language requires you to think about the implementation of a solution in different terms than those you can use to describe your problem, it is flawed as an OOP tool. (Note that I didn't say 'useless'. :) )
Real-world objects have various roles that depend on context. Those roles can have state. Therefore, I agree that lack of multiple-inheritance is an impediment to ease of modelling. Objective-C protocols, Java interfaces, and the claim that you should prefer composition to inheritance are all denials of a fundamental part of the OOP advantage.
One of many uses of C++ abstract classes is, among their other uses, to define interfaces (to specify reusable contracts). There are however also other programming languages, such as Objective C that have a separate concept for interfaces in this sense; in Objective C, it is called protocols.
A wide use of such a construct does require a way of attaching more than one contract to an object; and if such interfaces are allowed to inherit from each another, this has to be multiple inheritance to be useful.
However, this is not the same thing as multiple inheritance between classes.
Protocols are not trying to solve the multiple inheritance problem. They are trying to separate contract specification from object (data+code) specification. They can actually do much less than a class (if you ignore the multiple inheritance aspect) and that's why they exist as a separate concept.
Implementing a protocol is generally a much less restrictive (safer) proposition to consider than inheriting from a class.
I have a base class which adds some functionality to a number of derived classes in my app.
One of these features is only used by some subclasses.
Currently I'm using a method which returns a BOOL which defaults to NO to "short-circuit" this feature. Subclasses which want the feature must override this method and return YES.
This feature is only useful if you've also overridden at least one of two other methods.
I'd prefer to use class_copyMethodList to determine if the subclass implemented either of these two methods (instead of using the method which returns a BOOL).
What barriers/roadblocks/cons to this approach should I be aware of? Is there a standard implementation of this idiom which I can use?
If I may suggest an alternative approach, have you considered using -instanceMethodForSelector on the relevant subclass instance and comparing to the result on the base class?
That method returns an IMP, which is a C function pointer to the implementation for the given selector. So if the subclass has a different implementation from the base class, it'll return a different IMP.
EDIT: as discussed in the comments below, a further alternative is to declare a formal protocol that the sub classes may implement, and to use NSObject's -conformsToProtocol: to determine whether the protocol is implemented. Since conformsToProtocol returns whether the class has declared support for the protocol (in its #interface via the angle brackets syntax), that's a lot like adding a custom BOOL method that defaults to returning NO but without the syntactic and semantic overhead of adopting your own ad hoc solution.
I have a base class which adds some functionality to a number of derived classes in my app.
This sentence should cause you to rethink your design. A base class should never do anything to derived classes. It should be ignorant of its subclasses. (Class Clusters notwithstanding. That's a separate design approach and require the superclass to be aware in the construction, making it the Factory pattern, which is fine.)
One of these features is only used by some subclasses.
This is a strong indication of a "Square/Rectangle" mistake. In OOP (forget ObjC, this is just CS theory), a square is not a rectangle. You need to ensure that your types conform to Liskov's Substitution Principle. Again, this has nothing to do with any particular language; it's true of all OOP design. It may seem very "theoretical" but it will seriously screw up your implementation if you fail LSP, and you will chase subtle bugs for much longer than you like.
The pattern you probably want here is Decorator rather than subclassing. If you have some special functionality that exists on some classes, you want to encapsulate that functionality into a separate object and attach it to subclasses where it makes sense. Another possible pattern is Strategy (which is generally implemented as a "delegate" in ObjC, which is another way of thinking about Decorator). The point is that you don't want logic in the superclass that is only applicable to some subclasses. You want to put that logic into something that only exists in the appropriate subclasses.
If all of those things fail you, then I strongly recommend a simple (BOOL) function over anything that introspects the method implementations. That way is fragile because it relies on ever-deeper implementation details. respondsToSelector: is definitely better than testing instanceMethodForSelector:.
I'm learning Objective-C, and have a C/C++ background.
In object-oriented C++, you always need to declare your method before you define (implement) it, even if it is declared in the parent class.
In procedural-style C, IIRC, you can get away with just defining a function so long as it is only called from something else in the same compilational unit (ie. the same file) that came later on in the file (well, provided you don't declare it elsewhere with "extern").
Now, in Objective-C, it appears that you only need to declare selectors in the header file if they are going to be used by something external, and that you can make up selectors in your .m file just fine, and call them within the .m file. Also, it appears that delegate methods or inherited methods are never (re)defined.
Am I on the right track? When do you need to define a selector in Objective-C?
For Objective-C methods, the general practice is to put methods you wish to expose in the #interface section of the header file so other code can include only the .h and know how to interact with your code. Order-based "lazy declaration" works just like functions in C — you don't have to declare a method prototype unless you have a dependency that can't be resolved by ordering, but you can add method prototypes inside the #implementation if needed.
So yes, you're on the right track. Don't repeat the method prototype for inherited methods — the compiler finds it in the parent's header file. Delegate methods may be defined as prototypes in a category (tacked onto a class) and implemented as desired, but the delegate does not need to provide a method prototype, since it is already defined. (It still can if it wants to for clarity, etc.)
Since you're just learning Objective-C, the rest of this answer is much more detail than you asked for. You have been warned. ;-)
When you statically type a variable (e.g. MyClass* instead of id) the compiler will warn you when you try to call a method that a class doesn't advertise that it implements, whether it does or not. If you dynamically type the variable, the compiler won't stop you from calling whatever you like, and you'll only get runtime errors if you call something that doesn't exist. As far as the language is concerned, you can call any method that a class implements without errors at runtime — there is no way to restrict who can call a method.
Personally, I think this is actually a good thing. We get so used to encapsulation and protecting our code from other code that we sometimes treat the caller as a devious miscreant rather than a trustworthy coworker or customer. I find it's quite pleasant to code with a mindset of "you do your job and I do mine" where everyone respects boundaries and takes care of their own thing. You might say that the "attitude" of Objective-C is one of community trust, rather than of strict enforcement. For example, I'm happy to help anyone who comes to my desk, but would get really annoyed if someone messed with my stuff or moved things around without asking. Well-designed code doesn't have to be paranoid or sociopathic, it just has to work well together. :-)
That said, there are many approaches for structuring your interfaces, depending on the level of granularity you want/need in exposing interfaces to users. Any methods you declare in the public header are essentially fair game for anyone to use. Hiding method declarations is a bit like locking your car or house — it probably won't keep everyone out, but (1) it "keeps honest people honest" by not tempting them with something they shouldn't be messing with, and (2) anyone who does get in will certainly know they weren't supposed to, and can't really complain of negative consequences.
Below are some conventions I use for file naming, and what goes in each file — starting from a .m file at the bottom, each file includes the one above it. (Using a strict chain of includes will prevent things like duplicate symbol warnings.) Some of these levels only apply to larger reusable components, such as Cocoa frameworks. Adapt them according to your needs, and use whatever names suit you.
MyClass.h — Public API (Application Programming Interface)
MyClass_Private.h — Company-internal SPI (System Programming Interface)
MyClass_Internal.h — Project-internal IPI (Internal Programming Interface)
MyClass.m — Implementation, generally of all API/SPI/IPI declarations
MyClass_Foo.m — Additional implementation, such as for categories
API is for everyone to use, and is publicly supported (usually in Foo.framework/Headers). SPI exposes additional functionality for internal clients of your code, but with the understanding that support may be limited and the interface is subject to change (usually in Foo.framework/PrivateHeaders). IPI consists of implementation-specific details that should never be used outside the project itself, and these headers are not included in the framework at all. Anyone who chooses to use SPI and IPI calls does so at their own risk, and usually to their detriment when changes break their code. :-)
Declaring the methods in the header file will only stop compiler warnings. Objective-C is a dynamic language, so you can call a method (send a message) to an object whether or not that method is declared externally.
Also, if you define a method in the .m file above any code that calls it (lazy declaration) then that won't generate any warnings. However the same thing applies, you can send a message to an object without it being declared.
Of course - this means that there are no private methods in Objective-C. Any method that a class implements can be called.
Personal preference. If it's a public method (i.e one used externally). declare it in the .h and define in the .m. If you want to limit it's visibility, or at least indicate that it is a private method, use categories/class extensions in the .m file. Although lots of example code uses the lazy declaration method.
Objective-C treats functions as "messages" and as such, you can send a "message" to any object - even one that doesn't explicitly state in its interface that it can accept. As a result, there are no such things as private members in Obj-C.
This can be very powerful, but is a source of confusion for new Obj-C programmers - especially those coming from C++, Java or C#. Here are the basic rules of thumb:
You should define all public methods in your #interface so that consumers know what messages you expect to handle.
You should define #private methods in your #interface to avoid compiler messages and avoid having to order the methods in your #implementation.
You should use protocols when implementing a particular convention of methods for your class.
Much of this is personal preference, however it helps to avoid annoying compiler warnings and keeps your code organized. and easy to understand.