391

The ObjectiveC.swift file from the standard library contains the following few lines of code around line 228:

extension NSObject : Equatable, Hashable {
  /// ...
  open var hashValue: Int {
    return hash
  }
}

What does open var mean in this context, or what is the open keyword in general?

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
Clashsoft
  • 11,553
  • 5
  • 40
  • 79
  • 2
    Possibly related: https://stackoverflow.com/questions/24003918/does-swift-have-access-modifiers/39697920#39697920 ("What is the difference between `open` and `public`?") – Ahmad F Jul 10 '18 at 15:23
  • 1
    Side note: keyword “open” came from the concept “open for extension, closed for modification” – Sazzad Hissain Khan Nov 16 '19 at 12:29

5 Answers5

673

open is a new access level in Swift 3, introduced with the implementation of

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.

Marián Černý
  • 15,096
  • 4
  • 70
  • 83
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • 21
    So `public` in Swift 3 is like `public final` in Swift 2, and `open` is like `public`? – Clashsoft Aug 15 '16 at 12:35
  • 16
    @Clashsoft: "open" in Swift 3 is like "public" in Swift 2. "public" in Swift 3 has no equivalent in Swift 2. (A final class cannot be subclassed at all, not even in the same module.) – Martin R Aug 15 '16 at 12:38
  • @MartinR So to get this straight: By default, subclassing is allowed only within the module. `open` makes subclasses allowed from outside the module. `Final` Disallows all subclassing. Correct? – Alexander Aug 16 '16 at 16:03
  • 3
    @AlexanderMomchliov: That's is how I understand it, confirmed by some simple tests. – Martin R Aug 16 '16 at 16:29
  • 69
    That is hilariously counterintuitive. Thanks for the summary. – GoldenJoe Sep 13 '16 at 06:06
  • 7
    Agree with @MikeS, and the lack of backward compatibility makes this a horrible mess. – HughHughTeotl Sep 23 '16 at 10:23
  • 20
    @MikeS apple - think different, even if its unnecessary. – Varun Nath Oct 18 '16 at 07:14
  • 3
    @MikeS if you write "providing a very simple and clean model" after whatever you do, it's then okay. – Dan Rosenstark Dec 13 '16 at 15:28
  • 3
    So by changing this, all they've actually done is made `public` *less* public than every coder out there expects, providing a very simple and clean model. – devios1 Dec 16 '16 at 18:54
  • 1
    I almost understood your point of view but What you mean by [ outside of the defining module ] – Atef Dec 28 '16 at 09:26
  • 2
    @Abo3atef: The main app and each framework are separate modules. For example, if a class is defined in a framework but not "open" then you can *use* it in your app, but you cannot *subclass* it. – Martin R Dec 28 '16 at 15:41
  • 1
    Apple just wanted to limit overriding more restricted without changing, testing most of their existing code libraries. An easy way out. – t1ser Jun 12 '17 at 05:31
  • 2
    Side note: keyword “open” came from the concept “open for extension, closed for modification” – Sazzad Hissain Khan Nov 16 '19 at 12:30
  • 1
    The quote from @SazzadHissainKhan is the key idea for the change. The idea is to help code by default following the [Open–closed principle](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle). – Edward Brey May 28 '20 at 01:38
  • great explanation especially when you are dealing with Modularised codebases – Naishta Nov 13 '21 at 20:07
  • Apple should just open their API to other languages like C# and Delphi. Swift has gone off the deep end. I don't know why they developed their own programming language that offers no real improvements over the competition. The eco-system is growing too fast for Apple to control by itself. – ATL_DEV Jul 05 '23 at 02:11
27

Read open as

open for inheritance in other modules

I repeat open for inheritance in other modules. So an open class is open for subclassing in other modules that include the defining module. Open vars and functions are open for overriding in other modules. Its the least restrictive access level. It is as good as public access except that something that is public is closed for inheritance in other modules.

From Apple Docs:

Open access applies only to classes and class members, and it differs from public access as follows:

  1. Classes with public access, or any more restrictive access level, can be subclassed only within the module where they’re defined.

  2. Class members with public access, or any more restrictive access level, can be overridden by subclasses only within the module where they’re defined.

  3. Open classes can be subclassed within the module where they’re defined, and within any module that imports the module where they’re defined.

  4. Open class members can be overridden by subclasses within the module where they’re defined, and within any module that imports the module where they’re defined.

Raj Pawan Gumdal
  • 7,390
  • 10
  • 60
  • 92
Mohammad Sadiq
  • 5,070
  • 28
  • 29
  • Public is supposed to mean open to all, but in swift it means open only internally. Open means what public is supposed to mean. Sounds like they bolted it on with little thought. – ATL_DEV Jul 05 '23 at 02:18
11

Open is an access level, was introduced to impose limitations on class inheritance on Swift.

This means that the open access level can only be applied to classes and class members.

In Classes

An open class can be subclassed in the module it is defined in and in modules that import the module in which the class is defined.

In Class members

The same applies to class members. An open method can be overridden by subclasses in the module it is defined in and in modules that import the module in which the method is defined.

THE NEED FOR THIS UPDATE

Some classes of libraries and frameworks are not designed to be subclassed and doing so may result in unexpected behavior. Native Apple library also won't allow overriding the same methods and classes,

So after this addition they will apply public and private access levels accordingly.

For more details have look at Apple Documentation on Access Control

GenericJam
  • 2,915
  • 5
  • 31
  • 33
Saranjith
  • 11,242
  • 5
  • 69
  • 122
2

open come to play when dealing with multiple modules.

open class is accessible and subclassable outside of the defining module. An open class member is accessible and overridable outside of the defining module.

1

open is only for another module for example: cocoa pods, or unit test, we can inherit or override

William
  • 271
  • 2
  • 10