Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Jan 16, 2008, 04:19 AM   #1
russell.h
macrumors regular
 
Join Date: Jul 2007
Inheritance Question

So I have this Class called "LibraryItem". It basically needs to store a mutable array along with a few strings.

So I declared it like so:
Code:
@interface LibraryItem : NSMutableArray {
	NSString *itemType;
	NSString *itemPath;
}

- (id)initWithType:(NSString *)itemTypeToSet Path:(NSString *)path;
- (void)setItemType:(NSString *)newType;
- (void)setItemPath:(NSString *)newPath;
- (NSString *)getItemType;
- (NSString *)getItemPath;

@end
But when I call the "count" method the console shows:
Code:
*** -[NSArray count]: method only defined for abstract class.  Define -[LibraryItem count]!
Am I doing something wrong? Thanks,

Russell
russell.h is offline   0 Reply With Quote
Old Jan 16, 2008, 04:56 AM   #2
HexMonkey
Administrator
 
HexMonkey's Avatar
 
Join Date: Feb 2004
Location: New Zealand
NSArray and NSMutableArray are part of a class cluster so can't easily be subclassed. From the NSArray documentation:

Quote:
NSArray and NSMutableArray are part of a class cluster, so arrays are not actual instances of the NSArray or NSMutableArray classes but of one of their private subclasses. Although an array’s class is private, its interface is public, as declared by these abstract superclasses, NSArray and NSMutableArray.
More information on class clusters is available here.

