Czy Swift ma modyfikatory dostępu?


273

W celu C danych może być na przykład public, protectedalbo private. Na przykład:

@interface Foo : NSObject
{
  @public
    int x;
  @protected:
    int y;
  @private:
    int z;
  }
-(int) apple;
-(int) pear;
-(int) banana;
@end

W odnośniku Swift nie znalazłem żadnej wzmianki o modyfikatorach dostępu. Czy można ograniczyć widoczność danych w Swift?


Ja też nie. Apple powinien przynajmniej wprowadzić etykietę dla osób prywatnych, tak jak w pythonie są one poprzedzone znakiem podkreślenia.
Ciantic

Dodano odpowiedź zaktualizowaną do ostatecznej wersji Xcode 6.1.1
holroy

Odpowiedzi:


419

Począwszy od wersji Swift 3.0.1 , istnieją 4 poziomy dostępu , opisane poniżej, od najwyższego (najmniej restrykcyjnego) do najniższego (najbardziej restrykcyjnego).


1. openipublic

Włącz encję do użycia poza modułem definiującym (docelowym). Zazwyczaj używasz openlub publicuzyskujesz dostęp przy określaniu publicznego interfejsu do frameworka.

Jednak opendostęp dotyczy tylko klas i członków klasy i różni się od publicdostępu w następujący sposób:

  • public klasy i członkowie klasy mogą być podklasowane i zastępowane tylko w module definiującym (docelowym).
  • open klasy i elementy klasy mogą być podklasowane i zastępowane zarówno w module definiującym, jak i poza nim (cel).

// First.framework – A.swift

open class A {}

// First.framework – B.swift

public class B: A {} // ok

// Second.framework – C.swift

import First

internal class C: A {} // ok

// Second.framework – D.swift

import First

internal class D: B {} // error: B cannot be subclassed

2) internal

Umożliwia użycie encji w module definiującym (docelowym). Zwykle używasz internaldostępu podczas definiowania wewnętrznej struktury aplikacji lub frameworka.

// First.framework – A.swift

internal struct A {}

// First.framework – B.swift

A() // ok

// Second.framework – C.swift

import First

A() // error: A is unavailable

3) fileprivate

Ogranicza użycie encji do jej pliku źródłowego definiującego. Zwykle używasz fileprivatedostępu, aby ukryć szczegóły implementacji określonego elementu funkcjonalności, gdy są one używane w całym pliku.

// First.framework – A.swift

internal struct A {

    fileprivate static let x: Int

}

A.x // ok

// First.framework – B.swift

A.x // error: x is not available

4 private

Ogranicza użycie encji do jej załączonej deklaracji. Zwykle używasz privatedostępu, aby ukryć szczegóły implementacji określonego elementu funkcjonalności, gdy szczegóły te są używane tylko w ramach jednej deklaracji.

// First.framework – A.swift

internal struct A {

    private static let x: Int

    internal static func doSomethingWithX() {
        x // ok
    }

}

A.x // error: x is unavailable

37
Czy ktoś mógłby mi wyjaśnić, dlaczego to nie jest wielka sprawa?
Zaky German

15
W OOP zawsze są pewne metody lub zmienne, które powinny być prywatne lub chronione. Pozwala to na implementację projektu SOLID , ponieważ duże metody są podzielone na kilka mniejszych, z których każda ma własną odpowiedzialność, którą można zastąpić, ale tylko „główna” metoda powinna być dostępna do użytku publicznego.
akashivskyy

19
Ja osobiście nie lubię rozwiązań takich jak ta z wiodącymi „prywatnymi” metodami podkreślania / znaków specjalnych. Nawet jeśli zagwarantowane jest, że ja będę jedyną osobą, która kiedykolwiek zajrzy do tego kodu, spowoduje to, że kod będzie bardziej bezpieczny / mniej podatny na błędy, ponieważ kompilator po prostu uniemożliwi ci robienie rzeczy, których nie powinieneś robić. Myślę więc, że powinni jak najszybciej pozbyć się „mechanizmów kontroli dostępu”, aby ludzie nie przyzwyczaili się do złych nawyków.
Jonas Eschmann

