On Jun 9, 2008, at 10:24 AM, John Engelhart wrote:

This is not a bug. This is fundamental to how object-oriented programming works! You should always be able to pass an instance of a subclass wherever an instance of the superclass is expected.

You're mistaken.  You have statically typed the object.

John, it is you who are mistaken. You're mistaken about what "statically typed" means in Objective-C. It does not mean "I will always pass an instance of exactly NSArray", it means "I will always pass an instance of NSArray or a subclass."

That's all it means.

Just as '+(NSArray *)array' does not mean "and any possible subclasses"

In fact, it WOULD mean that. It means "returns an instance of NSArray, or any subclass thereof, that senders should treat as an NSArray."

For example, if -[NSArray array] were declared as above, it could still perfectly validly return a shared instance of a special _NSEmptyArray subclass of NSArray.

All your code will know or care about is that what it gets back is usable as an NSArray.

If one applies the 'attribute only applies to the class it was specified for' rule:

By statically typing the class to NSArray, you have certified to the compiler that no other object type will be received as an argument. When you passed it an object of a different type, even a subclass, you broke your promise to the compiler.

This is simply wrong.

You're encouraged to read the section "Enabling Static Behavior - Static Typing" in the Objective-C manual. This is what allows for subclasses to return different types for the same method. By statically typing a declaration as NSArray, you've told the compiler that the object is a NSArray (only) class object, and only the methods for NSArray apply.

John, with all due respect, I do know what I'm talking about here -- I've been working with Objective-C on NeXT and Mac OS X for 11 years now -- and it is you who are wrong about this.

Whether you're dealing with Objective-C, C++, or Java, instances of subclasses are always substitutable for instances of their superclass where the type system is concerned.

The fact that object instantiation methods return 'id' and not the base class are further evidence that this is indeed the case.

The reason these kinds of methods have a return type of (id) is that there is no way to say "returns an object of the receiver's class." For example, +[NSArray array] returns (id) rather than (NSArray *) because otherwise +[NSMutableArray array] would require a separate declaration (NSMutableArray *). Rather than have a large number of separate declarations, these methods return (id).

You also can't send messages declared in a subclass of NSArray to a 'NSArray *array;' object without getting a warning. Again, further evidence that the compiler believes that only the explicitly named class is applicable, and not 'any and all subclasses'.

You misunderstand. You can *assign* an instance of any subclass to a variable typed as a class. The compiler will warn you about any messages you send that aren't in the interface of the typed class, however.

Thus you can say, perfectly validly:

  NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
  NSArray *array = mutableArray;

This is perfectly fine. However, the compiler will give you a warning if you try to send any non-NSArray messages to "array."

  -- Chris

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to