What is the 'open' keyword in Swift?
open
is a new access level in Swift 3, introduced with the implementation
of
- SE-0117 Allow distinguishing between public access and public overridability
It is available with the Swift 3 snapshot from August 7, 2016,
and with Xcode 8 beta 6.
In short:
- An
open
class is accessible and subclassable outside of the
defining module. Anopen
class member is accessible and
overridable outside of the defining module. - A
public
class is accessible but not subclassable outside of the
defining module. Apublic
class member is accessible but
not overridable outside of the defining module.
So open
is what public
used to be in previous
Swift releases and the access of public
has been restricted.
Or, as Chris Lattner puts it in
SE-0177: Allow distinguishing between public access and public overridability:
“open” is now simply “more public than public”, providing a very simple and clean model.
In your example, open var hashValue
is a property which is accessible and can be overridden in NSObject
subclasses.
For more examples and details, have a look at SE-0117.
Using of open and public
As this answer says:
- An open class is accessible and subclassable outside of the defining module. An open class member is accessible and overridable outside of the defining module.
- A public class is accessible but not subclassable outside of the defining module. A public class member is accessible but not overridable outside of the defining module.
I think the answer to your first question, is that you can't override or subclass a protocol or extension. Thus, there is no use for such things to be open
because public
already makes them accessible outside of a module.
For your second question, I would say that you should only declare your own classes as open
if you plan on overriding or subclassing. Otherwise you are allowing unnecessary access to these items. Most of the time public
should suit your needs.
Edit:
As @Alex points out, I don't think there are many downsides to allowing this "extra access". The only thing I can think of is if you just wanted to protect your classes from your future self, but that may or may not be applicable. Thus, if this is not the case, there shouldn't be much harm in setting them as open
by default.
What is the use of open variables over public variables which are stored?
You can override a property but not with a stored property. When overriding properties, you have to use a computed property, e.g.:
A class with a stored property:
open class God {
open var hasSuperPowers = true
}
The property can be overriden only with a computed property:
class HalfGod: God {
override var hasSuperPowers: Bool {
didSet {
print("\(oldValue) -> \(hasSuperPowers)")
}
}
}
or
class HalfGod: God {
var hasPowers: Bool = false
override var hasSuperPowers: Bool {
get {
return hasPowers
}
set {
hasPowers = newValue
}
}
}
You can override properties from other modules only if they are open
. public
properties cannot be overriden from other modules.
Does the initializer of an `open` class need to be open as well?
From SE-0117 Allow distinguishing between public access and public overridability:
Initializers do not participate in open checking; they cannot be declared open, and there are no restrictions on providing an initializer that has the same signature as an initializer in the superclass.
You need not and you cannot declare a init method as open:
open class OpenClass {
open init() { // error: only classes and overridable class members can be declared 'open'; use 'public'
}
}
The default access level for all members of a class (properties
and methods) is internal, that applies to open classes as well.
public static vs open static vs public class vs open class?
This question is over-complicated because you're comparing the members of the cartesian product of two variables (open
vs public
and static
vs class
), rather than asking about the two variables separately.
It's not a matter of open static
vs public static
vs open class
vs public class
, but rather of open
vs public
and static
vs class
. They're two orthogonal dimensions.
open
vs public
public
:
Within the module, the public
access specifier allows access and overriding.
From outside the module, the public
access specifier allows access, but does not permit overrides/subclasses.
open
:
Within the module, the open
access specifier allows access and overriding.
From outside the module, the open
access specifier allows access, and permits overrides/subclasses.
static
vs class
static
:
A static
member (method or property) is one who is bound to the specific scope (class
/struct
/enum
) it is defined in. It's named such because access to such members is always statically dispatched. This is equivalent to Java's static
. Objective C has no equivalent to this.
class
:
A class
member is one who is bound to a class or its subclasses. class
members can be overridden by subclasses. Because of this, they're dynamically dispatched in the general case, although accesses to class
members can be devirtualized by the optimizer in some cases. Java has no equivalent to this. This is equivalent to Objective C's class (+
) methods.
Marking an open method final in subclass
You can do this by making the method public
like this:
open class A { // This class is from the SDK and cannot be modified in anyway.
open func aFunc() {}
}
open class B : A { // This has to be open for others to override.
override final public func aFunc() {}
}
open
keyword is for letting subclasses from different module to override, whereas the public
keyword only gives access to different module and do not allow the overriding. If you want to override this method in only your module and not in other modules you can just make it public without final
.
Swift 3: The difference between Public and Internal access modifiers?
Your diagram is just incorrect.
Public members of A.swift
and B.swift
are available to C.swift
and D.swift
. The only restriction is that classes can't be subclassed (they would need to be open
.
What is the use of the of keyword in Swift?
In this case, "of" is the label for the argument called "name".
If you were to call this function, it would be
student(of: "Mathematics")
However inside the student function, you would get it's value with "name"
func student(of name: String) -> String {
print(name)
// TODO: Do something and return
}
Just a suggestion, IMHO "of" is not very descriptive of what the function does or what "of" represents (is "of" an id? The name of the student?).
Related Topics
Any Way to Replace Characters on Swift String
Swiftui: How to Make Textfield Become First Responder
Swift: Print() VS Println() VS Nslog()
Accessing an Enumeration Association Value in Swift
How to Use Attributed String in Swiftui
Understanding Spritekit Collisionbitmask
Changing Navigation Title Programmatically
Swift - Extra Argument in Call
JavaScript Synchronous Native Communication to Wkwebview
"Classname Has No Member Functionname" When Adding Uibutton Target
Shall We Always Use [Unowned Self] Inside Closure in Swift
How to Resolve "Ambiguous Use Of" Compile Error With Swift #Selector Syntax
How to Compare Enum With Associated Values by Ignoring Its Associated Value in Swift
How to Stop a Dispatchworkitem in Gcd
How to Create Generic Protocols in Swift
Swift Array - Check If an Index Exists
Why Is 'Nil' Not Compatible With 'Unsafepointer≪Cgaffinetransform≫' in Swift 3