Swift a-t-il des modificateurs d'accès?

273

Dans l'instance Objective-C, les données peuvent être public, protectedou private. Par exemple:

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

Je n'ai trouvé aucune mention de modificateurs d'accès dans la référence Swift. Est-il possible de limiter la visibilité des données dans Swift?

Gergo Erdosi
la source
Moi non plus. Apple devrait au moins introduire l'étiquette pour les particuliers, comme en python, ils sont préfixés par un trait de soulignement.
Ciantic
Ajout d'une réponse mise à jour pour la version finale de Xcode 6.1.1
holroy
Swift 4 mise à jour de la réponse .
Ahmad F

Réponses:

419

Depuis Swift 3.0.1 , il existe 4 niveaux d'accès , décrits ci-dessous, du plus élevé (le moins restrictif) au plus bas (le plus restrictif).


1. openetpublic

Activer une entité à utiliser en dehors du module de définition (cible). Vous utilisez openou publicaccédez généralement lors de la spécification de l'interface publique d'un framework.

Cependant, l' openaccès s'applique uniquement aux classes et aux membres de la classe , et il diffère de l' publicaccès comme suit:

  • public les classes et les membres de classe peuvent uniquement être sous-classés et remplacés dans le module de définition (cible).
  • open Les classes et les membres de classe peuvent être sous-classés et remplacés à l'intérieur et à l'extérieur du module de définition (cible).

// 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

Permet à une entité d'être utilisée dans le module de définition (cible). Vous utilisez généralement l' internalaccès lors de la définition de la structure interne d'une application ou d'un framework.

// 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

Limite l'utilisation d'une entité à son fichier source de définition. Vous utilisez généralement l' fileprivateaccès pour masquer les détails d'implémentation d'une fonctionnalité spécifique lorsque ces détails sont utilisés dans un fichier entier.

// 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

Restreint l'utilisation d'une entité à sa déclaration englobante. Vous utilisez généralement l' privateaccès pour masquer les détails d'implémentation d'une fonctionnalité spécifique lorsque ces détails ne sont utilisés que dans une seule déclaration.

// First.framework – A.swift

internal struct A {

    private static let x: Int

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

}

A.x // error: x is unavailable
akashivskyy
la source
37
Quelqu'un pourrait-il m'expliquer pourquoi ce n'est pas un gros problème?
Zaky German
15
Il existe toujours certaines méthodes ou variables dans la POO qui doivent être privées ou protégées. Cela permet d'implémenter la conception SOLIDE , car les grandes méthodes sont divisées en plusieurs plus petites, chacune ayant sa propre responsabilité, qui peuvent être remplacées, mais seule la méthode "principale" doit être disponible pour un usage public.
akashivskyy
19
Personnellement, je n'aime pas les solutions comme celle avec les méthodes "privées" de soulignement / caractère spécial. Même s'il est garanti que je serai la seule personne à avoir regardé ce code, cela rend le code plus sauvegardé / moins sujet aux erreurs car le compilateur vous empêchera simplement de faire des choses que vous ne devriez pas faire. Je pense donc qu'ils devraient sortir les "mécanismes de contrôle d'accès" le plus rapidement possible, afin que les gens ne s'habituent pas aux mauvaises habitudes.
Jonas Eschmann
10
Les notes de version bêta de Xcode 6 disent: "Le contrôle d'accès (membres publics / privés) n'est pas activé dans cette graine. (15747445)"
Martin Ullrich
9
@alcalde L'idée d'une interface publique est très précieuse. Si vous prévoyez que tout le code d'une classe doit résider dans des fonctions qui font partie de l'API publique, je pense que c'est assez limitant. D'un autre côté, avoir une API publique spécifiée permet à l'implémentation de changer (y compris l'utilisation de méthodes privées) sans perturber les consommateurs. Si quelqu'un «a besoin» d'utiliser une méthode de classe interne, je pense qu'il comprend mal les limites de la fonctionnalité de la classe (ou essaie d'utiliser une classe buggy).
jinglesthula
26

Swift 4 / Swift 5

