Reputation: 7384
I have a C++ background, and I'm a little confused about how to translate a particular concept into Objective-C.
C++ allows multiple inheritance, so you see a lot of designs like:
class Z {
virtual void doSomething() {...}
};
class A : V, W, Z {
void doSomething() {...}
};
class B : X, Y, Z {
void doSomething() {...}
};
void callDoSomething(Z* inheritsFromZ) {
inheritsFromZ->doSomething();
}
A *a = new A();
callDoSomething(a);
The key thing about this is that you can be agnostic about what particular type the object at the pointer inheritsFromZ has -- all you care about is that that object actually implements the interface defined by class Z.
Objective-C does not allow multiple inheritance, but it does allow a class to use multiple protocols. The problem for me is that I don't know how to declare a variable or selector parameter as "something that uses protocol Z" the way C++ lets you use Z*.
Eg, here's a bit of quick Objective-C pseudocode:
@protocol A
- (void)selectorB;
@end
@interface C : NSObject <A>
@end
@implementation C
- (void)misc {
E* e = [[E alloc] initWithCallableA:self];
}
- (void)selectorB {
NSLog(@"In C");
}
@end
@interface D : NSObject <A>
@end
@implementation D
- (void)misc {
E* e = [[E alloc] initWithCallableA:self];
}
- (void)selectorB {
NSLog(@"In D");
}
@end
@interface E : NSObject
@end
@implementation E
- (id)initWithCallableA:(id)implementsA {
self = [super init];
if (self) {
[implementsA selectorB]; // compiler doesn't like this
}
return self;
}
@end
There are lots of questions on SO about how to call a selector implemented by a particular class when all you have is a more generic pointer to an object of that class; eg, you have access to your presentingViewController and you know its class type is M*, but Xcode complains that it is just a UIViewController*... that's a situation where you can just cast the variable. (Not pretty, but it works.)
The difference here is when a pointer could refer to more than one class type, and all you know is that whichever class it is implements a particular protocol.
Upvotes: 0
Views: 576
Reputation: 16660
[implementsA selectorB]; // compiler doesn't like this
This is not, because the compiler does not have a typing on the protocol as you think in your answer. See Chuck's comment.
Probably you simply forgot to import the protocol.
Anyway it is the better approach to add the protocol to the type.
Upvotes: 3
Reputation: 7384
As I was writing this question up, I answered my own question, at least somewhat. It looks like the syntax is:
(id <A>)
instead of the place where I was temporarily using
(id)
See Here
Upvotes: 2