10
Informacje o wersji beta Xcode 6 mówią: „Kontrola dostępu (członkowie publiczni / prywatni) nie jest włączona w tym ziarnie. (15747445)”
Martin Ullrich,

9
@alcalde Idea publicznego interfejsu jest bardzo cenna. Jeśli zamierzasz, że cały kod w klasie musi znajdować się w funkcjach, które są częścią publicznego API, myślę, że to dość ograniczone. Z drugiej strony posiadanie określonego publicznego interfejsu API umożliwia zmianę implementacji (w tym stosowanie metod prywatnych) bez zakłócania działania konsumentów. Jeśli ktoś „potrzebuje” użyć metody klasy wewnętrznej, to czuję, że nie rozumie ograniczeń funkcjonalności klasy (lub próbuje użyć klasy buggy).
jinglesthula,

26

Swift 4 / Swift 5

Jak wspomniano w dokumentacji Swift - Kontrola dostępu , Swift ma 5 kontroli dostępu :

  • otwarty i publiczny : można uzyskać do niego dostęp z encji ich modułu i encji dowolnego modułu, który importuje moduł definiujący.

  • wewnętrzne : można uzyskać dostęp tylko z encji ich modułu. Jest to domyślny poziom dostępu.

  • fileprivate i prywatne mogą być dostępne tylko w ograniczony w ograniczonym zakresie, w którym ich zdefiniowania.



Jaka jest różnica między jawnym a publicznym ?

open jest taki sam jak public we wcześniejszych wersjach Swift, pozwalają one klasom z innych modułów na używanie i dziedziczenie, tj .: można je subklasować z innych modułów. Pozwalają również członkom z innych modułów na ich używanie i zastępowanie. Ta sama logika dotyczy ich modułów.

public zezwala klasom z innych modułów na używanie ich, ale nie na dziedziczenie ich, tj .: nie można ich podklasować z innych modułów. Pozwalają też członkom z innych modułów korzystać z nich, ale NIE mogą ich zastępować. W przypadku modułów mają one tę samą logikę otwartą (pozwalają klasom na ich używanie i dziedziczenie; Pozwalają członkom na ich używanie i zastępowanie).


Jaka jest różnica między plikiem prywatnym a prywatnym ?

fileprivate można uzyskać z całego pliku.

private może być dostępne tylko z ich pojedynczej deklaracji i rozszerzeń tej deklaracji, które znajdują się w tym samym pliku; Na przykład:

// Declaring "A" class that has the two types of "private" and "fileprivate":
class A {
    private var aPrivate: String?
    fileprivate var aFileprivate: String?

    func accessMySelf() {
        // this works fine
        self.aPrivate = ""
        self.aFileprivate = ""
    }
}

// Declaring "B" for checking the abiltiy of accessing "A" class:
class B {
    func accessA() {
        // create an instance of "A" class
        let aObject = A()

        // Error! this is NOT accessable...
        aObject.aPrivate = "I CANNOT set a value for it!"

        // this works fine
        aObject.aFileprivate = "I CAN set a value for it!"
    }
}



Jakie są różnice między Swift 3 a Swift 4 Access Control?

Jak wspomniano w propozycji SE-0169 , jedynym ulepszeniem dodanym do Swift 4 jest to, że zakres prywatnej kontroli dostępu został rozszerzony, aby był dostępny z rozszerzeń tej deklaracji w tym samym pliku; Na przykład:

struct MyStruct {
    private let myMessage = "Hello World"
}

extension MyStruct {
    func printMyMessage() {
        print(myMessage)
        // In Swift 3, you will get a compile time error:
        // error: 'myMessage' is inaccessible due to 'private' protection level

        // In Swift 4 it should works fine!
    }
}

Dlatego nie ma potrzeby deklarowania myMessagejako plikprivate, aby był dostępny w całym pliku.


17

Kiedy mówi się o stworzeniu „prywatnej metody” w Swift lub ObjC (lub ruby, java lub…), te metody nie są tak naprawdę prywatne. Wokół nich nie ma faktycznej kontroli dostępu. Każdy język, który oferuje choć odrobinę introspekcji, pozwala programistom uzyskać dostęp do tych wartości spoza klasy, jeśli naprawdę tego chcą.

