Reputation: 13947
I have two classes
A.h
@interface A : UIView
@end
A.m
@implementation A
-(id)initWithCoder:(NSCoder*)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
[self initialize];
}
return self;
}
-(void)initialize{
[[NSNotificationCenter defaultCenter]addObserver:self name:keyboardnotificationwillshow];
}
@end
B.h
@interface B : A
@end
@implementation B
-(id)initWithCoder:(NSCoder*)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
[self initialize];
}
return self;
}
-(void)initialize{
//do some stuff to prepare B
[self setBackgroundColor:[UIColor redColor]];
}
@end
now i put B in the interface builder and wait for it to load via story board but!
now comes my question :
in all languages i've used to write code, the implementations i've written above would result in the following
now i've run this through debug and this is the actual result: create B, initWithCoderB -> initWithCoderA ->initializeB ->return B
my actual question is :WHY did it skip initializeA ?
Log output
2014-05-19 14:45:23.270 MyApp[17780:60b] B initWithCoder
2014-05-19 14:45:23.270 MyApp[17780:60b] A initWithCoder
2014-05-19 14:45:23.272 MyApp[17780:60b] B initialize
2014-05-19 14:45:23.278 MyApp[17780:60b] B initialize
If i rename initializeA to initStuffA this is the log output
2014-05-19 14:48:41.700 MyApp[17795:60b] B initWithCoder
2014-05-19 14:48:41.701 MyApp[17795:60b] A initWithCoder
2014-05-19 14:48:41.701 MyApp[17795:60b] A initialize
2014-05-19 14:48:41.702 MyApp[17795:60b] B initialize
so why can't i have 2 methods with the same name as private, without them overriding eachother? because they are private, i cannot call super on them
Upvotes: 2
Views: 192
Reputation: 1380
What exactly do you want to achieve here?
If you want an instance of interface B to go through the initWithCoder
of interface A, then you have no need to overwrite it in interface B. Simply make initialize
a public method and call:
- (void)initialize
{
[super initialize];
//Any further initialization here
}
Currently, interface B has no idea that it's super class also implements a method called initialize
as it is a private method.
If your initWithCoder:
method in interface A calls your initialize
method and it is a public method, then when you create an instance of interface B, it will go through the initWithCoder:
of interface A, then through to the initialize
of interface B which should then have a call to [super initialize];
to ensure any code in interface A's initialize
method is executed.
EDIT 1:
Ok, so interface B inherits from interface A.
By default (ie, with a blank implementation), an instance of interface B will act exactly the same as interface A as all methods will default through to their implementation in interface A.
Interface B, being a child of interface A, has the opportunity to override any methods or properties made publicly available by interface A.
To make them publicly available, declare them in the .h
file.
If you had a method, eg updateView
in interface A's .h
file, interface B's implementation then has the opportunity to override it. If you wanted interface B to perform the actions in both itself and interface A, you would need to call up the inheritance tree using the super
keyword. For example, having something like the following in the implementation of interface B (the child):
- (void)updateView
{
[super updateView]; //This calls any code written in interface A's updateView method
//Add your own code here
}
This shows your subclass performing inheritance as it gains access to the updateView
method created by interface A.
Interface B, as it is a child of interface A, will fill in any empty methods with the implementation from its parent class. In your example, you implemented initWithCoder:
in both interfaces. This is unnecessary, and causes overwriting complications. By leaving out the declaration of initWithCoder:
in interface B, it will use the implementation of it from interface A, its parent class, which calls to initialize
. You simply have to remember to call to super every time you override a method implementation and wish to perform both your own code and that of the parent class.
Hopefully this clears up some of your confusions about inheritance within Objective-C.
Upvotes: 2
Reputation: 13713
Since you override the initialize method in class B and you are creating an instance of class B when the initialize method is called it will point to the deepest implementation in the inheritance hierarchy (which in your case is the initialize method of class B)
Upvotes: 3