Comme mentionné dans la documentation Swift - Contrôle d'accès , Swift dispose de 5 contrôles d'accès :

  • ouvert et public : accessible depuis les entités de leur module et toutes les entités de module qui importent le module de définition.

  • interne : accessible uniquement depuis les entités de leur module. Il s'agit du niveau d'accès par défaut.

  • fileprivate et privé : accessible uniquement dans un cadre limité dans une portée limitée où vous les définissez.



Quelle est la différence entre ouvert et public ?

ouvert est le même que public dans les versions précédentes de Swift, ils permettent aux classes d'autres modules de les utiliser et de les hériter, c'est-à-dire: ils peuvent être sous-classés à partir d'autres modules. En outre, ils permettent aux membres d'autres modules de les utiliser et de les remplacer. La même logique vaut pour leurs modules.

public autorise les classes d'autres modules à les utiliser, mais pas à les hériter, c'est-à-dire qu'elles ne peuvent pas être sous-classées à partir d'autres modules. En outre, ils permettent aux membres d'autres modules de les utiliser, mais PAS de les remplacer. Pour leurs modules, ils ont la même logique d'ouverture (ils permettent aux classes de les utiliser et de les hériter; Ils permettent aux membres de les utiliser et de les remplacer).


Quelle est la différence entre fileprivate et private ?

fileprivate est accessible à partir de leurs fichiers entiers.

private n'est accessible qu'à partir de leur déclaration unique et aux extensions de cette déclaration qui se trouvent dans le même fichier; Par exemple:

// 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!"
    }
}



Quelles sont les différences entre Swift 3 et Swift 4 Access Control?

Comme mentionné dans la proposition SE-0169 , le seul raffinement ajouté à Swift 4 est que la portée du contrôle d'accès privé a été étendue pour être accessible à partir des extensions de cette déclaration dans le même fichier; Par exemple:

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!
    }
}

Il n'est donc pas nécessaire de déclarer myMessagecomme fichier privé pour être accessible dans tout le fichier.

Ahmad F
la source
17

Quand on parle de faire une "méthode privée" dans Swift ou ObjC (ou ruby ​​ou java ou…) ces méthodes ne sont pas vraiment privées. Il n'y a aucun contrôle d'accès réel autour d'eux. Tout langage qui offre même un peu d'introspection permet aux développeurs d'accéder à ces valeurs en dehors de la classe s'ils le souhaitent vraiment.

Donc, ce dont nous parlons vraiment ici est un moyen de définir une interface publique qui présente simplement les fonctionnalités que nous voulons, et "cache" le reste que nous considérons comme "privé".

Le mécanisme Swift pour déclarer les interfaces est le protocol, et il peut être utilisé à cette fin.

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)"
  }
}

N'oubliez pas que les protocoles sont des types de première classe et peuvent être utilisés partout où un type le peut. Et , lorsqu'ils sont utilisés de cette façon, ils exposent uniquement leurs propres interfaces, pas celles du type d'implémentation.

Ainsi, tant que vous utilisez MyClassau lieu de MyClassImplementationdans vos types de paramètres, etc., cela devrait tout simplement fonctionner:

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

Il y a des cas d'affectation directe où vous devez être explicite avec le type au lieu de compter sur Swift pour le déduire, mais cela ne semble guère être un facteur de rupture:

var myClass:MyClass = MyClassImplementation()

L'utilisation de protocoles de cette façon est sémantique, raisonnablement concise et, à mes yeux, ressemble beaucoup aux extensions de classe que nous avons utilisées à cet effet dans ObjC.

jemmons
la source
1
Si les protocoles ne nous permettent pas d'avoir un argument par défaut, comment puis-je créer une méthode publique avec des paramètres facultatifs qui est toujours conforme au protocole?
bdurao
Je ne comprends pas ce que tu veux dire. Ce qui suit crée une méthode publique avec un paramètre facultatif. Il ne semble pas y avoir de problème: gist.github.com/anonymous/17d8d2d25a78644046b6
jemmons
Pour une raison quelconque, le paramètre facultatif ne fonctionne pas comme il se doit sur mon projet, avait déjà essayé quelque chose de similaire à votre exemple GitHub. Comme nous ne pouvons pas définir un paramètre par défaut sur un protocole, je suis resté bloqué et j'ai fini par poser une question. Merci d'avoir essayé d'aider.
bdurao
Nous savons tous que tout est piratable. Nous avons juste besoin d'un ordre pour savoir pourquoi nous avons besoin de modificateurs d'accès
canbax
14