Tak więc tak naprawdę tutaj mówimy o sposobie zdefiniowania publicznego interfejsu, który jedynie przedstawia pożądaną funkcjonalność i „ukrywa” resztę, którą uważamy za „prywatną”.

Mechanizm Swift do deklarowania interfejsów jest protocoli można go w tym celu wykorzystać.

protocol MyClass {
  var publicProperty:Int {get set}
  func publicMethod(foo:String)->String
}

class MyClassImplementation : MyClass {
  var publicProperty:Int = 5
  var privateProperty:Int = 8

  func publicMethod(foo:String)->String{
    return privateMethod(foo)
  }

  func privateMethod(foo:String)->String{
    return "Hello \(foo)"
  }
}

Pamiętaj, że protokoły są pierwszorzędnymi typami i mogą być używane w dowolnym miejscu. W ten sposób ujawniają tylko własne interfejsy, a nie implementacyjne.

Tak więc, o ile używasz MyClasszamiast MyClassImplementationw typach parametrów itp., Wszystko powinno działać:

func breakingAndEntering(foo:MyClass)->String{
  return foo.privateMethod()
  //ERROR: 'MyClass' does not have a member named 'privateMethod'
}

Istnieją pewne przypadki bezpośredniego przypisania, w których musisz jawnie pisać na maszynie zamiast polegać na Swift, aby wnioskować, ale to nie wydaje się być przełomem:

var myClass:MyClass = MyClassImplementation()

Używanie protokołów w ten sposób jest semantyczne, dość zwięzłe, i moim zdaniem przypomina bardzo rozszerzenia klas, których używaliśmy do tego celu w ObjC.


1
Jeśli protokoły nie pozwalają nam mieć domyślnego argumentu, jak mogę utworzyć metodę publiczną z opcjonalnymi parametrami, która nadal będzie zgodna z protokołem?
bdurao

Nie rozumiem o co ci chodzi. Poniżej przedstawiono metodę publiczną z opcjonalnym parametrem. Wygląda na
jemmons

Z jakiegoś powodu opcjonalny parametr nie działa tak, jak powinien w moim projekcie, próbowałem już czegoś podobnego do twojego przykładu GitHub. Ponieważ nie możemy ustawić domyślnego parametru w protokole, utknąłem i ostatecznie zadałem pytanie. Dziękuję za próbę pomocy.
bdurao

Wszyscy wiemy, że wszystko można zhakować. Potrzebujemy tylko trochę zamówienia, dlatego potrzebujemy modyfikatorów dostępu
canbax

14

O ile mi wiadomo, nie ma słów kluczowych „public”, „private” ani „protected”. Sugerowałoby to, że wszystko jest publiczne.

Jednak Apple może oczekiwać, że ludzie będą używać „ protokołów ” (zwanych przez resztę świata interfejsami) i fabrycznego wzorca projektowego, aby ukryć szczegóły typu wdrożenia.

W każdym razie jest to dobry wzorzec projektowy; ponieważ pozwala to zmienić hierarchię klas implementacji , zachowując jednocześnie logiczny system typów.


Jest to miłe, ponieważ zmniejsza również sprzężenie i może ułatwić testowanie.
Scroog1

4
To działałoby lepiej, gdyby istniał sposób na ukrycie klasy implementacji protokołu, ale wydaje się, że tak nie jest.
David Moles

Czy ktoś może podać przykładowy przykład tego wzoru?
bloudermilk

Cóż, ta odpowiedź była poprawna w poprzednich wersjach Swift, wydaje się, że nie jest już ważna :) proszę sprawdzić moją odpowiedź .
Ahmad F

12

Korzystając z kombinacji protokołów, zamknięć oraz klas zagnieżdżonych / wewnętrznych, możliwe jest użycie czegoś podobnego do wzoru modułu, aby ukryć informacje w Swift w tej chwili. Nie jest super czysty ani przyjemny w czytaniu, ale działa.

Przykład:

protocol HuhThing {
  var huh: Int { get set }
}

func HuhMaker() -> HuhThing {
   class InnerHuh: HuhThing {
    var innerVal: Int = 0
    var huh: Int {
      get {
        return mysteriousMath(innerVal)
      }

      set {
       innerVal = newValue / 2
      }
    }

    func mysteriousMath(number: Int) -> Int {
      return number * 3 + 2
    }
  }

  return InnerHuh()
}

