Z pewnością uporządkowany zbiór jest bardziej konkretnym przypadkiem zbioru, więc dlaczego NSOrderedSet
dziedziczy po NSObject
zamiast?Dlaczego NSOrderedSet nie dziedziczy po NSSet?
Odpowiedz
Przeszedłem przez interfejs NSSet
i masz rację, zamówione zestawy wydają się spełniać Liskov substitution principle i mogą tam odziedziczyć po NSSet
.
Jest jedna mała metoda, która to łamie: mutableCopy
. Wartość zwracana wynosząca mutableCopy
musi wynosić NSMutableSet
, ale NSMutableOrderedSet
powinna odziedziczyć po NSOrderedSet
. Nie możesz mieć obu.
Pozwól mi wyjaśnić za pomocą kodu. Po pierwsze, spójrzmy na prawidłowym zachowaniu NSSet
i NSMutableSet
:
NSSet* immutable = [NSSet set];
NSMutableSet* mutable = [immutable mutableCopy];
[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES
Teraz udawajmy NSOrderedSet
dziedziczy NSSet
i NSMutableOrderedSet
dziedziczy 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)
Co jeśli NSMutableOrderedSet
odziedziczone NSMutableSet
zamiast? Następnie mamy inny problem:
//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)
W przykładzie 1, nie będzie w stanie przekazać NSOrderedSet
do funkcji oczekując NSSet
ponieważ zachowanie jest inny. Zasadniczo jest to problem kompatybilności wstecznej.
W przykładzie 2 nie można przekazać funkcji NSMutableOrderedSet
do funkcji, która wymaga NSOrderedSet
, ponieważ pierwsza nie dziedziczy z drugiej.
Wszystko dlatego, że NSMutableOrderedSet
nie może dziedziczyć zarówno z NSMutableSet
, jak i NSOrderedSet
, ponieważ Objective-C nie ma dziedziczenia wielokrotnego. Aby obejść ten problem, należy utworzyć protokoły dla NSMutableSet
i NSOrderedSet
, ponieważ wtedy NSMutableOrderedSet
może zaimplementować oba protokoły. Sądzę, że programiści Apple po prostu byli prostsi bez dodatkowych protokołów.
Myślę, że protokoły miałyby więcej sensu - mogłoby to być bardziej związane z faktem, że 'NSMutableSet' został już zdefiniowany i jeszcze nie użył protokołu dla zmienności.Czy nie można jeszcze dodać protokołu pomimo faktu, że 'NSMutableSet' jest już zgodny z tym protokołem? – jhabbott
Gdyby chcieli, mogliby dodać nowy protokół bez niszczenia czegokolwiek. Możemy to zobaczyć w przyszłości. –
Świetna odpowiedź, to zostało użyte w książce NSHipster, tak znalazłem to pytanie ... czy wiesz, dlaczego książka NSHipster łączy ten problem bezpośrednio z NSSet będącym klastrem klasy ?, po prostu nie widzę, jak gdyby NSSet był konkretną klasę, która byłaby inna niż zmienna kwestia kopiowania, czy wiesz? http://nshipster.com/nsorderedset/ –
Jeśli program developer.apple.com nie był wyłączony, powinienem przejrzeć dokumentację, ponieważ teraz jestem ciekawy! Doskonałe pytanie. I mam nadzieję, że strona Apple nie pozostanie zbyt długo niedostępna, prawda? – WendiKidd
(Disclaimer: To jest czysta spekulacja i zbyt mało przekonująca dla mnie, aby chcieć ją przedstawić jako odpowiedź, ale ...) 'NSOrderedSet' jest bardziej specyficznym przypadkiem zarówno NSSet, jak i NSArray' . Są to zarówno klasy nie protokoły, i nie ma wielu dziedziczenia w Objective-C. Więc, które wybierasz? Istnieje argument "NSSet" ze względu na nazwę, ale może to być "NSUniqueArray", prawda? Graj bezpiecznie, porzuć oba ... –
Widzę dokładnie to, co mówisz, ale masz rację, że nie jest to aż tak przekonujące. Intuicyjnie oczekiwałbym, że '[asetet intersectsSet: anOrderedSet]' będzie możliwy (ale nie jest tak, ponieważ 'NSOrderedSet' nie jest podklasą' NSSet'), więc 'NSSet' czyni o wiele bardziej logiczny wybór dla nadklasy niż' NSArray' - i nawet jeśli dokonali równie logicznych wyborów, utrata polimorfizmu i tak nie wybrała ani gorszej opcji. – jhabbott