Surely an ordered set is a more-specific case of a set, so why does NSOrderedSet
inherit from NSObject
rather than NSSet
?
I went through the interface of NSSet
and you're right, ordered sets appear to satisfy the Liskov substitution principle and could therefor inherit from NSSet
.
There is one little method that breaks this: mutableCopy
. The return value of mutableCopy
must be an NSMutableSet
, but NSMutableOrderedSet
should inherit from NSOrderedSet
. You can't have both.
Let me explain with some code. First, let's look at the correct behaviour of NSSet
and NSMutableSet
:
NSSet* immutable = [NSSet set];
NSMutableSet* mutable = [immutable mutableCopy];
[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES
Now, let's pretend NSOrderedSet
inherits from NSSet
, and NSMutableOrderedSet
inherits from NSOrderedSet
:
//Example 1
NSOrderedSet* immutable = [NSOrderedSet orderedSet];
NSMutableOrderedSet* mutable = [immutable mutableCopy];
[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // NO (this is the problem)
What if NSMutableOrderedSet
inherited from NSMutableSet
instead? Then we get a different problem:
//Example 2
NSOrderedSet* immutable = [NSOrderedSet orderedSet];
NSMutableOrderedSet* mutable = [immutable mutableCopy];
[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES
[mutable isKindOfClass:[NSOrderedSet class]]; // NO (this is a problem)
In Example 1, you wouldn't be able to pass an NSOrderedSet
into a function expecting an NSSet
because the behaviour is different. Basically, it's a backwards compatibility problem.
In Example 2, you can't pass an NSMutableOrderedSet
into a function expecting an NSOrderedSet
because the former doesn't inherit from the latter.
All of this is because NSMutableOrderedSet
can't inherit from both NSMutableSet
and NSOrderedSet
because Objective-C doesn't have multiple inheritance. The way to get around this is to make protocols for NSMutableSet
and NSOrderedSet
, because then NSMutableOrderedSet
can implement both protocols. I guess the Apple developers just though it was simpler without the extra protocols.
NSMutableSet
was already defined and didn't already use a protocol for the mutability. Couldn't the protocol still be added despite the fact that NSMutableSet
already conforms to it? –
Eudemon © 2022 - 2024 — McMap. All rights reserved.
NSOrderedSet
is a more-specific case of both anNSSet
and anNSArray
. Those are both classes not protocols, and there's no multiple inheritance in Objective-C. So, which do you pick? There's an argument forNSSet
because of the name, but it could totally have beenNSUniqueArray
, right? Play it safe, ditch them both... – Dunk[aSet intersectsSet:anOrderedSet]
to be possible (but it's not since theNSOrderedSet
is not a subclass ofNSSet
), soNSSet
makes a far more logical choice for a superclass thanNSArray
- and even if they made equally logical choices, losing the polymorphism makes choosing neither an inferior option anyway. – Eudemon