What is the Guiding Principle of Access Levels meaning in swift - swift

The Guiding Principle of Access Levels of swift is
No entity can be defined in terms of another entity that has a lower (more >restrictive) access level.
For example:
A public variable cannot be defined as having an internal or private type, because the type might not be available everywhere that the public variable is used.
A function cannot have a higher access level than its parameter types and return type, because the function could be used in situations where its constituent types are not available to the surrounding code.
could any body show me a code example about
A public variable cannot be defined as having an internal or private type, because the type might not be available everywhere that the public variable is used.
and
A function cannot have a higher access level than its parameter types and return type, because the function could be used in situations where its constituent types are not available to the surrounding code.
I don't know the clearly meaning of the principle of access level

Accessibility levels are, in increasing order:
private - only this file/class
internal - only this module
public - anybody
You can't use
private class Foo {
}
public var myFoo:Foo
because myFoo is visible outside the module but class Foo isn't, therefore anybody using myFoo wouldn't know what to do with it, how big it was, etc. If you change myFoo to private, then it's all good because anybody that has access to myFoo also has access to class Foo.
Likewise, you can't use:
private class Foo {
}
public func getMyFoo() -> Foo {...}
for the same reasons, the caller of getMyFoo doesn't (can't) know what Foo is, so has no way to properly deal with it.
Essentially if a type is private (or not public) then there can't be any external visibility of objects of that type.

Here are some simple examples:
internal protocol InternalProtocol { }
class MyClass {
// V~~~ This won't work, because InternalProtocol is internal, but the variable is public
public let myInternalProtocolVariable: InternalProtocol
// V~~~ This won't work because InternalProtocol is internal, but the function is public
public func publicFunc(ip: InternalProtocol) -> InternalProtocol {
return ip
}
}
The idea is that the caller of the function, or the object accessing the variable has to have access to the types that are used in the function or the variable.
If the user doesn't have access to InternalProtocol - i.e., they can't "see" it - then they shouldn't be able to "see" any variables or functions that use that type either.

Related

Why does nesting a class give the containing class access to the child class' protected data?

