 |
 |
Protocol issues with Objective-C++
|
 |
|
 |
|
Professional Poster
Join Date: Apr 2001
Location: Long Beach, CA
Status:
Offline
|
|
I'm wanting to create a super-class that will never actually be instantiated. To do this, I'm assuming this is what protocols are for. The problem I'm having is that I'm originally from the C++ camp... so to create a situation where I have several different subclasses the follow the scheme set up by this "super-class," I am declaring a pointer to this "super-class." But the compiler doesn't like this. Do I need to make an (id *)? If I do this, what's the point of creating the protocol?
|

ACSA 10.4/10.3, ACTC 10.3, ACHDS 10.3
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Feb 2001
Location: Vancouver, WA
Status:
Offline
|
|
Abstract superclasses are just fine... they're used all the time in Cocoa. There's nothing special you have to do. Just define and implement the superclass as you would any other -- if you want to make sure you or others don't try to use it as a concrete class, throw an exception when someone tries to call +alloc on it.
Subclasses only need to #import the superclass' header file. In a subclass, you can refer to instance variables of the superclass by name -- you odn't have to reference them as struct elements in a pointer to the superclass, or anything like that. Likewise, methods of the superclass can be invoked by calling them on self (which will use the subclass' implementation if it exists and the superclass' impementation otherwise) or super.
I'm having a hard time coming up with solutions more specific than that... Perhaps you could explain your problem in more detail?
|
|
|
| |
|
|
|
 |
|
 |
|
Professional Poster
Join Date: Apr 2001
Location: Long Beach, CA
Status:
Offline
|
|
the problem I was having is as follows:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
@protocol aprotocol
- (id) afunctiontobecalled;
@end
@class classfollowingprotocol : aprotocol
{
somedata;
}
@end
int main(void)
{
aprotocol *avariable;
avariable = [[classfollowingprotocol alloc] init];
return <font color = blue>0</font>;
}
</font>[/code]
This gave quite a few compile time errors. I figured out that protocols must be referenced in <brackets>. And, instead of creating the pointer as above, it would be created as (id <aprotocol> ). Then, the pointer can be to any object that adheres to that protocol. This fixed my compile errors.
|

ACSA 10.4/10.3, ACTC 10.3, ACHDS 10.3
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Feb 2001
Location: Vancouver, WA
Status:
Offline
|
|
Ah, I see. You're mixing up classes and protocols, which are quite different things.
When you want to use an object that must respond to certain method selectors, but you don't care one bit about how that object's class is implemented, use a protocol. Here's the correct form of your example:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
@protocol AProtocol
- (id) aMethodToBeCalled;
@end
@interface ClassFollowingProtocol : NSObject <AProtocol>
{
id someData;
}
- (id) aMethodToBeCalled;
@end
@implementation ClassFollowingProtocol
- (id) aMethodToBeCalled;
{
return self;
}
@end
int main(void)
{
id <AProtocol> aVariable;
aVariable = [[ClassFollowingProtocol alloc] init];
return <font color = blue>0</font>;
}
</font>[/code]
The class <font face = "courier">ClassFollowingProtocol</font> still has to inherit from some other class (unless you're wanting to create a new root class... not recommended). To declare that it conforms to <font face = "courier">AProtocol</font>, you include the protocol name in angle-brackets after the superclass name. This will cause the compiler and runtime to enforce conformance to the protocol in your implementation of the class and allow you to assign instances of it to variables whose type declaration includes <font face = "courier"><AProtocol></font>.
When you have a variable which you want to point to an object that conforms to a certain protocol, you don't have to do just <font face = "courier">id <AProtocol> foo</font>. If you want, you can be more specific and require it to be of a certain class as well. For example: <font face = "courier">NSView <AProtocol> *foo</font> requires that the object assigned to foo be of class NSView (or a subclass of NSView) and declare and implement every method in AProtocol.
By contrast, you can use subclassing if you care more about how an object you'll be using is implemented. Here's an example of an abstract superclass, a concrete subclass, and a main() that uses them:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
@interface AbstractClass : NSObject
{
id someStuff;
}
- (id)someStuff;
@end
@implementation AbstractClass
- (id)someStuff;
{
if ([self isMemberofClass:[AbstractClass class]])
[NSException raise:NSInternalInconsistencyException format:<font color = orange>@"This is an abstract class. Implement a subclass and use that instead."</font>
else
return someStuff;
}
@end
@interface ConcreteSubclass : AbstractClass
{
}
- (void)setSomeStuff  id)newStuff;
@end
@implementation ConcreteSubclass
- (void)setSomeStuff  id)newStuff;
{
[someStuff release]
someStuff = [newStuff retain];
}
@end
int main(void)
{
AbstractClass *foo;
foo = [[ConcreteSubclass alloc] init];
[foo setSomeStuff:<font color = orange>@"foo"</font>];
NSLog(<font color = orange>@"%@"</font>, [foo someStuff]);
return <font color = blue>0</font>;
}
</font>[/code]
So, that help any? You might want to consider re-reading Object-Oriented Programming and the Objective-C Language if you're still having problems.
(Warning: this code was typed in Omniweb and not tested with the compiler, so it may not be 100% accurate.)
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Feb 2001
Location: Rochester, uk
Status:
Offline
|
|
Does Objective-C not have any way to flag classes as abstract? Damn, and I was just starting to like it.
|
|
All words are lies. Including these ones.
|
| |
|
|
|
 |
