Почему 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, хотя это было проще без дополнительных протоколов.