为什么NSOrderedSet不从NSSet继承?

时间:2012-07-01 01:41:53

标签: objective-c ios nsset nsorderedset

当然,有序集是一个集合的更具体的情况,那么为什么NSOrderedSet继承自NSObject而不是NSSet

1 个答案:

答案 0 :(得分:76)

我浏览了NSSet的界面,你是对的,有序集似乎满足Liskov substitution principle,并且可以继承NSSet

有一种方法可以解决这个问题:mutableCopymutableCopy的返回值必须为NSMutableSet,但NSMutableOrderedSet应从NSOrderedSet继承。你不能兼得。

让我用一些代码解释一下。首先,让我们看一下NSSetNSMutableSet的正确行为:

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无法继承NSMutableSetNSOrderedSet,因为Objective-C没有多重继承。解决这个问题的方法是为NSMutableSetNSOrderedSet制定协议,因为NSMutableOrderedSet可以实现这两种协议。我猜Apple开发人员只是在没有额外协议的情况下更简单。