The question may be a bit confusing, and is best illustrated by an example:
unit Test
interface
type
TestClass = class()
Splitter1: TcxSplitter;
procedure SomeMethod();
end;
implementation
uses
cxSplitter;
// Locally-declared child type
type
TcxSplitterAccess = class(TcxSplitter);
procedure TestClass.SomeMethod()
var
pos: integer;
begin
// Access to protected field FPositionBeforeClose by casting
pos := TcxSplitterAccess(Splitter1).FPositionBeforeClose;
end;
Notice in the implementation section that there is a type TcxSplitterAccess being declared as a child of the TcxSplitter class. In the method SomeMethod(), belonging to the class TestClass, a TcxSplitter object is cast to the locally-declared TcxSplitterAccess class, and then a protected field is accessed on that object.
This is surprising to me as someone coming from a background of languages like Java, C++, C#, etc. In those languages, it is possible to access protected data in an object so long as you are doing it from within that object's type or an inherited type. For example, a method inside of a class ClazzA can access the private fields of other ClazzA objects since access is enforced at the type level rather than the instance level. Declaring a class locally in these languages would not give the containing class access to the local class' protected data (edit: As pointed out in the comments, this is actually not true at least for Java).
In this example, however, the type TestClass is directly accessing a protected field on the TcxSplitter object by first casting to the TcxSplitterAccess type. I am having trouble finding documentation on why this "trick" works. Does Delphi handle access levels fundamentally differently to Java-like languages and allows this sort of thing? Regardless, why does this trick work?
While I stumbled onto this behavior by using a nested, inherited class in order to access fields on the parent class (which breaks encapsulation, and I shouldn't do), the use of inheritance here is unnecessary. If the nested class did not inherit from a class, but instead had its own protected fields defined, TestClass would still be able to access those protected fields.
A unit has implicit-friendship semantics within itself. Types declared in the same unit are "friends" of each other (similar to friend in C++), and so can access each other's private and protected members (but not strict private or strict protected members).
So, in this case:
TcxSplitterAccess derives from TcxSplitter, so TcxSplitterAccess inherits all of the protected (but not private) members of TcxSplitter via normal class inheritance.
TestClass is declared in the same unit as TcxSplitterAccess, so TestClass has access to all of the protected members of TcxSplitterAccess, including the protected members of TcxSplitter (and the protected members of its ancestors).
FPositionBeforeClose is protected in TcxSplitter.
So, that is why TestClass.SomeMethod() is able to access FPositionBeforeClose when type-casting the Splitter1 object to TcxSplitterAccess.
This is covered by the Delphi documentation:
Private, Protected, Public, and Published Declarations
Classes and Objects (Delphi): Visibility of Class Members

Should I use public member of internal type?

I've been searching over access control guides and tutorials, but couldn't find any information.
Imagine you have some Swift module with class A implementation. This class is internal. It has some property, let's call it prop.
The question is: what changes if I set it's access level from internal to public?
internal class A {
public var prop: String?
}
I saw examples of such code, but don't understand, why. Is it just useful when you decide to make your type public, so you don't need to change access level of properties and methods? Or it has some other practical use like giving someone else access while the type is still internal?
As per Apple doc
A public variable cannot be defined as having an internal,
file-private, or private type, because the type might not be available
everywhere that the public variable is used.
More about Internal -
Internal access enables entities to be used within any source file
from their defining module, but not in any source file outside of that
module. You typically use internal access when defining an app’s or a
framework’s internal structure.
So no use of declared public inside internal class.
There is no difference in overall functionality: since your class is internal, it cannot be exposed in public members, say public var propA : A or public func f(a:A) so the fact that its members have public visibility makes no difference.
However, by using public you avoid repeating yourself: you have already designated the whole class internal, so you don't need to designate all its individual members as internal.
It also becomes helpful if you decide to convert the class to public at some later time, because you change only one internal modifier to public.

Property cannot be declared public because its type uses an internal type

I created two classes Content and Bucket. Bucket contains an array of Content objects and exposes that via a public property. However, when I do so, I receive the error:
Property cannot be declared public because its type uses an internal type
Any thoughts on why this is raising an error?
You have to declare the access level of the Content class public as well.
public class Content {
// some code
}
As stated in the documentation:
A public variable cannot be defined as having an internal or private
type, because the type might not be available everywhere that the
public variable is used.
Classes are declared as internal by default, so you have to add the public keyword to make them public.
A similar rule exists for functions as well.
A function cannot have a higher access level than its parameter types
and return type, because the function could be used in situations
where its constituent types are not available to the surrounding code.
Content must be declared as public too:
public class Content {
…
}
Depending on your use-case you might declare Bucket as internal, too. Just omit the public keyword in this case.
My issue was a namespace problem.
I had declared an enum called Data and that was mucking with the Swift Data class, especially an imageData: Data property within a Core Data model.

Swift Members / Methods Accessibility Modifiers [duplicate]

In Objective-C instance data can be public, protected or private. For example:
#interface Foo : NSObject
{
#public
int x;
#protected:
int y;
#private:
int z;
}
-(int) apple;
-(int) pear;
-(int) banana;
#end
I haven't found any mention of access modifiers in the Swift reference. Is it possible to limit the visibility of data in Swift?
As of Swift 3.0.1, there are 4 levels of access, described below from the highest (least restrictive) to the lowest (most restrictive).
1. open and public
Enable an entity to be used outside the defining module (target). You typically use open or public access when specifying the public interface to a framework.
However, open access applies only to classes and class members, and it differs from public access as follows:
public classes and class members can only be subclassed and overridden within the defining module (target).
open classes and class members can be subclassed and overridden both within and outside the defining module (target).
// 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
Enables an entity to be used within the defining module (target). You typically use internal access when defining an app’s or a framework’s internal structure.
// 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
Restricts the use of an entity to its defining source file. You typically use fileprivate access to hide the implementation details of a specific piece of functionality when those details are used within an entire file.
// 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
Restricts the use of an entity to its enclosing declaration. You typically use private access to hide the implementation details of a specific piece of functionality when those details are used only within a single declaration.
// First.framework – A.swift
internal struct A {
private static let x: Int
internal static func doSomethingWithX() {
x // ok
}
}
A.x // error: x is unavailable
Swift 4 / Swift 5
As per mentioned in the Swift Documentation - Access Control, Swift has 5 Access Controls:
open and public: can be accessed from their module's entities and any module's entities that imports the defining module.
internal: can only be accessed from their module's entities. It is the default access level.
fileprivate and private: can only be accessed in limited within a limited scope where you define them.
What is the difference between open and public?
open is the same as public in previous versions of Swift, they allow classes from other modules to use and inherit them, i.e: they can be subclassed from other modules. Also, they allow members from other modules to use and override them. The same logic goes for their modules.
public allow classes from other module to use them, but not to inherit them, i.e: they cannot be subclassed from other modules. Also, they allow members from other modules to use them, but NOT to override them. For their modules, they have the same open's logic (they allow classes to use and inherit them; They allow members to use and override them).
What is the difference between fileprivate and private?
fileprivate can be accessed from the their entire files.
private can only be accessed from their single declaration and to extensions of that declaration that are in the same file; For instance:
// 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!"
}
}
What are the differences between Swift 3 and Swift 4 Access Control?
As mentioned in the SE-0169 proposal, the only refinement has been added to Swift 4 is that the private access control scope has been expanded to be accessible from extensions of that declaration in the same file; For instance:
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!
}
}
So, there is no need to declare myMessage as fileprivate to be accessible in the whole file.
When one talks about making a "private method" in Swift or ObjC (or ruby or java or…) those methods aren't really private. There's no actual access control around them. Any language that offers even a little introspection lets developers get to those values from outside the class if they really want to.
So what we're really talking about here is a way to define a public-facing interface that merely presents the functionality we want it to, and "hides" the rest that we consider "private".
The Swift mechanism for declaring interfaces is the protocol, and it can be used for this purpose.
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)"
}
}
Remember, protocols are first-class types and can be used anyplace a type can. And, when used this way, they only expose their own interfaces, not those of the implementing type.
Thus, as long as you use MyClass instead of MyClassImplementation in your parameter types, etc. it should all just work:
func breakingAndEntering(foo:MyClass)->String{
return foo.privateMethod()
//ERROR: 'MyClass' does not have a member named 'privateMethod'
}
There are some cases of direct assignment where you have to be explicit with type instead of relying on Swift to infer it, but that hardly seems a deal breaker:
var myClass:MyClass = MyClassImplementation()
Using protocols this way is semantic, reasonably concise, and to my eyes looks a lot like the Class Extentions we've been using for this purpose in ObjC.
As far as I can tell, there are no keywords 'public', 'private' or 'protected'. This would suggest everything is public.
However Apple may be expecting people to use “protocols” (called interfaces by the rest of the world) and the factory design pattern to hide details of the implementation type.
This is often a good design pattern to use anyway; as it lets you change your implementation class hierarchy, while keeping the logical type system the same.
Using a combination of protocols, closures, and nested/inner classes, it's possible to use something along the lines of the module pattern to hide information in Swift right now. It's not super clean or nice to read but it does work.
Example:
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 and mysteriousMath are hidden here from outside use and attempting to dig your way into the object should result in an error.
I'm only part of the way through my reading of the Swift docs so if there's a flaw here please point it out, would love to know.
As of Xcode 6 beta 4, Swift has access modifiers. From the release notes:
Swift access control has three access levels:
private entities can only be accessed from within the source file where they are defined.
internal entities can be accessed anywhere within the target where they are defined.
public entities can be accessed from anywhere within the target and from any other context that imports the current target’s module.
The implicit default is internal, so within an application target you can leave access modifiers off except where you want to be more restrictive. In a framework target (e.g. if you're embedding a framework to share code between an app and an sharing or Today view extension), use public to designate API you want to expose to clients of your framework.
Swift 3.0 provides five different access controls:
open
public
internal
fileprivate
private
Open access and public access enable entities to be used within any source file from their defining module, and also in a
source file from another module that imports the defining module. You
typically use open or public access when specifying the public
interface to a framework.
Internal access enables entities to be used within any source file from their defining module, but not in any source file outside of that
module. You typically use internal access when defining an app’s or a
framework’s internal structure.
File-private access restricts the use of an entity to its own defining source file. Use file-private access to hide the
implementation details of a specific piece of functionality when those
details are used within an entire file.
Private access restricts the use of an entity to the enclosing declaration. Use private access to hide the implementation details of
a specific piece of functionality when those details are used only
within a single declaration.
Open access is the highest (least restrictive) access level and private access is the lowest (most restrictive) access level.
Default Access Levels
All entities in your code (with a few specific exceptions) have a default access level of internal if you do not specify an explicit access level yourself. As a result, in many cases you do not need to specify an explicit access level in your code.
The release note on the topic:
Classes declared as public can no longer be subclassed outside of
their defining module, and methods declared as public can no longer be
overridden outside of their defining module. To allow a class to be
externally subclassed or a method to be externally overridden, declare
them as open, which is a new access level beyond public. Imported
Objective-C classes and methods are now all imported as open rather
than public. Unit tests that import a module using an #testable import
will still be allowed to subclass public or internal classes as well
as override public or internal methods. (SE-0117)
More information & details :
The Swift Programming Language (Access Control)
In Beta 6, the documentation states that there are three different access modifiers:
Public
Internal
Private
And these three apply to Classes, Protocols, functions and properties.
public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}
For more, check Access Control.
Now in beta 4, they've added access modifiers to Swift.
from Xcode 6 beta 4 realese notes:
Swift access control has three access levels:
private entities can only be accessed from within the source file where they are defined.
internal entities can be accessed anywhere within the target where they are defined.
public entities can be accessed from anywhere within the target and from any other context
that imports the current target’s module.
By default, most entities in a source file have internal access. This allows application developers
to largely ignore access control while allowing framework developers full control over a
framework's API.
Access control mechanisms as introduced in Xcode 6:
Swift provides three different access levels for entities within your code. These access levels are relative to the source file in which an entity is defined, and also relative to the module that source file belongs to.
Public access enables entities to be used within any source file from their defining module, and also in a source file from another module that imports the defining module. You typically use public access when specifying the public interface to a framework.
Internal access enables entities to be used within any source file from their defining module, but not in any source file outside of that module. You typically use internal access when defining an app’s or a framework’s internal structure.
Private access restricts the use of an entity to its own defining source file. Use private access to hide the implementation details of a specific piece of functionality.
Public access is the highest (least restrictive) access level and private access is the lowest (or most restrictive) access level.
Default accecss it internal, and does as such not need to be specified. Also note that the private specifier does not work on the class level, but on the source file level. This means that to get parts of a class really private you need to separate into a file of its own. This also introduces some interesting cases with regards to unit testing...
Another point to me made, which is commented upon in the link above, is that you can't 'upgrade' the access level. If you subclass something, you can restrict it more, but not the other way around.
This last bit also affects functions, tuples and surely other stuff in the way that if i.e. a function uses a private class, then it's not valid to have the function internal or public, as they might not have access to the private class. This results in a compiler warning, and you need to redeclare the function as a private function.
Swift 3 and 4 brought a lot of change also for the access levels of variables and methods. Swift 3 and 4 now has 4 different access levels, where open/public access is the highest (least restrictive) access level and private access is the lowest (most restrictive) access level:
private functions and members can only be accessed from within the scope of the entity itself (struct, class, …) and its extensions (in Swift 3 also the extensions were restricted)
fileprivate functions and members can only be accessed from within the source file where they are declared.
internal functions and members (which is the default, if you do not explicitly add an access level key word) can be accessed anywhere within the target where they are defined. Thats why the TestTarget doesn't have automatically access to all sources, they have to be marked as accessible in xCode's file inspector.
open or public functions and members can be accessed from anywhere within the target and from any other context that imports the current target’s module.
Interesting:
Instead of marking every single method or member as "private", you can cover some methods (e.g. typically helper functions) in an extension of a class / struct and mark the whole extension as "Private".
class foo { }
private extension foo {
func somePrivateHelperFunction01() { }
func somePrivateHelperFunction02() { }
func somePrivateHelperFunction03() { }
}
This can be a good idea, in order to get better maintainable code. And you can easily switch (e.g. for unit testing) to non-private by just changing one word.
Apple documentation
For Swift 1-3:
No, it's not possible. There aren't any private/protected methods and variables at all.
Everything is public.
Update
Since Swift 4, it's possible see other answers in this thread
One of the options you could use is to wrap the instance creation into a function and supply the appropriate getters and setters in a constructor:
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
The language grammar does not have the keywords 'public', 'private' or 'protected'. This would suggest everything is public. Of course, there could be some alternative method of specifying access modifiers without those keywords but I couldn't find it in the language reference.
Hopefully to save some time for those who want something akin to protected methods:
As per other answers, swift now provides the 'private' modifier - which is defined file-wise rather than class-wise such as those in Java or C# for instance. This means that if you want protected methods, you can do it with swift private methods if they are in the same file
Create a base class to hold 'protected' methods (actually private)
Subclass this class to use the same methods
In other files you cannot access the base class methods, even when you subclass either
e.g. File 1:
class BaseClass {
private func protectedMethod() {
}
}
class SubClass : BaseClass {
func publicMethod() {
self.protectedMethod() //this is ok as they are in same file
}
}
File 2:
func test() {
var a = BaseClass()
a.protectedMethod() //ERROR
var b = SubClass()
b.protectedMethod() //ERROR
}
class SubClass2 : BaseClass {
func publicMethod() {
self.protectedMethod() //ERROR
}
}
till swift 2.0 there were only three access level [Public, internal, private]
but in swift 3.0 apple added two new access level which are [ Open, fileType ] so
now in swift 3.0 there are 5 access level
Here I want to clear the role of these two access level
1. Open: this is much similar to Public but the only difference is that the Public
can access the subclass and override, and Open access level can not access that this image is taken from Medium website and this describe the difference between open and public access
Now to second new access level
2. filetype is bigger version of private or less access level than internal
The fileType can access the extended part of the [class, struct, enum]
and private can not access the extended part of code it can only access the
lexical scope
this image is taken from Medium website and this describe the difference between fileType and Private access level

