简体   繁体   中英

Swift protocol extension with property conforming to protocol

I declared a protocol like so

protocol JSONConnection {
  var request: NSURLRequest { get set }
  var session: NSURLSession { get set }
  var jsonRootObject: JSONSerializable? { get set }
}

Here, the JSONSerializable is not an actual type, it is another protocol that I declared like so:

protocol JSONSerializable {
  func readFromJSON(json: JSON) throws
}

So, in fact, this JSONConnection protocol requires a variable called jsonRootObject that just needs to conform to the JSONSerializable protocol.

Fine.


Now, for the implementations.

I created a class called JSONStockDetailRootObject that conforms to the JSONSerializable protocol.

class JSONStockDetailRootObject: JSONSerializable

And I wanted to create a StockConnection class that conforms to the JSONConnection protocol.

class StockConnection: JSONConnection {
  var request: NSURLRequest
  var session: NSURLSession
  var jsonRootObject: JSONStockDetailRootObject?
}

I thought that, if I had a jsonRootObject variable of a type that conformed to the JSONSerializable protocol, then this class StockConnection would in turn conform to the JSONConnection protocol ... but no.

The compiler claims: "Protocol requires property 'jsonRootObject' with type 'JSONSerializable?'

What am I missing? Thanks

In your example, the class StockConnection does not contain any valid implementation of the blueprint var jsonRootObject: JSONSerializable? { get set } var jsonRootObject: JSONSerializable? { get set } , which it promises to implement by conforming to JSONConnection . Note that in the context of jsonRootObject , JSONSerializable is a type , and even if JSONStockDetailRootObject conforms to JSONSerializable , it cannot be treated as the same type.

You can solve this by introducing a typealias, say T , (to use as jsonRootObject type) into protocol JSONConnection ; where T is constrained to types conforming to JSONSerializable .

protocol JSONSerializable {
    func readFromJSON(json: JSON) throws
}

protocol JSONConnection {
    typealias T: JSONSerializable
    var request: NSURLRequest { get set }
    var session: NSURLSession { get set }
    var jsonRootObject: T? { get set }
}

class JSONStockDetailRootObject: JSONSerializable {
    func readFromJSON(json: JSON) throws ...
}

class StockConnection: JSONConnection {
    var request: NSURLRequest = NSURLRequest()
    var session: NSURLSession = NSURLSession()
    var jsonRootObject: JSONStockDetailRootObject?
}

Since JSONStockDetailRootObject conforms JSONSerializable , the implementation of jsonRootObject in StockConnection above is valid conformance of the blueprint var jsonRootObject: T? { get set } var jsonRootObject: T? { get set } in protocol JSONConnection .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM