W Swift istnieje pięć poziomów dostępu do członków typów (właściwości, metody itp.) i samych typów:
open — maksymalny stopień publiczności. Można dziedziczyć i nadpisywać nawet poza modułem.public — dostępne poza modułem, ale nie można nadpisywać/dziedziczyć.internal (domyślnie) — dostępne wewnątrz modułu.fileprivate — dostępne tylko w ramach pliku.private — dostępne tylko w obrębie obszaru deklaracji (extension też w tym zakresie).private dla logiki, która nie powinna być widoczna nigdzie poza deklaracją.fileprivate — jeśli wymagana jest wymiana danych w jednym pliku (np. między dwoma powiązanymi extensions).internal — domyślny dla wszystkiego ogólnodostępnego w module.public/open — dla API używanych przez inne moduły/frameworki.open class MyOpenClass {} public class MyPublicClass {} internal class InternalClass {} fileprivate class FilePrivateClass {} private class PrivateClass {}
Czym różni się open od public przy opisywaniu klasy? Dlaczego nie wszystkie klasy publiczne są dostępne do dziedziczenia?
Odpowiedź:
open oznacza klasę/metodę jako dostępną do nadpisania i dziedziczenia poza swoim modułem. public tylko otwiera dostęp do użycia, ale nie pozwala na tworzenie dziedziców poza modułem. Z jednej strony chroni to implementację przed niepożądanymi zmianami, z drugiej — otwiera tylko potrzebne punkty rozszerzenia.
public class PublicClass {} open class OpenClass {} // W innym module: class InheritFromOpen: OpenClass {} // OK class InheritFromPublic: PublicClass {} // Błąd!
Historia
W ogólnej bibliotece klasa została oznaczona jako public, a zewnętrzny projekt próbował ją rozszerzyć, nadpisując metody. Projekt nie kompilował się z powodu błędnego zrozumienia różnicy między public a open — kosztowało to zespół dodatkowy tydzień na poprawki interfejsu.
Historia
W obrębie jednego pliku próbowano uzyskać dostęp do private-właściwości z extension — ale właściwość została zadeklarowana jako nie fileprivate, a jako private. Doprowadziło to do błędu kompilatora, który zauważono dopiero na integracyjnej kompilacji.
Historia
W aplikacji z wieloma frameworkami wszystkie typy były oznaczane jako internal (domyślnie). Gdy zajęło się korzystanie z typów między modułami, interfejs nie był dostępny — konieczne było przepisywanie dziesiątek deklaracji na public, co zajęło dodatkowy czas i testowanie.