From a design perspective, however, your class should contain an array, not inherit it. What you are doing is known as inheritance for implementation, which means that you're inheriting a class for implementation purposes, not because it makes logical sense. By inheriting NSMutableArray, you're basically stating that LibraryItem is an array (which logically it isn't), and you're making it significantly more difficult to change your code in the future should you decide to change the way you store the list (for example, if you were to change it to use an NSMutableSet instead then you'd have to change every class that uses LibraryItem, rather than just the LibraryItem class).

Another problem is that other classes could use LibraryItem in unexpected ways by using methods in NSMutableArray that you don't anticipate - an example of this problem is the Java API where Stack inherits Vector; this lets you, for example, remove an item from midway through the stack, which violates the rules of a stack.
HexMonkey is offline   0 Reply With Quote
Old Jan 16, 2008, 09:02 AM   #3
Eraserhead
macrumors G4
 
Eraserhead's Avatar
 
Join Date: Nov 2005
Location: UK
CoreData could be another alternative.
__________________
Actually it does make sense. Man created god, so if we exist, He exists. - obeygiant
Eraserhead is offline   0 Reply With Quote
Old Jan 16, 2008, 01:20 PM   #4
russell.h
Thread Starter
macrumors regular
 
Join Date: Jul 2007
Quote:
Originally Posted by HexMonkey View Post
From a design perspective, however, your class should contain an array, not inherit it.
Good point, that fixes it and makes more sense too. Thanks,

Russell
russell.h is offline   0 Reply With Quote
Old Jan 16, 2008, 01:47 PM   #5
iSee
macrumors 68040
 
iSee's Avatar
 
Join Date: Oct 2004
A general rule of thumb when deciding between inheritence and containment to represent the relationship between two objects is this:

Inheritence = is a
Containment (member) = has a

So, you just say/write/think the relationship and pick the one that makes sense:

1. LibraryItem is an array
2. LibraryItem has an array

So in this case, #2 is the obvious choice.

Actually, in the case of inheritance, it's better to say the relationship in a stronger way:

Every <class 1> is a <class 2>.

This will help you catch certain object model errors. (If the statement isn't true, you shouldn't try to represent the relationship as class 1 inherits from class 2.)
iSee is offline   0 Reply With Quote
Old Jun 24, 2008, 11:00 PM   #6
col.
macrumors newbie
 
Join Date: Jun 2008
But I really like sub-classing NSMutableDictionary :(

I've just come across the same problem. It had me very confused but I found this thread and it explained the situation very well so thank you.

However, I'm not so sure what I'm trying to do is a bad thing and I'd like to know if there IS a way for me to extend an NSMutableDictionary.

I'm a Java WebObjects programmer that has been subclassing NSMutableDictionary for years and have found it extremely useful. Basically I find it to be a great way to create an class and to store any instance variables I like by calling setObjectForKey. Doing this has a lot of advantages such as:
- it automatically provides key value coding
- it automatically provides serialization and de-serialization in multiple formats
- I can dynamically add properties to the object whenever I want
- etc. etc.

I'm now starting to do more and more Objective-C programming and would like to continue to subclass NSMutableDictionary when appropriate.

I'm not experienced in Objective-C yet to figure out a way around the problem mentioned above. Does anyone have any advice as too weather this can be done or not?? and if so how?

thanks
col. is offline   0 Reply With Quote
Old Jun 25, 2008, 01:55 AM   #7
Catfish_Man
macrumors 68030
 
Catfish_Man's Avatar
 
Join Date: Sep 2001
Location: Portland, OR
Send a message via AIM to Catfish_Man
Basically what you'd need to do is figure out which methods on NSMutableDictionary are its "primitive" methods (check the header file), and which ones are implemented in categories. Then have your subclass provide its own implementations of all the primitive methods, and the ones from categories should just work.
Catfish_Man is offline   0 Reply With Quote
Old Aug 26, 2008, 11:11 PM   #8
adobongkangkong
macrumors newbie
 
Join Date: Aug 2008
Subclassing NSMutableDictionary

@ col.

Hi col. this is a bit off topic but this question is for you. You said you're a WebObjects programmer and have been subclassing dictionary I just want to know how did you subclass NSMutableDictionary. I have been subclassing NSMutableDictionary but everytime I use WOXMLCoder to serialize a subclass of NSMutableDictioanry it all resulst to its immutable counter part which is NSDictionary.

e.g.: I have a class MyDictionary that extends NSMutableDictionary.
My MyDictionary has the following methods.

setUserName(String username){
this.setObjectForKey(username,"USERNAME");
}

userName(){
if(this.containsKey("USERNAME")){
return (String)this.objectForKey("USERNAME");
}else{
return new String();
}
}

And when I serialized MyDictionary object using WOXMlCoder the result is this.

<ROOT type="com.webobjects.foundation.NSDictionary" objectID="1">
<USERNAME type="java.lang.String" objectID="2">myusername</USERNAME>
</ROOT>

Notice that the type of the ROOT document is "com.webobjects.foundation.NSDictionary" why not "MyDictionary" or "NSMutableDictionary" why "NSDictionary" ?

Please reply to this post and thanks in advance.
adobongkangkong is offline   0 Reply With Quote
Old Aug 26, 2008, 11:23 PM   #9
lee1210
macrumors 68040
 
lee1210's Avatar
 
Join Date: Jan 2005
Location: Dallas, TX
Quote:
Originally Posted by adobongkangkong View Post
@ col.

Hi col. this is a bit off topic but this question is for you. You said you're a WebObjects programmer and have been subclassing dictionary I just want to know how did you subclass NSMutableDictionary. I have been subclassing NSMutableDictionary but everytime I use WOXMLCoder to serialize a subclass of NSMutableDictioanry it all resulst to its immutable counter part which is NSDictionary.

e.g.: I have a class MyDictionary that extends NSMutableDictionary.
My MyDictionary has the following methods.

setUserName(String username){
this.setObjectForKey(username,"USERNAME");
}

userName(){
if(this.containsKey("USERNAME")){
return (String)this.objectForKey("USERNAME");
}else{
return new String();
}
}

And when I serialized MyDictionary object using WOXMlCoder the result is this.

<ROOT type="com.webobjects.foundation.NSDictionary" objectID="1">
<USERNAME type="java.lang.String" objectID="2">myusername</USERNAME>
</ROOT>

Notice that the type of the ROOT document is "com.webobjects.foundation.NSDictionary" why not "MyDictionary" or "NSMutableDictionary" why "NSDictionary" ?

Please reply to this post and thanks in advance.
This was totally off-topic, but...
http://developer.apple.com/documenta...er.html#coder()

"an instance of NSArray, NSDictionary and NSData. Please note that before WebObjects 5.1, when the mutable forms of these classes (NSMutableArray, NSMutableDictionary and NSMutableData) are encoded using WOXMLCoder, they get written out as their immutable counterparts. For example, NSMutableArray used to be written out as NSArray. Now, they get written out as themselves. As a result, when WOXMLDecoder is used to decode the objects, they are decoded as mutable forms."

If you are using WebObjects less than 5.1, it looks like this is known behavior.

If you can't get around this behavior, you should be able to get yourself an NSMutableDictionary from the decoded NSDictionary with:

http://developer.apple.com/documenta...n.NSDictionary)

-Lee
lee1210 is offline   0 Reply With Quote
Old Aug 27, 2008, 02:14 AM   #10
adobongkangkong
macrumors newbie
 
Join Date: Aug 2008
Off topic Inheritance

BTW, I'm using WebObjects 5.3 as I don't have Leopard yet.
adobongkangkong is offline   0 Reply With Quote
Old Aug 27, 2008, 02:20 AM   #11
laprej
macrumors regular
 
Join Date: Oct 2005
Location: Troy, NY
http://en.wikipedia.org/wiki/Thread_hijacking
laprej is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
inheritance problem grandM iPhone/iPad Programming 5 Apr 18, 2014 04:47 PM
THE INHERITANCE–Short Film(Suspense/Thriller)edited-final cut pro 7/audio - logic pro smjd45 Digital Video 0 May 31, 2013 09:35 PM
dispatch_async and class inheritance hierarchy KnightWRX iPhone/iPad Programming 4 Sep 15, 2012 02:22 PM
Family Share Question, Upgrade Question, Argh head hurting.. Jazwire iPhone 1 Sep 14, 2012 01:19 AM

Forum Jump

All times are GMT -5. The time now is 12:51 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC