Chắc chắn một bộ đặt hàng là trường hợp cụ thể hơn của một bộ, vậy tại sao NSOrderedSet
được kế thừa từ NSObject
thay vì NSSet
?Tại sao NSOrderedSet không được kế thừa từ NSSet?
Trả lời
Tôi đã đi qua giao diện của NSSet
và bạn nói đúng, các bộ đặt hàng dường như đáp ứng số Liskov substitution principle và có thể thừa kế từ NSSet
.
Có một phương pháp nhỏ để giải quyết vấn đề này: mutableCopy
. Giá trị trả lại của mutableCopy
phải là NSMutableSet
, nhưng NSMutableOrderedSet
phải được kế thừa từ NSOrderedSet
. Bạn không thể có cả hai.
Hãy để tôi giải thích với một số mã. Đầu tiên, chúng ta hãy nhìn vào những hành vi đúng đắn về NSSet
và NSMutableSet
:
NSSet* immutable = [NSSet set];
NSMutableSet* mutable = [immutable mutableCopy];
[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES
Bây giờ, chúng ta hãy giả vờ NSOrderedSet
thừa hưởng từ NSSet
, và NSMutableOrderedSet
thừa hưởng từ 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)
gì nếu NSMutableOrderedSet
thừa hưởng từ NSMutableSet
để thay thế? Sau đó chúng ta có được một vấn đề khác nhau:
//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)
Trong ví dụ 1, bạn sẽ không thể vượt qua một NSOrderedSet
thành một chức năng hy vọng một NSSet
vì hành vi này là khác nhau. Về cơ bản, đó là một vấn đề tương thích ngược.
Trong ví dụ 2, bạn không thể chuyển một số NSMutableOrderedSet
vào hàm mong đợi một NSOrderedSet
vì cũ không kế thừa từ sau.
Tất cả điều này là do NSMutableOrderedSet
không thể kế thừa từ cả hai NSMutableSet
và NSOrderedSet
vì Mục tiêu-C không có nhiều thừa kế. Cách để giải quyết vấn đề này là thực hiện các giao thức cho NSMutableSet
và NSOrderedSet
, vì sau đó NSMutableOrderedSet
có thể thực hiện cả hai giao thức. Tôi đoán các nhà phát triển của Apple mặc dù nó đã được đơn giản mà không có các giao thức bổ sung.
Tôi nghĩ rằng các giao thức sẽ có ý nghĩa hơn - nó có thể được nhiều hơn để làm với thực tế là 'NSMutableSet' đã được xác định và đã không sử dụng một giao thức cho các mutability.Không thể giao thức vẫn được thêm vào mặc dù thực tế là 'NSMutableSet' đã phù hợp với nó chưa? – jhabbott
Nếu họ muốn, họ có thể thêm một giao thức mới mà không vi phạm bất cứ điều gì. Chúng ta có thể thấy nó được thêm vào trong tương lai. –
Câu trả lời hay, điều này đã được sử dụng trong sách NSHipster, đó là cách tôi tìm thấy câu hỏi này ... bạn có biết tại sao cuốn sách NSHipster liên kết trực tiếp vấn đề này với NSSet là một nhóm lớp không ?, Tôi đơn giản không biết làm thế nào nếu NSSet một lớp cụ thể mà điều này sẽ khác biệt với vấn đề sao chép có thể thay đổi, bạn có biết không? http://nshipster.com/nsorderedset/ –
Nếu developer.apple.com không ngừng hoạt động ngay bây giờ, tôi sẽ xem xét tài liệu vì giờ đây bạn đã khiến tôi tò mò! Câu hỏi hay. Và hy vọng một trang web của Apple sẽ không ở lại quá lâu, phải không? – WendiKidd
(Disclaimer: Đây là suy đoán thuần túy, và quá thuyết phục đối với tôi để thực sự cung cấp nó như là một câu trả lời, nhưng ...) Một 'NSOrderedSet' là một trường hợp cụ thể hơn của cả một' NSSet' và 'NSArray' . Đó là cả hai lớp không phải là giao thức, và không có nhiều thừa kế trong Objective-C. Vậy bạn chọn cái nào? Có một đối số cho 'NSSet' vì tên, nhưng nó hoàn toàn có thể là' NSUniqueArray', đúng không? Chơi nó an toàn, mương cả hai ... –
Tôi thấy chính xác những gì bạn đang nói, nhưng bạn nói đúng rằng nó không phải là tất cả những gì thuyết phục. Tôi mong đợi một cách trực giác '[aSet intersectsSet: anOrderedSet]' là có thể (nhưng không phải vì 'NSOrderedSet' không phải là một lớp con của' NSSet'), do đó, 'NSSet' tạo ra một sự lựa chọn hợp lý hơn cho một siêu lớp hơn' NSArray' - và thậm chí nếu họ đưa ra những lựa chọn hợp lý như nhau, việc mất đa hình làm cho việc lựa chọn không phải là một lựa chọn kém hơn. – jhabbott