HuhMaker()
var h = HuhMaker()

h.huh      // 2
h.huh = 32 
h.huh      // 50
h.huh = 39
h.huh      // 59

innerVal i mysteriousMath są tutaj ukryte przed użyciem zewnętrznym, a próba wkopania się w obiekt powinna spowodować błąd.

Jestem tylko częścią mojej drogi do czytania dokumentów Swift, więc jeśli jest tu jakaś wada, proszę to wskazać, chciałbym wiedzieć.


ok, myślałem też o tym rozwiązaniu, ale wyjaśnij mi, dlaczego nie mogę uzyskać dostępu za pomocą h.huh.innerVal?
Sam

Swift jest bezpieczny dla typu i jedyne, co świat zewnętrzny wie o h, to to, że jest on zgodny z HuhThing. HuhThing nie zawiera żadnych informacji o właściwości o nazwie innerVal, dlatego próba uzyskania dostępu do niej jest błędem.
Dave Kapp

8
Nadal dostępny: Preflect(h)[0].1.value // 19
John Estropia

2
Fajnie tam znajdź John - nie byłem świadomy refleksji. Wygląda na to, że zamienia obiekty w krotki - czy jest jakaś oficjalna dokumentacja na temat tej funkcji lub innych elementów metaprogramowania w Swift? Przejrzałem przewodnik językowy w iBooks, ale go nie widzę.
Dave Kapp,

1
@JohnEstropia Nie sądzę, żeby liczyło się odbicie. W Java (bardziej dojrzały język), nie modyfikatory dostępu, ale nie zapobiegają refleksji sztuczki albo.
11684

10

Począwszy od Xcode 6 beta 4, Swift ma modyfikatory dostępu. Z informacji o wersji:

Szybka kontrola dostępu ma trzy poziomy dostępu:

  • do podmiotów prywatnych można uzyskać dostęp tylko z pliku źródłowego, w którym są zdefiniowane.
  • dostęp do encji wewnętrznych można uzyskać w dowolnym miejscu celu, w którym zostały zdefiniowane.
  • do podmiotów publicznych można uzyskać dostęp z dowolnego miejsca w celu i z dowolnego innego kontekstu, który importuje moduł bieżącego celu.

Domyślna wartość domyślna to internal, więc w obrębie celu aplikacji możesz pozostawić modyfikatory dostępu wyłączone, chyba że chcesz być bardziej restrykcyjny. W celu struktury (np. Jeśli osadzasz platformę do udostępniania kodu między aplikacją a rozszerzeniem udostępniania lub widoku Dzisiaj), użyj publicdo wyznaczenia interfejsu API, który chcesz udostępnić klientom twojej struktury.


Cóż, ta odpowiedź była poprawna w poprzednich wersjach Swift, wydaje się, że nie jest już ważna :) proszę sprawdzić moją odpowiedź .
Ahmad F

6

Swift 3.0 zapewnia pięć różnych kontroli dostępu:

  1. otwarty
  2. publiczny
  3. wewnętrzny
  4. fileprivate
  5. prywatny

Otwarty dostęp i publiczny dostęp umożliwiają stosowanie encji w dowolnym pliku źródłowym z ich modułu definiującego, a także w pliku źródłowym z innego modułu, który importuje moduł definiujący. Zwykle używasz dostępu otwartego lub publicznego podczas określania publicznego interfejsu do frameworka.

Dostęp wewnętrzny umożliwia stosowanie encji w dowolnym pliku źródłowym z ich modułu definiującego, ale nie w żadnym pliku źródłowym poza tym modułem. Zwykle używasz dostępu wewnętrznego podczas definiowania wewnętrznej struktury aplikacji lub frameworka.

Dostęp do prywatnego pliku ogranicza użycie encji do własnego pliku źródłowego definiującego. Użyj dostępu do pliku prywatnego, aby ukryć szczegóły implementacji określonego elementu funkcjonalności, gdy są one używane w całym pliku.

Prywatny dostęp ogranicza użycie jednostki do załączonej deklaracji. Użyj prywatnego dostępu, aby ukryć szczegóły implementacji określonego elementu funkcjonalności, gdy szczegóły te są używane tylko w ramach jednej deklaracji.