Pour autant que je sache, il n'y a pas de mots clés «public», «privé» ou «protégé». Cela suggère que tout est public.

Cependant, Apple peut s'attendre à ce que les gens utilisent des « protocoles » (appelés interfaces par le reste du monde) et le modèle de conception d'usine pour masquer les détails du type d'implémentation.

C'est souvent un bon modèle de conception à utiliser de toute façon; car il vous permet de modifier la hiérarchie de votre classe d' implémentation , tout en conservant le même système de type logique .

Ian Ringrose
la source
C'est bien car cela réduit également le couplage et peut faciliter les tests.
Scroog1
4
Cela fonctionnerait mieux s'il y avait un moyen de cacher la classe d'implémentation du protocole, mais il ne semble pas y en avoir.
David Moles
Quelqu'un peut-il fournir un exemple illustratif de ce modèle?
bloudermilk
Eh bien, cette réponse était valide dans les versions précédentes de Swift, il semble qu'elle ne soit plus valide :) veuillez vérifier ma réponse .
Ahmad F
12

En utilisant une combinaison de protocoles, de fermetures et de classes imbriquées / internes, il est possible d'utiliser quelque chose dans le sens du modèle de module pour masquer les informations dans Swift en ce moment. Ce n'est pas super propre ou agréable à lire mais ça marche.

Exemple:

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 et mysteriousMath sont cachés ici à l'extérieur et une tentative de creuser votre chemin dans l'objet devrait entraîner une erreur.

Je ne suis qu'une partie du chemin dans ma lecture des documents Swift, donc s'il y a un défaut ici, veuillez le signaler, j'aimerais savoir.

Dave Kapp
la source
ok, j'ai aussi pensé à cette solution, mais expliquez-moi pourquoi je ne peux pas accéder à h.huh.innerVal?
Sam
Swift est sûr pour les caractères et la seule chose que le monde extérieur sait sur h est qu'il est conforme à HuhThing. HuhThing n'inclut aucune information sur une propriété appelée innerVal et donc tenter d'y accéder est une erreur.
Dave Kapp
8
Toujours accessible: Preflect(h)[0].1.value // 19
John Estropia
2
Belle trouvaille là John - je n'étais pas au courant de réfléchir. Semble transformer des objets en tuples - existe-t-il une documentation officielle sur cette fonction ou d'autres éléments de métaprogrammation dans Swift? J'ai jeté un œil au guide linguistique sur iBooks mais je ne le vois pas.
Dave Kapp
1
@JohnEstropia Je ne pense pas que la réflexion compte. En Java (un langage plus mature), il existe des modificateurs d'accès, mais ils n'empêchent pas non plus les astuces de réflexion.
11684
10

Depuis Xcode 6 beta 4, Swift dispose de modificateurs d'accès. D'après les notes de version:

Le contrôle d'accès Swift a trois niveaux d'accès:

  • les entités privées ne sont accessibles qu'à partir du fichier source où elles sont définies.
  • les entités internes sont accessibles n'importe où dans la cible où elles sont définies.
  • les entités publiques sont accessibles depuis n'importe où dans la cible et depuis tout autre contexte qui importe le module de la cible actuelle.

