Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift -- Require classes implementing protocol to be subclasses of a certain class

I'm creating several NSView classes, all of which support a special operation, which we'll call transmogrify. At first glance, this seems like the perfect place for a protocol:

protocol TransmogrifiableView {     func transmogrify() } 

However, this protocol does not enforce that every TransmogrifiableView be an NSView as well. This means that any NSView methods I call on a TransmogrifiableView will not type check:

let myView: TransmogrifiableView = getTransmogrifiableView() let theSuperView = myView.superView // error: TransmogrifiableView does not have a property called 'superview' 

I don't know how to require that all classes implementing my protocol are also subclasses of NSView. I tried this:

protocol TransmogrifiableView: NSView {     func transmogrify() } 

but Swift complains that protocols cannot inherit from classes. It does not help to turn the protocol into a class-only protocol using

protocol TransmogrifiableView: class, NSView {     func transmogrify() } 

I cannot make TransmogrifiableView a superclass rather than a protocol, because some of my TransmogrifiableView classes must be subclasses of other, non-transmogrifiable views.

How should I require that all TransmogrifiableView's also be NSView's? I really don't want to pepper my code with "as" conversions, which are bad form and distracting.

like image 682
exists-forall Avatar asked Jan 07 '15 07:01

exists-forall


People also ask

What is subclass Swift?

Subclassing. Subclassing is the act of basing a new class on an existing class. The subclass inherits characteristics from the existing class, which you can then refine. You can also add new characteristics to the subclass.

Can Swift protocol implementation?

In Swift, to use a protocol, other classes must conform to it. After we conform a class to the protocol, we must provide an actual implementation of the method.

CAN protocol inherit from class Swift?

Protocols allow you to group similar methods, functions, and properties. Swift lets you specify these interface guarantees on class , struct , and enum types. Only class types can use base classes and inheritance from a protocol.

How many protocols can a Swift class adopt?

Swift 4 allows multiple protocols to be called at once with the help of protocol composition.


1 Answers

Update. In the latest Swift version you can just write

protocol TransmogrifiableView: NSView {     func transmogrify() } 

, and this will enforce the conformer types to be either NSView, or a subclass of it. This means the compiler will "see" all members of NSView.


Original answer

There is a workaround by using associated types to enforce the subclass:

protocol TransmogrifiableView {     associatedtype View: NSView = Self     func transmogrify() }  class MyView: NSView, TransmogrifiableView { ... } // compiles class MyOtherClass: TransmogrifiableView { ... } // doesn't compile 
like image 134
Cristik Avatar answered Sep 23 '22 14:09

Cristik