Search code examples
objective-cobjective-c-category

Can categories be inherited?


Say I have a class Parent and the child is Child1 and Child2.

I declare Parent+ParentCategory and then I declare a method:

-(void) Redraw;

Later I want the Redraw function of Child1 to be different than the Redraw function of Child2.

Can I declare Child1+Child1Category and then override the

-(void) Redraw

Can -(void)Redraw of Child1 call the function in the parent category?

Can that be done?

What would be good approach?

I know classes can inherit each other. I know protocol can extend each other. I wonder why category doesn't?


Solution

  • I do not agree with the given answers:

    A.: It is not true, that category's methods win against class' method. This is an implementation detail, but the behavior is not defined.

    If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime.

    B. But this does not matter. You neither define a method in a category that is defined in the class nor define a method in two clashing categories. The cit. simply does not apply to your case. It applies to something like this:

    @interface A : NSObject
    - (void)doSomething;
    @end
    @implementation A
    - (void)doSomething {}
    @end
    
    @interface A (Addition)
    - (void)doSomething;
    @end
    @implementation A (Addition)
    - (void)doSomething {}
    @end
    

    If I understand you correct, you do not want to do this. You want something like that:

    Base level:

    @interface A : NSObject
    @end
    @implementation A
    @end
    
    @interface A (Addition)
    - (void)doSomething;
    @end
    @implementation A (Addition)
    - (void)doSomething {}
    @end
    

    This does not break the rule, because there is no method in the category, which is in the class.

    Subclass level:

    @interface B : A
    @end
    @implementation B
    @end
    
    @interface B (Addition)
    - (void)doSomething;
    @end
    @implementation B (Addition)
    - (void)doSomething {}
    @end
    
    1. There is no clash on the level of B for the same reason as there is no clash on the level of A.

    2. Somebody might say, that there is a clash, because B inherits -doSomething from A. But this is no clash, because in this case a priority rule applies: Subclasses overwrite methods.

    You can do that.

    Edit:

    You can check the problem simply by adding the method to the class. Would that compile? In the clashing case, it wouldn't. In your case, it would.