La valeur implicite par défaut est internal, donc dans une cible d'application, vous pouvez laisser les modificateurs d'accès désactivés, sauf là où vous voulez être plus restrictif. Dans une cible de cadre (par exemple, si vous intégrez un cadre pour partager du code entre une application et une extension de partage ou de vue Aujourd'hui), utilisez publicpour désigner l'API que vous souhaitez exposer aux clients de votre cadre.

rickster
la source
Eh bien, cette réponse était valide dans les versions précédentes de Swift, il semble qu'elle ne soit plus valide :) veuillez vérifier ma réponse .
Ahmad F
6

Swift 3.0 propose cinq contrôles d'accès différents:

  1. ouvert
  2. Publique
  3. interne
  4. fileprivate
  5. privé

Le libre accès et l' accès public permettent aux entités d'être utilisées dans n'importe quel fichier source de leur module de définition, ainsi que dans un fichier source d'un autre module qui importe le module de définition. Vous utilisez généralement un accès ouvert ou public lors de la spécification de l'interface publique d'un framework.

L' accès interne permet aux entités d'être utilisées dans n'importe quel fichier source de leur module de définition, mais pas dans aucun fichier source en dehors de ce module. Vous utilisez généralement l'accès interne lors de la définition de la structure interne d'une application ou d'un framework.

L' accès privé au fichier limite l'utilisation d'une entité à son propre fichier source de définition. Utilisez un accès privé au fichier pour masquer les détails d'implémentation d'une fonctionnalité spécifique lorsque ces détails sont utilisés dans un fichier entier.

L' accès privé limite l'utilisation d'une entité à la déclaration jointe. Utilisez un accès privé pour masquer les détails d'implémentation d'une fonctionnalité spécifique lorsque ces détails ne sont utilisés que dans une seule déclaration.

L' accès ouvert est le niveau d'accès le plus élevé (le moins restrictif) et l' accès privé est le niveau d'accès le plus bas (le plus restrictif).

Niveaux d'accès par défaut

Toutes les entités de votre code (à quelques exceptions spécifiques près) ont un niveau d'accès par défaut interne si vous ne spécifiez pas vous-même un niveau d'accès explicite. Par conséquent, dans de nombreux cas, vous n'avez pas besoin de spécifier un niveau d'accès explicite dans votre code.

La note de sortie sur le sujet:

Les classes déclarées comme publiques ne peuvent plus être sous-classées en dehors de leur module de définition, et les méthodes déclarées comme publiques ne peuvent plus être remplacées en dehors de leur module de définition. Pour autoriser une classe à être sous-classée en externe ou une méthode à remplacer en externe, déclarez-les comme ouvertes, ce qui est un nouveau niveau d'accès au-delà de public. Les classes et méthodes Objective-C importées sont désormais toutes importées comme ouvertes plutôt que publiques. Les tests unitaires qui importent un module à l'aide d'une importation @testable seront toujours autorisés à sous-classer les classes publiques ou internes ainsi qu'à remplacer les méthodes publiques ou internes. (SE-0117)

Plus d'informations et de détails: le langage de programmation Swift (contrôle d'accès)

PleurerHippopotame
la source
Eh bien, cette réponse était valide dans les versions précédentes de Swift, il semble qu'elle ne soit plus valide :) veuillez vérifier ma réponse .
Ahmad F
4

Dans la version bêta 6, la documentation indique qu'il existe trois modificateurs d'accès différents:

  • Publique
  • Interne
  • Privé

Et ces trois s'appliquent aux classes, protocoles, fonctions et propriétés.

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

Pour en savoir plus, consultez Contrôle d'accès .

OliverAssad
la source
Il aurait dû y avoir un modificateur protégé qui facilite la création de classes avec une plus grande sécurité.
Kumar C
Eh bien, cette réponse était valide dans les versions précédentes de Swift, il semble qu'elle ne soit plus valide :) veuillez vérifier ma réponse .
Ahmad F
2

Maintenant en version bêta 4, ils ont ajouté des modificateurs d'accès à Swift.

de Xcode 6 beta 4 realese notes :

Le contrôle d'accès Swift a trois niveaux d'accès:

  • private les entités ne sont accessibles qu'à partir du fichier source où elles sont définies.
  • internal les entités sont accessibles n'importe où dans la cible où elles sont définies.
  • public les entités sont accessibles depuis n'importe où dans la cible et depuis tout autre contexte qui importe le module de la cible actuelle.

