Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

darkandlong

macrumors member
Original poster
Jun 19, 2008
64
212
Uk
Is there any way I can make a classes methods accessible ONLY to subclasses of that class?

I understand how to use Class Extensions to achieve simulated private methods and properties, but is there any way to simulate protected methods and properties?

At the moment I am forces to make internal methods and properties public so that subclasses have access to them, but what is my alternative?
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
Perhaps an arrangement like this.

myclass.h
Code:
@interface MyClass : NSObject {
   // ivars
}
// public methods
@end

myclass_protected.h
Code:
#import "myclass.h"
@interface MyClass(MyClass_protected)
// protected methods
@end

myclass.m
Code:
#import "myclass_protected.h"

@interface MyClass(MyClass_private)
// private methods
@end

@implementation MyClass
// ...
@end

mysubclass.h
Code:
#import "myclass_protected.h"
@interface MySubclass : MyClass
@end

myotherclass.h
Code:
#import "myclass.h"
@interface MyOtherClass : NSObject {
   MyClass *myClass_;
}
@end
 

darkandlong

macrumors member
Original poster
Jun 19, 2008
64
212
Uk
Hi jiminaus,

Thanks for replying. So the onus is on the subclass to opt in by importing the protected header? That's very different from what I'm used to, but I suppose it would achieve the same ends.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
Hi jiminaus,

Thanks for replying. So the onus is on the subclass to opt in by importing the protected header? That's very different from what I'm used to, but I suppose it would achieve the same ends.

Yes, that would be the pattern, that subclasses import the protected header so they have the declarations of the protected methods. Where as other classes would import the non-protected header so they have only the declarations of the public methods.

Mind you, none of this would actually stop another classes from invoked a protected method, or even a private method. Objective-C simply doesn't have this protection for methods.

Personally, I would abandon the idea of protected methods when coding in Objective-C. Design your classes so that their subclasses just use the public API.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,739
8,410
A sea of green
Personally, I would abandon the idea of protected methods when coding in Objective-C. Design your classes so that their subclasses just use the public API.

I mostly agree with this. However, it depends on the public API.

If the intended public API is small, say a half-dozen methods and properties in total, and the subclassing API is large, say two-dozen additional methods, then I think it's worthwhile to use the class extension mechanism, or something similar. It's not done to rigorously enforce access visibility, it's only done to manage the size of the visible public API.

Then there are classes that are the opposite of this, like say NSString. Zillions of methods and extensions in the public API, but only a handful of primitives that a subclass should implement.

So if the relative size of the public API is smaller than the size of the subclassing API, say by a factor of 3 or more, I'd go with a class extension mechanism. Otherwise, just use a single public API.
 

darkandlong

macrumors member
Original poster
Jun 19, 2008
64
212
Uk
Thanks. I think I'm just struggling to wrap my head round the idea of no private or protected classes. I'm so used to hiding internals away. It seems like I end up with lots of long public methods with duplicate functionality where I'm used to snapping off functionality in sharable utility and helper methods.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,739
8,410
A sea of green
It seems like I end up with lots of long public methods with duplicate functionality where I'm used to snapping off functionality in sharable utility and helper methods.

That just seems silly. A well-factored method is well-factored whether the sub-methods are public or not. Factoring is not the same as visibility.

Exactly what is your concern? That some bozo can override one of the sub-methods and cause another method to break? Sad to say, but protected visibility won't prevent that.

Or is it that you think you have to declare every method in the public @interface, in order to define it in a well-factored @implementation? Because that's not true. You can define methods in the @implementation that are not declared in the @interface.

I think you should post an example that illustrates the problem you want to solve.

You might want to review the Objective-C reference doc, too:
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/
 

darkandlong

macrumors member
Original poster
Jun 19, 2008
64
212
Uk
I know I can hide methods from a public API using class extensions, but I am specifically talking about protected methods. Methods meant for use only by subclasses. The reason I mentioned long methods is that in order to keep the API as simple as possible, I don't want lots of secondary methods that no-one but subclasses would be interested in cluttering it up. Hense longer methods that include this secondary functionality rather than factoring it out into protected methods.

My concern usually isn't that someone will can override them, but more that they don't belong in the public API.

I'm used to programming in Actionscript which supports protected methods and truely private methods and allows classes to be more of a black box than Objective C allows. I am aware this is just one of the many differences between the languages, but it is so far the one I am finding hardest to adapt to as it feels like a big deal.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
I'm used to programming in Actionscript which supports protected methods and truely private methods and allows classes to be more of a black box than Objective C allows. I am aware this is just one of the many differences between the languages, but it is so far the one I am finding hardest to adapt to as it feels like a big deal.

Keep this instinct, because it is a good one generally. But come to peace by accepting that you just can't do it in Objective-C.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.