Dostęp otwarty to najwyższy (najmniej restrykcyjny) poziom dostępu, a dostęp prywatny to najniższy (najbardziej restrykcyjny) poziom dostępu.

Domyślne poziomy dostępu

Wszystkie podmioty w twoim kodzie (z kilkoma wyjątkami) mają domyślny poziom dostępu wewnętrznego, jeśli sam nie określisz jawnego poziomu dostępu. W rezultacie w wielu przypadkach nie trzeba określać jawnego poziomu dostępu w kodzie.

Informacja o wersji na ten temat:

Klasy zadeklarowane jako publiczne nie mogą już być podklasowane poza ich modułem definiującym, a metody zadeklarowane jako publiczne nie mogą już być zastępowane poza ich modułem definiującym. Aby umożliwić klasę zewnętrzną podklasę lub metodę zewnętrzną przesłaniania, zadeklaruj je jako otwarte, co stanowi nowy poziom dostępu poza publicznym. Zaimportowane klasy i metody Objective-C są teraz importowane jako otwarte, a nie publiczne. Testy jednostkowe, które importują moduł za pomocą importu @testable, nadal będą mogły podklasować klasy publiczne lub wewnętrzne, a także zastępować metody publiczne lub wewnętrzne. (SE-0117)

Więcej informacji i szczegółów: Swift Programming Language (kontrola dostępu)


Cóż, ta odpowiedź była poprawna w poprzednich wersjach Swift, wydaje się, że nie jest już ważna :) proszę sprawdzić moją odpowiedź .
Ahmad F

4

W wersji Beta 6 dokumentacja stwierdza, że ​​istnieją trzy różne modyfikatory dostępu:

  • Publiczny
  • Wewnętrzny
  • Prywatny

Te trzy dotyczą klas, protokołów, funkcji i właściwości.

public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}

Aby uzyskać więcej informacji, sprawdź kontrolę dostępu .


Powinien istnieć chroniony modyfikator, który ułatwia tworzenie klas z większym bezpieczeństwem.
Kumar C

Cóż, ta odpowiedź była poprawna w poprzednich wersjach Swift, wydaje się, że nie jest już ważna :) proszę sprawdzić moją odpowiedź .
Ahmad F

2

Teraz w wersji beta 4 dodali modyfikatory dostępu do Swift.

z notatek dotyczących aktualizacji Xcode 6 beta 4 :

Szybka kontrola dostępu ma trzy poziomy dostępu:

  • private do encji można uzyskać dostęp tylko z pliku źródłowego, w którym zostały zdefiniowane.
  • internal do encji można uzyskać dostęp w dowolnym miejscu celu, w którym zostały zdefiniowane.
  • public do encji można uzyskać dostęp z dowolnego miejsca w celu i z dowolnego innego kontekstu, który importuje moduł bieżącego celu.

Domyślnie większość podmiotów w pliku źródłowym ma dostęp wewnętrzny. Dzięki temu programiści aplikacji mogą w dużej mierze ignorować kontrolę dostępu, jednocześnie umożliwiając twórcom frameworków pełną kontrolę nad interfejsem API frameworka.


Czy możesz zamieścić link do tego?
Bałwan

Cóż, ta odpowiedź była poprawna w poprzednich wersjach Swift, wydaje się, że nie jest już ważna :) proszę sprawdzić moją odpowiedź .
Ahmad F

2

Mechanizmy kontroli dostępu wprowadzone w Xcode 6 :

Swift zapewnia trzy różne poziomy dostępu dla encji w kodzie. Te poziomy dostępu odnoszą się do pliku źródłowego, w którym zdefiniowana jest jednostka, a także do modułu, do którego należy plik źródłowy.

  • Dostęp publiczny umożliwia stosowanie encji w dowolnym pliku źródłowym z ich modułu definiującego, a także w pliku źródłowym z innego modułu, który importuje moduł definiujący. Zwykle używasz publicznego dostępu podczas określania publicznego interfejsu do frameworka.
  • Dostęp wewnętrzny umożliwia stosowanie encji w dowolnym pliku źródłowym z ich modułu definiującego, ale nie w żadnym pliku źródłowym poza tym modułem. Zwykle używasz dostępu wewnętrznego podczas definiowania wewnętrznej struktury aplikacji lub frameworka.
  • Prywatny dostęp ogranicza użycie encji do własnego pliku źródłowego. Użyj prywatnego dostępu, aby ukryć szczegóły implementacji określonego elementu funkcjonalności.