|
 |
|
Professional Poster
Join Date: Apr 2001
Location: Long Beach, CA
Status:
Offline
|
|
Originally posted by sadie:
<STRONG>Does Objective-C not have any way to flag classes as abstract? Damn, and I was just starting to like it.</STRONG>
I believe that would be what protocols are intended for.
|

ACSA 10.4/10.3, ACTC 10.3, ACHDS 10.3
|
| |
|
|
|
 |
|
 |
|
Professional Poster
Join Date: Apr 2001
Location: Long Beach, CA
Status:
Offline
|
|
Originally posted by Rickster:
<STRONG>Ah, I see. You're mixing up classes and protocols, which are quite different things.
When you want to use an object that must respond to certain method selectors, but you don't care one bit about how that object's class is implemented, use a protocol. Here's the correct form of your example:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre>& amp;lt;font size=1 face=courier>
...
</font></pre><HR></BLOCKQUOTE>
The class <font face = "courier">ClassFollowingProtocol< ;/font> still has to inherit from some other class (unless you're wanting to create a new root class... not recommended). To declare that it conforms to <font face = "courier">AProtocol</font>, you include the protocol name in angle-brackets after the superclass name. This will cause the compiler and runtime to enforce conformance to the protocol in your implementation of the class and allow you to assign instances of it to variables whose type declaration includes <font face = "courier"><AProtocol>& ;lt;/font>.
When you have a variable which you want to point to an object that conforms to a certain protocol, you don't have to do just <font face = "courier">id <AProtocol> foo</font>. If you want, you can be more specific and require it to be of a certain class as well. For example: <font face = "courier">NSView <AProtocol> *foo</font> requires that the object assigned to foo be of class NSView (or a subclass of NSView) and declare and implement every method in AProtocol.
By contrast, you can use subclassing if you care more about how an object you'll be using is implemented. Here's an example of an abstract superclass, a concrete subclass, and a main() that uses them:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre>& amp;lt;font size=1 face=courier>
...
</font></pre><HR></BLOCKQUOTE>
So, that help any? You might want to consider re-reading Object-Oriented Programming and the Objective-C Language if you're still having problems.
(Warning: this code was typed in Omniweb and not tested with the compiler, so it may not be 100% accurate.)</STRONG>
Actually, your first example is how I wound up implementing it. I was more interested in being able to create different implementations of a concept as opposed to being able to create different objects with the same functionality. This way, the user can choose which "engine" to run to modify the data. In addition, it leaves room for future enhancements and possibly a plugin type structure.
|

ACSA 10.4/10.3, ACTC 10.3, ACHDS 10.3
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Feb 2001
Location: Vancouver, WA
Status:
Offline
|
|
Yeah, either way has its advantages in different scenarios. Sometimes you don't need to care about anything more than method implementations, and sometimes you want to make plugin developers' lives easier by providing them a default implementation which they can subclass.
Anyway, glad I could help. 
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Feb 2001
Location: Rochester, uk
Status:
Offline
|
|
Originally posted by Detrius:
<STRONG>
I believe that would be what protocols are intended for.</STRONG>
I thought a protocol was the equivalent of a Java interface - something that gave method signatures but not implementations, and that can be inherited multiply rather than in the strict class hierarchy.
That's not what an abstract class is supposed to be for (except in C++, which is screwy) - it's for a partial implementation which can be used as the basis for other classes that complete the implementation, but which cannot be instanciated (sp?) itself.
|
|
All words are lies. Including these ones.
|
| |
|
|
|
 |
|
 |
|
Professional Poster
Join Date: Apr 2001
Location: Long Beach, CA
Status:
Offline
|
|
Originally posted by sadie:
<STRONG>
I thought a protocol was the equivalent of a Java interface - something that gave method signatures but not implementations, and that can be inherited multiply rather than in the strict class hierarchy.
That's not what an abstract class is supposed to be for (except in C++, which is screwy) - it's for a partial implementation which can be used as the basis for other classes that complete the implementation, but which cannot be instanciated (sp?) itself.</STRONG>
Maybe taking a look at the NSObject header file will give some information into what Apple did. I noticed that it is a protocol, but it also has a base class implementation. I don't know, however, whether or not you can actually instantiate an NSObject.
|

ACSA 10.4/10.3, ACTC 10.3, ACHDS 10.3
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |
|