Generic Wrapper Class possible?

On C# 3.0 and .NET 3.5, imagine there's an interface:
public interface INameable
{
string Name {get;}
}
and many immutable classes that implement the interface.
I would like to have a single extension method
public static T Rename<T>(this T obj) where T : INameable
{
...
}
that returns a wrapped instance of the original object with just the name changed and all other property reads and method calls routed to the original object.
How to get a generic wrapper class for this, without implementing it for all INameable implementing types? Do you think that's possible?
No, this isn't possible, unless T is constrained to be an interface or to be a class with all members virtual, and this constraint isn't possible to specify at compile time (though you could write a runtime check if you're happy with that approach).
The reason you cannot do it for arbitrary types is that if you take an object of type T then you must return an object that is assignable to T. If I pass an object that looks as follows...
public sealed class SomeClass : INameable
{
public string Name { get; }
public string Abc { get; }
}
...then there is no way you can create another type that is assignable to SomeClass. Not using Reflection.Emit or any other method, because the type is sealed.
However, if you're happy with the restrictions that I've mentioned then you could use something like the Castle DynamicProxy framework to create a type that proxies the passed in object and intercepts the calls to either forward or re-implement as appropriate.
Well, yes, it's possible, but it involves generating code in memory.
You can look at Reflection.Emit and here.
Note that it will involve a lot of code.
That is, if I assume I understand you correctly.
Here's what I think you're asking for:
SomeNameableObject a1 = new SomeNameableObject("ThisIsTheFirstName");
SomeNameableObject a2 = a1.Rename("ThisIsTheSecondName");
// a1 works, still has the name ThisIsTheFirstName
// a2 works, but everything is routed to a1,
// except for the name, which is ThisIsTheSecondName
Is that correct?