当然,有序集是一个集合的更具体的情况,那么为什么NSOrderedSet
继承自NSObject
而不是NSSet
?
答案 0 :(得分:76)
我浏览了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
可以实现这两种协议。我猜Apple开发人员只是在没有额外协议的情况下更简单。