Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating properties only visible to subclass in Objective-C

I am attempting to create an abstract class and inherit some of its properties in a subclass. If I leave the properties in the abstract class' header file, all of the properties are accessible. The problem is that the instance of the subclass can also access those properties, which is not always desirable in my case.

For instance, I have a delegate in my abstract class that sends down button presses to its sub class. I realize that this may not be the best way of structuring inheritance, so other suggestions are welcome. However, I would still like to know how my subclass can inherit some properties from its superclass without making all of those properties available in its instance. Thanks in advance!

Here is some example code below:

@interface AbstractClass : UIView

@property (nonatomic, strong) id<ButtonDelegate>buttonDelegate;

@end

…

@protocol ButtonDelegate

@required
- (void) buttonWasPressed;

@end

…

@interface SubClass() <ButtonDelegate>

- (id)init {
    self = [super init];
    if (self) {
        self.buttonDelegate = self;
    }
    return self;
}

-(void) buttonWasPressed {
    [self doSomething];
}

…

@implementation ViewController

- (void)viewDidLoad {
    SubClass *subClass = [[SubClass alloc] init];
    subClass.buttonDelegate = self; // THIS IS NOT DESIRABLE
}
like image 291
Chris Avatar asked Oct 11 '13 14:10

Chris


3 Answers

Do like UIGestureRecognizer does.

  1. All public properties and methods goes into UIGestureRecognizer.h

  2. All protected properties and methods goes into UIGestureRecognizerSubclass.h. Only import this in the *.m-files. Never include it in any public header.

  3. All private properties and methods goes into *.m-files. Use the @interface ClassName ()

Example https://gist.github.com/hfossli/8041396

like image 163
hfossli Avatar answered Oct 14 '22 16:10

hfossli


how to my subclass can inherit some properties from its superclass without making all of those properties available in its instance

What is the problem with this?

#import <Foundation/Foundation.h>

@interface Animal : NSObject
{
    @protected
    NSString *name; // default access. Only visible to subclasses.
}
@end

@implementation Animal
-(NSString*)description {
    return name;
}
@end

@interface Cow : Animal
@end

@implementation Cow

-(id)init {
    self=[super init];
    if (self){
        name   = @"cow";
    }
    return self;
}
@end

int main(int argc, char *argv[]) {
    @autoreleasepool {
        Cow *cow = [Cow new];
        NSLog(@"%@", cow); // prints the name through internal access
        // error accessing from the outside: NSLog(@"%@", cow.name);

        Animal *animal = [Animal new];
        // error accessing from the outside: NSLog(@"%@", animal.name);
    }
}

Maybe I misunderstood the question, you say

Creating properties only visible to subclass in Objective-C

and then

The problem is that the instance of the subclass can also access those properties

Which one is it?

like image 34
Jano Avatar answered Oct 14 '22 14:10

Jano


Create an empty category on top of your implementation file (.m):

@interface AbstractClass()

@property (nonatomic, strong) id<ButtonDelegate>buttonDelegate;

@end

In that way, your subclass will inherit and can access that property, but not other external classes because it's not in the header.

like image 42
Antonio MG Avatar answered Oct 14 '22 15:10

Antonio MG