Waarom erft NSOrderedSet niet van NSSet?

Een geordende set is toch een meer specifiek geval van een set, dus waarom erft NSOrderedSetvan NSObjectin plaats van NSSet?


Antwoord 1, autoriteit 100%

Ik heb de interface van NSSetdoorlopen 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 mutableCopymoet een NSMutableSetzijn, maar NSMutableOrderedSetmoet 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 NSSeten NSMutableSet:

NSSet* immutable = [NSSet set];
NSMutableSet* mutable = [immutable mutableCopy];
[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES

Laten we nu doen alsof NSOrderedSeterft van NSSet, en NSMutableOrderedSeterft 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 NSMutableOrderedSetin 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 NSOrderedSetkunnen doorgeven aan een functie die een NSSetverwacht, omdat het gedrag anders is. Kortom, het is een probleem met achterwaartse compatibiliteit.

In voorbeeld 2 kun je een NSMutableOrderedSetniet doorgeven aan een functie die een NSOrderedSetverwacht, omdat de eerste niet van de laatste erft.

Dit alles is omdat NSMutableOrderedSetniet kan erven van zowel NSMutableSetals NSOrderedSetomdat Objective-C geen meervoudige overerving heeft. De manier om dit te omzeilen is om protocollen te maken voor NSMutableSeten NSOrderedSet, omdat NSMutableOrderedSetdan beide protocollen kan implementeren. Ik denk dat de Apple-ontwikkelaars, hoewel het eenvoudiger was zonder de extra protocollen.

Other episodes