That is a very good point, it should be explicitly mentioned in the proposal. My thought would be that since in the Obj-C runtime it's not possible to guarantee a class won't have subclasses, or that a method is not overriden, Obj-C classes would be imported as open.
On the Swift side, I think today it's possible to declare a "public final @objc class", but you can still inherit from it from Obj-C, right? My hunch would be that that should be disallowed, but perhaps there's a reason why it's allowed today. On Mon, Jun 27, 2016 at 4:25 PM Michael Ilseman <[email protected]> wrote: > Could you elaborate on how we should treat classes imported from > Objective-C or CF-style C? That is, do we always annotate them as being > “open” because those paradigms permit subclassing anywhere, or do you > propose some kind of recommended “sealed” audit, or what? > > On Jun 27, 2016, at 3:40 PM, Javier Soto via swift-evolution < > [email protected]> wrote: > > Hello! > > I sent this as a PR <https://github.com/apple/swift-evolution/pull/376> > on the swift-evolution repo, but we never had any discussion about it > on-list, besides a long time ago > <http://thread.gmane.org/gmane.comp.lang.swift.evolution/9702/focus=9708>. > Here's the first draft of the proposal: > > > Sealed classes by default > <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#introduction> > Introduction > > Introduce a new sealed class modifier that makes classes and methods final > outside of the module they're declared in, but non-final within the > module. > > <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#motivation> > Motivation > > - It is not uncommon to have a need for a reference type without > needing inheritance. Classes must be intentionally designed to be > subclassable, carefully deciding which methods are the override > entry-points such that the the behavior remains correct and subclasses > respect the Liskov substitution principle > <https://en.wikipedia.org/wiki/Liskov_substitution_principle>. > - Defaulting to non-final allows the author of a class to accidentally > leave the visible methods open for overrides, even if they didn't carefully > consider this possibility. > - Requiring that the author of a class mark a class as open is akin to > requiring symbols to be explicitly public: it ensures that a conscious > decision is made regarding whether the ability to subclass a class is > part of the API. > > > <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#proposed-solution>Proposed > solution > > - New sealed (*actual name pending bike-shedding*) class modifier for > classes and methods which marks them as only overridable within the module > they're declared in. > - sealed becomes the default for classes and methods. > - New open (*actual name pending bike-shedding*) class modifier to > explicitly mark a class or a method as overridable. > > > <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#detailed-design>Detailed > design > > Code Examples: > > /// ModuleA: > /// This class is `sealed` by default./// This is equivalent to `sealed class > SealedParentClass`class SealedParentClass { > /// This method is `sealed` by default`. > func foo() > > /// This raises a compilation error: a method can't have a > "subclassability" > /// level higher than that of its class. > open func bar() > > /// The behavior of `final` methods remains unchanged. > final func baz() > } > > open class OpenParentClass { > /// This method is `sealed` by default`. > func foo() > > /// Overridable methods in an `open` class must be explicitly marked as > `open`. > open func bar() > > /// The behavior of a `final` method remains unchanged. > final func baz() > } > /// The behavior of `final` classes remains unchanged.final class FinalClass > { } > > /// ModuleB: > import ModuleA > /// This raises a compilation error: ParentClass is effectively `final` > from/// this module's point of view.class SubclassA : SealedParentClass { } > /// This is allowed since `OpenParentClass` has been marked explicitly > `open`class SubclassB : OpenParentClass { > /// This raises a compilation error: `OpenParentClass.foo` is > /// effectively `final` outside of `ModuleA`. > override func foo() { } > > /// This is allowed since `OpenParentClass.bar` is explicitly `open`. > override func bar() { } > } > > > <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#impact-on-existing-code>Impact > on existing code > > - This would be a backwards-breaking change for all classes and > methods that are public and non-final, which code outside of their module > has overriden. Those classes/methods would fail to compile. Their > superclass would need to be changed to open. > > > <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#alternatives-considered>Alternatives > considered > > - Defaulting to final instead: This would be comparable to Swift > defaulting to private, as opposed to internal. Just like internal is a > better trade-off, sealed by default also makes sure that getting > started with Swift, writing code within a module, doesn't require a lot of > boilerplate, and fighting against the compiler. > > -- > Javier Soto > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution > > > -- Javier Soto
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
