Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I properly override a class method in an Objective-C in a subclass?

In the second chapter of his iOS Programming book, Joe Conway describes using 'self' in class methods in the event of subclassing. I understand this concept and have a question about the issue of subclassing.

Background: We created a Possession class whose class method +randomPossession looks like this:

+(id)randomPossession
{
NSArray *randomAdjectiveList = [NSArray arrayWithObjects:@"Fluffy", @"Rusty", @"Shiny", nil];
NSArray *randomNounList = [NSArray arrayWithObjects:@"Bear", @"Spork", @"Mac", nil];

unsigned long adjectiveIndex = rand() % [randomAdjectiveList count];
unsigned long nounIndex = rand() % [randomNounList count];

NSString *randomName = [NSString stringWithFormat:@"%@ %@", [randomAdjectiveList objectAtIndex:adjectiveIndex], [randomNounList objectAtIndex:nounIndex]];

int randomValue = rand() % 100;

NSString *randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c%c", 
                                '0' + rand() % 10, 
                                'A' + rand() % 10, 
                                '0' + rand() % 10, 
                                'A' + rand() % 10,
                                '0' + rand() % 10];

Possession *newPossession = [[self alloc] initWithPossessionName:randomName valueInDollars:randomValue serialNumber:randomSerialNumber];

return [newPossession autorelease];
}

I am aware that the return value should really be of type id such that id newPossession = ...

I subclassed Possession and created a class called BallGlove that included a new iVar, brandName, an NSString *

I overrode the +randomPossession in BallGlove as follows:

+(id)randomPossession
{
BallGlove *myGlove = [super randomPossession];

NSArray *brandNames = [NSArray arrayWithObjects:@"Rawlings", @"Mizuno", @"Wilson", nil];

unsigned long randomNameIndex = rand() % [brandNames count];

[myGlove setBrandName:[brandNames objectAtIndex:randomNameIndex]];

NSLog(@"myGlove is of type class: %@", [self class]);

return myGlove;
}

My question is this: Is the manner in which I overrode this class method appropriate and acceptable by the community (i.e. parallel the -init format by capturing the super implementation in a variable, manipulate the variable accordingly and then return it? My output shows that the object returned is an instance of BallGlove however, I was interested in the acceptable implementation. Thanks in advance.

like image 877
Brian Palma Avatar asked Dec 28 '11 17:12

Brian Palma


People also ask

Does Objective C support method overriding?

Objective-C lacks private methods or java-esque final methods. This means that it is possible for a subclass to (accidentally) override some of the internals of a superclass.

What is method overriding give an example?

Method overriding is a feature that allows a subclass, or a child class, to specifically implement a method already given in one of its super-classes, or parent classes, in any object-oriented programming language. Thus, the process of redefining a parent class's method in a subclass is known as method overriding.

Can you override an instance method?

An instance method that is defined in a subclass is said to override an inherited instance method that would otherwise be accessible in the subclass if the two methods have the same signature.


2 Answers

Yep, that's a perfectly sensible way to do it. There's nothing particularly different between class methods and normal methods — just that one is performed by a class and the other is performed by an instance.

like image 84
Chuck Avatar answered Nov 05 '22 19:11

Chuck


The moment you override a class method you can decide to implement it with the help of the super implementation or without it. It is totally up to you. Overiding init is a completely differeent story, not only because it is an instance method but because it has a convention/contract associated with it. Keep in mind that for instance methods the Liskov Subtitution principle should not be violated.

Your overrided of the class method is perfectly fine, although I would consider overiding class methods a design smell. Although it's very well possible in Objective-C, it's not in other languages and that for a very good reason. Polymorphism as a concept is better bound to instances that can be used as substitutes for each other, whereas using class methods breaks the concept (i.e. no real subtitution). It's clever, but not necessesarily intuitive and flexible.

like image 45
Johannes Rudolph Avatar answered Nov 05 '22 21:11

Johannes Rudolph