当然,有序集合是集合的一个更具体的例子,那么为什么NSOrderedSet
从NSObject
继承而不是从NSSet
继承呢?
当然,有序集合是集合的一个更具体的例子,那么为什么NSOrderedSet
从NSObject
继承而不是从NSSet
继承呢?
我浏览了NSSet
的界面,你是对的,有序集似乎满足Liskov substitution principle,因此可以从NSSet
继承.
有一个小方法打破了这一点:mutableCopy
.mutableCopy
的返回值必须是NSMutableSet
,但NSMutableOrderedSet
应该继承自NSOrderedSet
.你不能两者兼得.
让我用一些代码解释一下.首先,让我们看看NSSet
和NSMutableSet
的正确行为:
NSSet* immutable = [NSSet set];
NSMutableSet* mutable = [immutable mutableCopy];
[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES
现在,让我们假设NSOrderedSet
从NSSet
继承,NSMutableOrderedSet
从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)
如果NSMutableOrderedSet
是从NSMutableSet
继承来的呢?然后我们会遇到另一个问题:
//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)
在示例1中,由于行为不同,无法将NSOrderedSet
传递给预期为NSSet
的函数.基本上,这是一个向后兼容性问题.
在示例2中,不能将NSMutableOrderedSet
传递给预期为NSOrderedSet
的函数,因为前者不会从后者继承.
所有这些都是因为NSMutableOrderedSet
不能同时从NSMutableSet
和NSOrderedSet
继承,因为Objective-C没有多重继承.解决这个问题的方法是为NSMutableSet
和NSOrderedSet
制定协议,因为NSMutableOrderedSet
可以同时实现这两个协议.我猜苹果的开发者只是觉得没有额外的协议更简单.