Par défaut, la plupart des entités d'un fichier source ont un accès interne. Cela permet aux développeurs d'applications d'ignorer en grande partie le contrôle d'accès tout en permettant aux développeurs de framework un contrôle total sur l'API d'un framework.

Alexey Globchastyy
la source
Pouvez-vous publier un lien vers cela?
Snowman
Eh bien, cette réponse était valide dans les versions précédentes de Swift, il semble qu'elle ne soit plus valide :) veuillez vérifier ma réponse .
Ahmad F
2

Mécanismes de contrôle d'accès tels qu'introduits dans Xcode 6 :

Swift propose trois niveaux d'accès différents pour les entités de votre code. Ces niveaux d'accès sont relatifs au fichier source dans lequel une entité est définie, et également au module auquel appartient le fichier source.

  • L'accès public permet aux entités d'être utilisées dans n'importe quel fichier source de leur module de définition, ainsi que dans un fichier source d'un autre module qui importe le module de définition. Vous utilisez généralement l'accès public lors de la spécification de l'interface publique d'un framework.
  • L'accès interne permet aux entités d'être utilisées dans n'importe quel fichier source de leur module de définition, mais pas dans un fichier source en dehors de ce module. Vous utilisez généralement l'accès interne lors de la définition de la structure interne d'une application ou d'un framework.
  • L'accès privé limite l'utilisation d'une entité à son propre fichier source de définition. Utilisez un accès privé pour masquer les détails d'implémentation d'une fonctionnalité spécifique.

L'accès public est le niveau d'accès le plus élevé (le moins restrictif) et l'accès privé est le niveau d'accès le plus bas (ou le plus restrictif).

L'accès par défaut est interne et n'a donc pas besoin d'être spécifié. Notez également que le spécificateur privé ne fonctionne pas au niveau de la classe, mais au niveau du fichier source. Cela signifie que pour obtenir des parties d'une classe vraiment privées, vous devez les séparer dans un fichier qui lui est propre. Cela introduit également quelques cas intéressants en ce qui concerne les tests unitaires ...

Un autre point que j'ai souligné, qui est commenté dans le lien ci-dessus, est que vous ne pouvez pas «mettre à niveau» le niveau d'accès. Si vous sous-classe quelque chose, vous pouvez le restreindre davantage, mais pas l'inverse.

Ce dernier bit affecte également les fonctions, les tuples et sûrement d'autres choses dans le sens où si par exemple une fonction utilise une classe privée , alors il n'est pas valide d'avoir la fonction interne ou publique , car ils pourraient ne pas avoir accès à la classe privée . Cela entraîne un avertissement du compilateur et vous devez redéclarer la fonction en tant que fonction privée .

holroy
la source
Eh bien, cette réponse était valide dans les versions précédentes de Swift, il semble qu'elle ne soit plus valide :) veuillez vérifier ma réponse .
Ahmad F
2

Swift 3 et 4 ont également apporté beaucoup de changements pour les niveaux d'accès des variables et des méthodes. Swift 3 et 4 ont maintenant 4 niveaux d'accès différents, où l' accès ouvert / public est le niveau d'accès le plus élevé (le moins restrictif) et l' accès privé est le niveau d'accès le plus bas (le plus restrictif):

  • les fonctions et membres privés ne sont accessibles que dans le cadre de l'entité elle-même (struct, classe,…) et de ses extensions (dans Swift 3 également les extensions étaient restreintes)
  • Les fonctions et membres de fileprivate ne sont accessibles que depuis le fichier source où ils sont déclarés.
  • les fonctions et membres internes (qui sont la valeur par défaut si vous n'ajoutez pas explicitement un mot clé de niveau d'accès) sont accessibles n'importe où dans la cible où ils sont définis. C'est pourquoi le TestTarget n'a pas automatiquement accès à toutes les sources, elles doivent être marquées comme accessibles dans l'inspecteur de fichiers de xCode.
  • les fonctions et membres ouverts ou publics sont accessibles depuis n'importe où dans la cible et depuis tout autre contexte qui importe le module de la cible actuelle.

Intéressant:

