Re: How to force a message to a overriding method from within an init method
Re: How to force a message to a overriding method from within an init method
- Subject: Re: How to force a message to a overriding method from within an init method
- From: Graham Cox <email@hidden>
- Date: Thu, 12 Feb 2009 13:23:38 +1100
On 12 Feb 2009, at 12:31 pm, João Varela wrote:
Hi all
I am porting most of my C++ code into Objective C and at the moment
I have this problem:
In C++ to force a constructor to call a overriding method of a
subclass I used pure virtual functions defined in an abstract
(super) class.
An example:
class Foo
{
Foo();
virtual read( x, y ) = 0; // pure virtual
};
class Bar : public Foo
{
Bar();
virtual Read( x, y ); // implemented in the subclass
};
// Foo constructor
Foo::Foo()
{
Read( x, y ); // <-- this calls Bar::Read and not Foo::Read
// because the latter is pure virtual
}
I know that the closest thing to a pure virtual function in
Objective C is a formal protocol. My question is: can you implement
such a behavior in objective C with a formal protocol?
Related to this, what method gets called inside the init method of
the superclass: a) the superclass method? or b) the overriding
method if there is one?
Although this is not strict Cocoa code, I think this is the best
place to ask this kind of question. Sorry for the mild "OT-ness" of
my question.
TIA
JV
Objective-C doesn't have constructors like C++. Instead there is a
convention that after allocating the object you call its designated
initializer (typically a method called 'init'). There is nothing
special about the init method in terms of how it is run - it's called
like any other method and never automatically like C++ constructors
are. There is a convention that init must call super's designated
initializer and return self, but otherwise it can do anything that any
other method can do, including calling another method of self or super.
If self implements the method, and overrides a method of super, it
will be called. You don't need to "force" it to call the method, since
you have to explicitly call it using self, e.g. [self ReadWithX: y:];
'self' is always explicit and never implicit like 'this' is in C++.
Even if the method call is implemented by super, it will call the
method of the actual class being inited.
Formal protocols are useful for defining what an object must
implement, and so in some ways are similar to defining a class using
pure virtual methods in C++, but they only force the object that
adopts the protocol to implement the method. They do not force it to
be called (and neither is that the case in C++).
The code example you cite above will translate directly to Objective-C
without a formal protocol being strictly necessary, but if you wanted
to do it that way, you could do:
@protocol Read
@optional
- (void) ReadWithX:(int) x y:(int) y;
@end
@class foo : NSObject <Read>
// foo is required to implement the mandatory methods defined by
protocol <Read> and inherits the methods of NSObject
@end
@class bar : foo
@end
@implementation foo
- (id) init
{
self = [super init];
if( self )
[self readWithX:1 y:0];
return self;
}
@end
@implementation bar
- (void) readWithX:(int) x y:(int) y
{
// this is called when an instance of bar is initialised
}
@end
Note that the read method here is @optional, meaning that it's not
strictly required by the protocol. This is an Objective-C 2.0 feature,
and allows foo not to have to implement it. The default is @required
which is more like a pure virtual function, in that it has to be
implemented, but in that case foo would have to have an implementation
of it as well, even if it were just an empty stub. There is no exact
equivalent of a pure virtual, which allows foo to treat it as
@optional, but a subclass as @required.
In the above example, if an instance of foo were created, you would
get a runtime error when it tried to call readWithX:y: on itself,
because the method doesn't exist. The same problem would occur in C++
trying to invoke a pure virtual method that didn't exist.
--Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden