So in Apple documentation:
Any type members added in an extension have the same default access level as type members declared in the original type being extended. If you extend a public or internal type, any new type members you add will have a default access level of internal.
Giving a sub class of UIView extension:
extension UIViewSubClass
{
var helloWorld : String {
get {
return "helloWorld"
}
}
}
This will mark helloWorld
as internal, I have no problem, and I cannot see it in my Objective-C based project.
However, if I mark the extension to be public:
public extension UIViewSubClass
{
var helloWorld : String {
get {
return "helloWorld"
}
}
}
Now helloWorld
apprears in my Objective-C based code, which means it is marked as public.
However, I don't see Apple mentions this, did it?
I just saw the documentation said a public class will still has implicit internal level.
public class SomePublicClass { // explicitly public class
public var somePublicProperty = 0 // explicitly public class member
var someInternalProperty = 0 // implicitly internal class member
private func somePrivateMethod() {} // explicitly private class member
}
Marking public for extension seems have different effect than marking a Class definition. This makes me confused.
Could someone help me, is this supposed to be so, or this is a sort of swift bug? I am with swift 2.1 and Xcode 7.2
Extensions can add new computed properties, but they can't add stored properties, or add property observers to existing properties.
Computed Property In Extension However, Swift lets us add computed properties to an extension. For example, extension Circle { // computed property var area: Double { ... } } Here, area is a computed property defined in the extension body.
A Swift extension allows you to add functionality to a type, a class, a struct, an enum, or a protocol.
It is not possible to override functionality (like properties or methods) in extensions as documented in Apple's Swift Guide. Extensions can add new functionality to a type, but they cannot override existing functionality. The compiler is allowing you to override in the extension for compatibility with Objective-C.
Answer: Yes, placing access level modifiers (in your case, public
, specifically) in front of extensions modify the default access level of all new types in the scope of that extension.
Note that the modifier does not affect the access level of the class/struct/etc being extended (only it's members. However, there are things that ought to be considered, as I will discuss below.
In this discussion, I'll post a few important facts regarding regarding access levels in Swift. All these are from the Swift Language Guide - Access Control - Access Levels.
Let's first assure what you've already stated:
All entities in your code (with a few specific exceptions, as described later in this chapter) have a default access level of internal if you do not specify an explicit access level yourself.
OK, this goes in line with what you've quoted in you question: any new type members, whether in a class or structure definition, will have a default access level of internal.
Now, lets look at the access level modifier that you can add in front of extensions:
You can extend a class, structure, or enumeration in any access context in which the class, structure, or enumeration is available. Any type members added in an extension have the same default access level as type members declared in the original type being extended. If you extend a public or internal type, any new type members you add will have a default access level of internal. If you extend a private type, any new type members you add will have a default access level of private.
Alternatively, you can mark an extension with an explicit access level modifier (for example, private extension) to set a new default access level for all members defined within the extension. This new default can still be overridden within the extension for individual type members.
This sorts things out. We look at your example, and assume that your class UIViewSubClass
has access level public
(or compile time error, se below):
/* no access level modifier: default access level will be 'internal' */
extension UIViewSubClass
{
// default access level used: internal
var helloWorld : String {
get {
return "helloWorld"
}
}
}
// modify default access level to public
public extension UIViewSubClass
{
// default access level used: public
var helloWorld : String {
get {
return "helloWorld"
}
}
}
With the discussion above in mind, it's expected that your helloWorld
in you public extension ...
is marked as internal
, as this is, in this context, the default access level. In the context of extensions, access level modifiers work differently than when applied to types.
Finally, we should point out that using a public
access modifier when extending a non-public class will yield a compile time error in Swift. So in your case above:
UISubViewClass
is an internal
or a private
class, then the public extension ...
on the class will yield an compile time error.UISubViewClass
is a public
class, then adding the public extension
will be redundant as the default access modifier of a public class is already, by definition, public
.I'd say that the error described above is not really an error to avoid runtime errors, but rather to avoid redundant (and confusing) code: public
member types or private
or internal
classes will never make use of its
public` access level.
class MyImplicitlyInternalClass {
private var myExplicitlyPrivateVar = 0
var myImplicitlyInternalVar = 0
public var myExplicitlyPublicVar = 0 // warning, see (Note 1) below
// redundant 'public': can never be accessed publicly
// myExplicitlyPublicVar will behave as 'internal'
}
public extension MyImplicitlyInternalClass { // error, see (Note 2)
var myNewVarIsInternal : Int { get { return 0 } }
}
/* (Note 1) Compile type warning:
"Declaring a public var for an internal class."
(Note 2) Compile time error:
"Extension of internal class cannot be declared public."
Summary: in theory, these two above are the same type of
'faults', but only the latter is flagged as and error. */
Hence, it only ever makes sense to use the access level modifiers on extensions to make the default access level more restrictive, i.e., using internal extension ...
of a public
class, or private extension
or an internal
class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With