Почему NSOrderedSet не наследуется от NSSet?

Конечно, упорядоченный набор является более конкретным случаем набора, так почему же NSOrderedSet наследовать от NSObject скорее, чем NSSet?

1 ответ

Решение

Я прошел через интерфейс NSSet и вы правы, упорядоченные множества, по-видимому, удовлетворяют принципу подстановки Лискова и поэтому могут наследовать от 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, хотя это было проще без дополнительных протоколов.

Другие вопросы по тегам