Why doesn't NSOrderedSet inherit from NSSet? Why doesn't NSOrderedSet inherit from NSSet? ios ios

Why doesn't NSOrderedSet inherit from 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 1NSOrderedSet* 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 2NSOrderedSet* 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.