What Is the 'Open' Keyword in Swift

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

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



Leave a reply



Submit