当然,有序集合是集合的一个更具体的例子,那么为什么NSOrderedSetNSObject继承而不是从NSSet继承呢?

推荐答案

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

有一个小方法打破了这一点:mutableCopy.mutableCopy的返回值必须是NSMutableSet,但NSMutableOrderedSet应该继承自NSOrderedSet.你不能两者兼得.

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

NSSet* immutable = [NSSet set];
NSMutableSet* mutable = [immutable mutableCopy];

[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES

现在,让我们假设NSOrderedSetNSSet继承,NSMutableOrderedSetNSOrderedSet继承:

//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可以同时实现这两个协议.我猜苹果的开发者只是觉得没有额外的协议更简单.

Objective-c相关问答推荐

恢复 iOS7 之前的 UINavigationController pushViewController 动画

在哪里可以找到 iPad 示例代码

XCTAssertEqual 不适用于双精度值

表达式不可分配 - 将浮点数分配为 Xcode 中其他两个浮点数的总和时出现问题?

使用 NSArray 初始化对象数组

Objective-C 浮点舍入

NSView 的边界与框架

ios 13 - 带有 UISearchBar _searchField 的自定义 SearchBar 不起作用

Objective-C 的 Eclipse 插件?

将 NSArray 转换为 NSDictionary

如何删除 xcode 5 中的旧配置文件?

Xcode:可以为协议接口所需的方法自动创建存根吗?

如何在情节提要场景中嵌入自定义视图 xib?

在不导入自己的情况下播放系统声音

如何删除应用程序可访问的所有 keys 串项目?

Xcode 在您的 keys 串中找不到此配置文件的有效私有证书/有效密钥对

如何查看 NSError?

自定义 colored颜色 我的 UIActivityIndi​​catorView

Objective-C 异常

如何定义 UIColor 的常量值?