Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
239 views
in Technique[技术] by (71.8m points)

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

question from:https://stackoverflow.com/questions/27814519/swift-require-classes-implementing-protocol-to-be-subclasses-of-a-certain-cla

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think you are after a subclass of NSView. Try this:

protocol TransmogrifiableView {
    func transmogrify()
}

class MyNSView: NSView, TransmogrifiableView {
    // do stuff.
}

And later in the code accept objects of type MyNSView.

Edit

You maybe want an Extension, see this

extension NSView: TransmogrifiableView {
    // implementation of protocol requirements goes here
}
  • Note that you will not be able to get an NSView without this extra method.
  • You can separately extend subclasses of NSView to override this new method.

Yet another option is to make a class which holds a pointer to an NSView, and implements additional methods. This will also force you to proxy all methods from NSView that you want to use.

class NSViewWrapper: TransmogrifiableView {
    var view : NSView!
    // init with the view required.
    //  implementation of protocol requirements goes here.
    .....
   // proxy all methods from NSView.
   func getSuperView(){
       return self.view.superView
   }
}

This is quite long and not nice, but will work. I would recommend you to use this only if you really cannot work with extensions (because you need NSViews without the extra method).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...