2012-07-01 19 views
48

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?

+0

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

+2

(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 ... –

+1

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

Odpowiedz

72

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.

+0

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

+0

Gdyby chcieli, mogliby dodać nowy protokół bez niszczenia czegokolwiek. Możemy to zobaczyć w przyszłości. –

+2

Ś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/ –

Powiązane problemy