Au lieu de marquer chaque méthode ou membre comme "privé", vous pouvez couvrir certaines méthodes (par exemple, généralement les fonctions d'assistance) dans une extension d'une classe / structure et marquer l'extension entière comme "privée".

class foo { }

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

Cela peut être une bonne idée, afin d'obtenir un meilleur code maintenable. Et vous pouvez facilement passer (par exemple pour les tests unitaires) à non privé en changeant simplement un mot.

Documentation Apple

LukeSideWalker
la source
Eh bien, cette réponse était valide dans les versions précédentes de Swift, il semble qu'elle ne soit plus valide :) veuillez vérifier ma réponse .
Ahmad F
2

Pour Swift 1-3:

Non, ce n'est pas possible. Il n'y a pas du tout de méthodes et de variables privées / protégées.

Tout est public.

Mise à jour depuis Swift 4, il est possible voir d' autres réponses dans ce fil

Sam
la source
1
Ce commentaire est exact pour la graine actuelle.
Jesper
2
Pour la graine actuelle. Il apparaîtra à l'avenir .
Jesper
1
"public" / "protected" / "private" n'existe pas actuellement, mais vous pouvez masquer des choses en utilisant des fermetures, des protocoles et des classes internes - cela ressemble un peu au modèle de module couramment utilisé en JavaScript. Veuillez voir mon exemple de code sur ma réponse ici pour un exemple de la façon de procéder. Si je me trompe sur la façon dont cela fonctionne et que mon exemple est incorrect, veuillez le signaler car j'apprends encore. :)
Dave Kapp
Il semble que ce ne soit plus valable :) veuillez vérifier ma réponse .
Ahmad F
1

L'une des options que vous pourriez utiliser consiste à encapsuler la création d'instance dans une fonction et à fournir les getters et setters appropriés dans un constructeur:

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
Bartosz Ciechanowski
la source
0

La grammaire linguistique n'a pas les mots-clés «public», «privé» ou «protégé». Cela suggère que tout est public. Bien sûr, il pourrait y avoir une autre méthode pour spécifier les modificateurs d'accès sans ces mots clés, mais je ne pouvais pas le trouver dans la référence du langage.

Scroog1
la source
0

Espérons pouvoir gagner du temps pour ceux qui veulent quelque chose de semblable aux méthodes protégées:

Comme pour les autres réponses, swift fournit désormais le modificateur «privé» - qui est défini par fichier plutôt que par classe, comme ceux de Java ou C # par exemple. Cela signifie que si vous voulez des méthodes protégées, vous pouvez le faire avec des méthodes privées rapides si elles sont dans le même fichier

  1. Créer une classe de base pour contenir les méthodes «protégées» (en fait privées)
  2. Sous-classe cette classe pour utiliser les mêmes méthodes
  3. Dans d'autres fichiers, vous ne pouvez pas accéder aux méthodes de classe de base, même lorsque vous sous-classe soit

par exemple, fichier 1:

class BaseClass {
    private func protectedMethod() {

    }
}

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

Fichier 2:

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


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

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

}

james_alvarez
la source
-2

jusqu'à swift 2.0, il n'y avait que trois niveaux d'accès [Public, interne, privé] mais dans swift 3.0 apple a ajouté deux nouveaux niveaux d'accès qui sont [Open, fileType] alors maintenant dans swift 3.0 il y a 5 niveaux d'accès Ici, je veux effacer le rôle de ces deux niveaux d'accès 1. Ouvert: ceci est très similaire à Public mais la seule différence est que le Public peut accéder à la sous-classe et remplacer, et le niveau d'accès Ouvert ne peut pas accéder à cette image est prise à partir du site Web Medium et cela décrit la différence entre accès ouvert et public

Passons maintenant au deuxième nouveau niveau d'accès 2. filetype est une version plus grande du niveau d'accès privé ou inférieur à celui interne Le fileType peut accéder à la partie étendue de [class, struct, enum] et private ne peut pas accéder à la partie étendue de code à laquelle il ne peut accéder l'étendue lexicale de cette image est tirée du site Web Medium et décrit la différence entre fileType et niveau d'accès privé

Dilip Tilonia
la source