Kiedy zastanawiasz się nad wszystkim, co wydaje się "dziwne" w Swift, przez większość czasu odpowiedź brzmi "z powodu Celu C".
jakiegoś punktu widzenia, uważam, 3 poziom dostępu wspólne dla wielu nowoczesnych języków programowania:
private
: dostępny tylko w tej klasie, w której jest zdefiniowana.
protected
: dostępne tylko dla klasy, w której jest zdefiniowana i jej podklas.
public
: dostępne dla każdego programu zewnętrznego.
Weźmy jeden krok dalej wstecz, do świata C. C ma modyfikator dostępu w ogóle, nie jest językiem OOP. Jednak w rzeczywistości jest bliżej posiadania prywatnego/publicznego systemu. Jeśli chcesz, aby inne programy znały Twoje symbole (funkcje, makra, typy danych itp.), Możesz je zdefiniować w pliku nagłówkowym (.h
). Jeśli nie, możesz je zdefiniować w pliku źródłowym (.c
) lub w prywatnym pliku nagłówkowym.Niezależnie od programu zainteresowany symbol będzie zawierać odpowiedni plik nagłówka:
#include "foo.h"
Ten #include
jest nie więcej niż kompilatora wspomaganego kopia & pasty. Kompilator skopiuje wszystkie symbole z foo.h
i ponownie je odczyta w pliku źródłowym.
Ponieważ Objective-C jest ścisłym nadzbiorem C, każdy ważny program C jest również ważnym programem Objective-C. Objective-C kontynuuje tę tradycję: zadeklarować publicznych metod w pliku nagłówkowym, zachować prywatny deklarację metody do pliku wdrażania:
// ------------------------------------------
// MyClass.h
// ------------------------------------------
@interface MyClass: NSObject
- (void) publicMethod;
@end
// ------------------------------------------
// MyClass.m
// ------------------------------------------
#import "MyClass.h"
// Declare your private methods here.
// You can move this to a separate file, i.e. MyClass+Private.h if you want
@interface MyClass()
- (void) privateMethod;
@end
@implementation MyClas
- (void) publicMethod() { ... }
- (void) privateMethod() { ... }
@end
Tak w skrócie, Objective-C wydaje się dziedziczyć C system w deklaracji publicznych/prywatnych. Jednak Objective-C jest bardzo dynamicznym językiem. Możesz zapytać swoje środowisko uruchomieniowe o wszystkie metody do klasy, prywatnej lub publicznej. Kontrola dostępu w Objective-C to raczej "używaj tego, co ci powiem w dokumentacji", niż "ta metoda jest dla Ciebie niedostępna".
To stanowi paradoks: jak wdrożyć protected
w Objective-C? Na to nie ma dobrej odpowiedzi. Jeden wspólny wzór jest przeniesienie wszystkich chronionych metod w osobnym pliku deklaracji i importować je do głównej klasy i realizacji podklas:
// ------------------------------------------
// MyClass+Protected.h
// ------------------------------------------
@interface MyClass (Protected)
- (void) protectedMethod;
@end
// ------------------------------------------
// MySubClass.m
// ------------------------------------------
#import "MyClass+Protected.h"
...
Swift po prostu kontynuuje tę tradycję, lepiej lub gorzej. Istnieje an accepted proposal, aby zmienić to w Swift 3. Jeśli tak, to Chris Lattner i zespół Swift wykazali niewielkie podobieństwo do przeszłości i spuścizny C. Możesz zobaczyć dowód na to w Swift 2.2 z usunięciem ++
i stylu C for
pętle.
Nie byłbym tak szybki, by powiedzieć, że łamie hermetyzację. Jeśli masz dwie klasy, które nie są ze sobą powiązane (i nie powinny wiedzieć o swoich wewnętrznych cechach), to prawdopodobnie nie powinny znajdować się w tym samym pliku źródłowym. –
Powiązane: [Kontrola dostępu i ochrona] (https://developer.apple.com/swift/blog/?id=11) na blogu Swift. –
@CraigOtis jakie typy można zdefiniować jako "powiązane", aby mogły one zadziałać między sobą? Dwie dyskretne klasy nie powinny wiedzieć o swoim prywatnym okresie składowym. Opieram się na posiadaniu wszystkich typów we własnych plikach źródłowych, nawet malutkich. –