Subclasses and Protected Methods

Discussion in 'iOS Programming' started by darkandlong, Sep 20, 2011.

  1. darkandlong macrumors member

    darkandlong

    Joined:
    Jun 19, 2008
    Location:
    Uk
    #1
    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?
     
  2. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #2
    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
    
     
  3. darkandlong thread starter macrumors member

    darkandlong

    Joined:
    Jun 19, 2008
    Location:
    Uk
    #3
    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.
     
  4. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #4
    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.
     
  5. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #5
    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.
     
  6. darkandlong thread starter macrumors member

    darkandlong

    Joined:
    Jun 19, 2008
    Location:
    Uk
    #6
    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.
     
  7. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #7
    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/
     
  8. darkandlong thread starter macrumors member

    darkandlong

    Joined:
    Jun 19, 2008
    Location:
    Uk
    #8
    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.
     
  9. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #9
    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.
     

Share This Page