Een geordende set is toch een meer specifiek geval van een set, dus waarom erft NSOrderedSet
van NSObject
in plaats van NSSet
?
Antwoord 1, autoriteit 100%
Ik heb de interface van NSSet
doorlopen en je hebt gelijk, bestelde sets lijken te voldoen aan de Liskov-substitutieprincipeen zou daarom kunnen erven van NSSet
.
Er is een kleine methode die dit verbreekt: mutableCopy
. De retourwaarde van mutableCopy
moet een NSMutableSet
zijn, maar NSMutableOrderedSet
moet erven van NSOrderedSet
. Je kunt niet beide hebben.
Laat het me uitleggen met wat code. Laten we eerst eens kijken naar het juiste gedrag van NSSet
en NSMutableSet
:
NSSet* immutable = [NSSet set];
NSMutableSet* mutable = [immutable mutableCopy];
[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES
Laten we nu doen alsof NSOrderedSet
erft van NSSet
, en NSMutableOrderedSet
erft van 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)
Wat als NSMutableOrderedSet
in plaats daarvan is overgenomen van NSMutableSet
? Dan krijgen we een ander probleem:
//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)
In voorbeeld 1 zou je geen NSOrderedSet
kunnen doorgeven aan een functie die een NSSet
verwacht, omdat het gedrag anders is. Kortom, het is een probleem met achterwaartse compatibiliteit.
In voorbeeld 2 kun je een NSMutableOrderedSet
niet doorgeven aan een functie die een NSOrderedSet
verwacht, omdat de eerste niet van de laatste erft.
Dit alles is omdat NSMutableOrderedSet
niet kan erven van zowel NSMutableSet
als NSOrderedSet
omdat Objective-C geen meervoudige overerving heeft. De manier om dit te omzeilen is om protocollen te maken voor NSMutableSet
en NSOrderedSet
, omdat NSMutableOrderedSet
dan beide protocollen kan implementeren. Ik denk dat de Apple-ontwikkelaars, hoewel het eenvoudiger was zonder de extra protocollen.