0

I have a subclass of NSMutableArray which in fact deals with a certain type of data i.e. say Employee. The problem is I don't like the inherented names of addObject insertObject and etc. and want to change them to something like addEmployee insertEmployee.

How should I deal with this?

L__
  • 866
  • 1
  • 9
  • 15
  • 1
    Just to make sure: You _do_ know that `NSMutableArray` is not a normal class, but rather a class cluster's public abstract class, right? Thus it needs to be [handled](http://www.mikeash.com/pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html) [differently](http://blog.securemacprogramming.com/2010/05/on-type-safety-and-making-it-harder-to-write-buggy-code/). – Regexident Apr 25 '13 at 22:08
  • Yeah I know of that; so indeed the current implementation is already using composition – L__ Apr 25 '13 at 22:28

3 Answers3

3

If you are not going to inherit the methods of the superclass then you should not use that superclass!

When you inherit it is a 'is a' relationship between the sub and super classes. "Employer is a NSMutableArray" - no, that is not true and thus don't make Employer a subclass of NSMutableArray. Additionally, in the future you might use a dictionary to store employees (like mapping 'name' -> 'employee') and then having the representation being inherited as an array simply won't work.

@interface Employer : NSObject {
  NSMutableArray *employees;
}

- (void) addEmployee: (Employee *) employee;
@end

Like such. Now addObject: isn't workable on instances of Employee; only addEmployee: works. Additionally, you'll only want to specialize methods like filteredArrayWithPredicate: eventually - so it won't be an advantage to inherit them.

GoZoner
  • 67,920
  • 20
  • 95
  • 145
  • If there are no better answers then I'll accept yours. The downside is that if I override `NSMutableArray` then I can get methods like `filteredArray..` for free just for overriding the few methods; but in this way I have to duplicate lots of methods..duh.. – L__ Apr 25 '13 at 22:08
  • 1
    Edited with explanation on why inheritance if wrong; even if `__attribute__((unavailable,...)` is easy now. – GoZoner Apr 25 '13 at 22:11
  • Note that if you were really hell-bent on exposing all of NSArray's interface on the Employee object, you don't necessarily have to manually reimplement all of NSArray's methods, you can override Employee's `forwardInvocation:` to pass on any array methods to the NSArray ivar. – iluvcapra Apr 26 '13 at 00:08
0

You add a method addEmployee: and in that call addObject:. Similar for insertObject:

Krumelur
  • 32,180
  • 27
  • 124
  • 263
  • But that will still expose `addObject` to the client; and I'd like not to have that to happen :/ – L__ Apr 25 '13 at 22:01
  • Right and you cannot avoid that using subclassing. You should have a look at the adapter pattern (https://en.wikipedia.org/wiki/Adapter_pattern). – Krumelur Apr 26 '13 at 08:01
0

You can inherit NSMutableArray and add methods like -addEmployee: then add this in your .h file:

- (void)addObject:(id)anObject __attribute__((unavailable("Use -addEmployee:")));

This is a clang extension which will cause a complier error.

References:

How do I flag a function as being deprecated in an iPhone Objective C header file?

http://clang.llvm.org/docs/LanguageExtensions.html#messages-on-deprecated-and-unavailable-attributes

Community
  • 1
  • 1
leafduo
  • 144
  • 1
  • 5
  • That's a brilliant way that I've not thought of! I'll immediately give it a go – L__ Apr 25 '13 at 22:11
  • 1
    Oh, thats not clean, I think. inheritance adds one badness point, overriding a method another :) – Anders Lindén Apr 25 '13 at 22:14
  • 1
    Ineritance from an array class adds another thousand :) – Anders Lindén Apr 25 '13 at 22:16
  • I don't think inheritance is that bad, and I'm not overriding anything. I just tell the outside world some methods are not available. – leafduo Apr 25 '13 at 22:18
  • 1
    I clarify, overriding every method adds responsibility that you did not have if you did not inherit. It adds code. Code will contain dead ends that you hope for will not get called. – Anders Lindén Apr 25 '13 at 22:18
  • 1
    Methods that will never get called as such are not very clean. – Anders Lindén Apr 25 '13 at 22:21
  • It seems a good and short answer to the problem but it does't work as well as I expected though...From my experiment I still get completion of `NSArray` methods. – L__ Apr 25 '13 at 22:25
  • Yes, you are actually pinpointing one ugly aspect there, yulan6248! – Anders Lindén Apr 25 '13 at 22:26
  • @yulan6248 When I call `-addObject:`, I get a complier error, saying `'addObject:' is unavailable: Use -addEmployee:`. What's your expectation? – leafduo Apr 25 '13 at 22:35
  • @Anders Lindén Which method never get called? – leafduo Apr 25 '13 at 22:36
  • Methods that you "turn off" by overriding them with "pukers" will hopefully never be called. – Anders Lindén Apr 25 '13 at 22:38
  • @leafduo I was hoping that the IDE is smart enough to understand these methods shouldn't be seen from the outside (like autocompletion popup etc.). But I was hoping too much – L__ Apr 25 '13 at 22:40
  • Its bad practice anyway, would be cool if the IDE could stop showing that methods for sure. – Anders Lindén Apr 25 '13 at 22:42
  • @yulan6248 IDE (Xcode) actually understands it, `-addObject:` will popup but with a red line through it. – leafduo Apr 25 '13 at 22:43
  • 1
    @leafduo I was using AppCode and that might be the reason; but just as Anders has said, it's maybe the best practice to adhere to strict super/subclass relationships – L__ Apr 25 '13 at 22:49