In Swift zijn er vijf toegangsniveaus voor de leden van types (eigenschappen, methoden, enz.) en de types zelf:
open — maximale publiciteit. Kan zelfs buiten het module worden geërfd en overschreven.public — beschikbaar buiten het module, maar kan niet worden overschreven/geërfd.internal (standaard) — beschikbaar binnen het module.fileprivate — alleen beschikbaar binnen het bestand.private — alleen beschikbaar binnen de declaratie scope (extension is ook binnen deze scope).private voor logica die nergens buiten de declaratie zichtbaar mag zijn.fileprivate — als gegevensuitwisseling binnen één bestand vereist is (bijvoorbeeld tussen twee gerelateerde extensions).internal — de standaard voor alles dat publiek toegankelijk is binnen het module.public/open — voor API's die door andere modules/frameworks worden gebruikt.open class MyOpenClass {} public class MyPublicClass {} internal class InternalClass {} fileprivate class FilePrivateClass {} private class PrivateClass {}
Wat is het verschil tussen open en public bij het beschrijven van een klasse? Waarom zijn niet alle public klassen beschikbaar voor erfgenamen?
Antwoord:
open markeert een klasse/methode als beschikbaar voor overwriting en erven buiten zijn module. public opent alleen de toegang voor gebruik, maar staat geen erfgenamen buiten het module toe. Enerzijds beschermt dit de implementatie tegen ongewenste wijzigingen, anderzijds opent het alleen de noodzakelijke extensiepunten.
public class PublicClass {} open class OpenClass {} // In een ander module: class InheritFromOpen: OpenClass {} // OK class InheritFromPublic: PublicClass {} // Fout!
Verhaal
In de algemene bibliotheek was een klas gemarkeerd als public, en een extern project probeerde deze uit te breiden door methoden te overschrijven. Het project compileerde niet vanwege een verkeerd begrip van het verschil tussen public en open — dit kostte het team een extra week om de interface aan te passen.
Verhaal
Binnen één bestand werd geprobeerd toegang te krijgen tot een private-eigenschap vanuit een extension — maar de eigenschap was niet als fileprivate, maar als private gedeclareerd. Dit leidde tot een compilerfout die pas tijdens de integratiebuild werd opgemerkt.
Verhaal
In een applicatie met meerdere frameworks werden alle types als internal (standaard) gemarkeerd. Toen het nodig was om types tussen modules te gebruiken, was de interface niet beschikbaar — tientallen declaraties moesten naar public worden herschreven, wat extra tijd en testen kostte.