Dostęp publiczny to najwyższy (najmniej restrykcyjny) poziom dostępu, a dostęp prywatny to najniższy (lub najbardziej restrykcyjny) poziom dostępu.

Domyślnie akceptuje go wewnętrznie i jako takie nie musi być określone. Zauważ też, że prywatny specyfikator nie działa na poziomie klasy, ale na poziomie pliku źródłowego. Oznacza to, że aby części klasy były naprawdę prywatne, musisz podzielić je na własny plik. Wprowadza to również kilka interesujących przypadków dotyczących testów jednostkowych ...

Innym stwierdzeniem, które skomentowałem w powyższym linku, jest to, że nie można „uaktualnić” poziomu dostępu. Jeśli podklasujesz coś, możesz to bardziej ograniczyć, ale nie na odwrót.

Ten ostatni bit wpływa również na funkcje, krotki i na pewno inne rzeczy w taki sposób, że jeśli np. Funkcja wykorzystuje klasę prywatną , to nie jest ważne, aby funkcja była wewnętrzna lub publiczna , ponieważ mogą nie mieć dostępu do klasy prywatnej . Powoduje to ostrzeżenie kompilatora i konieczne jest ponowne określenie funkcji jako funkcji prywatnej .


Cóż, ta odpowiedź była poprawna w poprzednich wersjach Swift, wydaje się, że nie jest już ważna :) proszę sprawdzić moją odpowiedź .
Ahmad F

2

Swift 3 i 4 przyniosły wiele zmian również dla poziomów dostępu do zmiennych i metod. Swift 3 i 4 mają teraz 4 różne poziomy dostępu, gdzie dostęp otwarty / publiczny jest najwyższym (najmniej restrykcyjnym) poziomem dostępu, a dostęp prywatny jest najniższym (najbardziej restrykcyjnym) poziomem dostępu:

  • do funkcji prywatnych i członków można uzyskać dostęp wyłącznie z zakresu samego bytu (struct, klasa,…) i jego rozszerzeń (w Swift 3 rozszerzenia również były ograniczone)
  • do funkcji i elementów fileprivate można uzyskać dostęp tylko z pliku źródłowego, w którym zostały zadeklarowane.
  • do funkcji wewnętrznych i członków (co jest domyślne, jeśli nie dodasz wyraźnie słowa kluczowego poziomu dostępu) można uzyskać dostęp w dowolnym miejscu celu, w którym są zdefiniowane. Właśnie dlatego TestTarget nie ma automatycznego dostępu do wszystkich źródeł, należy je oznaczyć jako dostępne w inspektorze plików xCode.
  • do otwartych lub publicznych funkcji i członków można uzyskać dostęp z dowolnego miejsca w celu i z dowolnego innego kontekstu, który importuje moduł bieżącego celu.

Ciekawy:

Zamiast oznaczać każdą metodę lub członka jako „prywatny”, możesz uwzględnić niektóre metody (np. Zwykle funkcje pomocnicze) w rozszerzeniu klasy / struktury i oznaczyć całe rozszerzenie jako „Prywatne”.

class foo { }

private extension foo {
    func somePrivateHelperFunction01() { }
    func somePrivateHelperFunction02() { }
    func somePrivateHelperFunction03() { }
}

To może być dobry pomysł, aby uzyskać łatwiejszy do utrzymania kod. I możesz łatwo zmienić (np. Do testowania jednostkowego) na nieprywatne, zmieniając tylko jedno słowo.

Dokumentacja Apple


Cóż, ta odpowiedź była poprawna w poprzednich wersjach Swift, wydaje się, że nie jest już ważna :) proszę sprawdzić moją odpowiedź .
Ahmad F

2

W przypadku Swift 1-3:

Nie, to niemożliwe. Nie ma żadnych prywatnych / chronionych metod i zmiennych.

Wszystko jest publiczne.

Aktualizacja Od wersji Swift 4 można zobaczyć inne odpowiedzi w tym wątku


