51

確かに、順序集合は集合のより具体的なケースですが、なぜではなくNSOrderedSetから継承するのですか?NSObjectNSSet

4

1 に答える 1

77

私はのインターフェースを通り抜けました、NSSetそしてあなたは正しいです、順序集合はリスコフの置換原則を満たしているように見え、それ故にから継承することができますNSSet

これを破る小さな方法が1つあります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ためです。NSMutableOrderedSetAppleの開発者は、追加のプロトコルがなくても簡単だったと思います。

于 2012-07-01T02:48:19.093 に答える