Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should subclasses call the designated initializer in the immediate super class?

I've seen some sample code which has got me wondering about calling the designated initializer in the super classes. Say I have some code this:

@interface NewTableViewCell : UITableViewCell {
}
@end

@implementation NewTableViewCell 
- (id) initWithFrame: (CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Do some stuff
    }
return self;
}
@end

Note that initWithFrame is the designated initializer for UIView, not UITableView. Should this code always be calling [UITableViewCell initWithStyle:reuseIdentifier:], or does it depend on the coder's intent?

like image 942
MikeG Avatar asked Aug 11 '11 17:08

MikeG


People also ask

Do you need to call super init in Swift?

This is called class inheritance or subclassing, the class you inherit from is called the “parent” or “super” class, and the new class is called the “child” class. For safety reasons, Swift always makes you call super. init() from child classes – just in case the parent class does some important work when it's created.

Why do we need convenience initializer of the same task can be obtained with designated initializer?

A convenience initializer is a secondary initializer that must call a designated initializer of the same class. It is useful when you want to provide default values or other custom setup. A class does not require convenience initializers.

What must a convenience initializer call?

The convenience initializer must call one of the two designated initializers, because it can only call another initializer from the same class. This satisfies rules 2 and 3 from above. Both designated initializers must call the single designated initializer from the superclass, to satisfy rule 1 from above.

How many types of Initializers are there in Swift?

Swift defines two kinds of initializers for class types to help ensure all stored properties receive an initial value. Designated initializers are the primary initializers for a class.

What does it mean when a class calls the Super method?

When a class calls the super method, it means it is a subclass of a superclass. You can also see this from the extends keyword after Car. Languages vary in how they handle inheritance so I won't go into that any further. From the example I provided above, the Car class is a subclass of the React.Component superclass.

Do I need a constructor for a subclass of a superclass?

If your superclass has no constructor, you don’t need to run the super () method in the constructor of your subclass. You can also use the super method to access other methods or information in the superclass. Using my initial React Car class, you can see from my IDE I have access to all the methods and properties of my Component superclass.

What is the difference between subclass and Superclass?

subclass (child) - the class that inherits from another class. superclass (parent) - the class being inherited from. To inherit from a class, use the extends keyword. In the example below, the Car class (subclass) inherits the attributes and methods from the Vehicle class (superclass):

What does the car class inherit from the superclass of vehicle?

In the example below, the Car class (subclass) inherits the attributes and methods from the Vehicle class (superclass): Did you notice the protected modifier in Vehicle? We set the brand attribute in Vehicle to a protected access modifier.


2 Answers

When subclassing, the guideline is that the designated initializer has to call its super class' designated initializer.

Another guideline is that the subclass needs to override the superclass' designated initializer to call the new designated initializer.

If UITableViewCell follows this guideline (and it does; I tested with the help of a category), it overrides its superclass' designated initializer (UIView's initWithFrame:) to call the new designated initializer (initWithStyle:reuseIdentifier:). Therefore, if you call initWithFrame: on UITableViewCell it will call initWithStyle:reuseIdentifier:, which in turn will call initWithFrame: on super (UIView).

Therefore, it will need an additional method call but it will eventually go through initWithStyle:reuseIdentifier:.

Again, the best practice is that the designated initializer has to call the super class' designated initializer and any other initializer that isn't the designated initializer has to call the designated initializer. From "The Designated Initializer":

General principle: The designated initializer in a class must, through a message to super, invoke the designated initializer in a superclass.

Designated initializers are chained to each other through messages to super, while other initialization methods are chained to designated initializers through messages to self.

like image 183
albertamg Avatar answered Oct 06 '22 11:10

albertamg


I agree it depends on the coders attempt but the coder should always try and use the designated initializer. Think about initializers you may have written, they probably do additional work for your object to be in a usable or desired state. If you are overriding an initializer like you are doing in your example you should call the overridden initializer as well. If that was a custom init method then you would want to call the designated initializer because for UITableViewCell's that is the only way to set the reuseIdentifier publicly.

//Override initWithFrame
//Fine although it may not (should not) get called for a UITableViewCell
- (id) initWithFrame: (CGRect)frame {
    self = [super initWithFrame:frame];

//Design a custom initializer to gather parameters for supers default initializer
-(id)initWithCustomObject:(id)object style:(UI..Style)style reuseIdentifier:(NSString*)rid {
    //This should call initWithStyle:reuseIdentifier:
like image 30
Joe Avatar answered Oct 06 '22 11:10

Joe