1
Ten komentarz jest poprawny dla bieżącego materiału siewnego.
Jesper

2
Dla aktualnego materiału siewnego. Pojawi się w przyszłości .
Jesper

1
„publiczne” / „chronione” / „prywatne” obecnie nie istnieją, ale można ukryć różne rzeczy za pomocą zamknięć, protokołów i klas wewnętrznych - to trochę przypomina wzorzec modułu często używany w JavaScript. Zobacz mój przykładowy kod w mojej odpowiedzi tutaj, aby zobaczyć, jak to zrobić. Jeśli się mylę co do tego, jak to działa, a mój przykład jest niepoprawny, proszę to zaznaczyć, ponieważ wciąż się uczę. :)
Dave Kapp

Wygląda na to, że nie jest już ważny :) sprawdź moją odpowiedź .
Ahmad F

1

Jedną z opcji, których możesz użyć, jest zawinięcie tworzenia instancji do funkcji i dostarczenie odpowiednich programów pobierających i ustawiających w konstruktorze:

class Counter {
    let inc: () -> Int
    let dec: () -> Int

    init(start: Int) {
        var n = start

        inc = { ++n }
        dec = { --n }
    }
}


let c = Counter(start: 10)

c.inc()  // 11
c.inc()  // 12
c.dec()  // 11

0

Gramatyki języka nie ma słowa kluczowe „publiczny”, „prywatny” lub „chronione”. Sugerowałoby to, że wszystko jest publiczne. Oczywiście mogłaby istnieć alternatywna metoda określania modyfikatorów dostępu bez tych słów kluczowych, ale nie mogłem jej znaleźć w odnośniku językowym.


0

Mam nadzieję, że zaoszczędzisz trochę czasu tym, którzy chcą czegoś podobnego do chronionych metod:

Podobnie jak w przypadku innych odpowiedzi, swift zapewnia teraz „prywatny” modyfikator - który jest zdefiniowany pod względem plików, a nie pod względem klasy, na przykład w Javie lub C #. Oznacza to, że jeśli chcesz metod chronionych, możesz to zrobić za pomocą szybkich metod prywatnych, jeśli są one w tym samym pliku

  1. Utwórz klasę podstawową do przechowywania metod „chronionych” (właściwie prywatnych)
  2. Podklasuj tę klasę, aby używać tych samych metod
  3. W innych plikach nie można uzyskać dostępu do metod klasy bazowej, nawet w przypadku podklasy

np. plik 1:

class BaseClass {
    private func protectedMethod() {

    }
}

class SubClass : BaseClass {
    func publicMethod() {
        self.protectedMethod()  //this is ok as they are in same file
    }
}

Plik 2:

func test() {
    var a = BaseClass()
    a.protectedMethod() //ERROR


    var b = SubClass()
    b.protectedMethod() //ERROR
}

class SubClass2 : BaseClass {
    func publicMethod() {
        self.protectedMethod() //ERROR
    }

}



-2

do wersji 2.0 istniały tylko trzy poziomy dostępu [publiczny, wewnętrzny, prywatny], ale w swift 3.0 Apple dodało dwa nowe poziomy dostępu, które są [Open, fileType], więc teraz w swift 3.0 jest 5 poziom dostępu Tutaj chcę wyczyścić rolę z tych dwóch poziomów dostępu 1. Otwarty: jest to bardzo podobne do Publicznego, ale jedyna różnica polega na tym, że Publiczny może uzyskać dostęp do podklasy i zastąpić, a Otwarty poziom dostępu nie może uzyskać dostępu do tego, że to zdjęcie pochodzi ze strony internetowej Średni i opisuje różnicę między dostępem otwartym a publicznym

Teraz na drugi nowy poziom dostępu 2. typ pliku jest większą wersją prywatnego lub mniejszym poziomem dostępu niż wewnętrzny FileType może uzyskać dostęp do rozszerzonej części [klasy, struktury, wyliczenia], a prywatny nie może uzyskać dostępu do rozszerzonej części kodu, do którego może uzyskać dostęp tylko zakres leksykalny to zdjęcie pochodzi ze strony Medium i opisuje różnicę między typem pliku a poziomem dostępu prywatnego

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.