0

Consider the following example:

class ManObj {
    func baseFunc() {
        print("ManObj baseFunc")
    }
}

class SubObj: ManObj {
}

protocol Model {
}

extension Model { // This is protocol extension
    func someFunc() { // Protocol extension default implementation
        (self as! ManObj).baseFunc()
        print("Model implementation")
    }
}
extension SubObj: Model {
    func someFunc() {
        print("SubObj Implementation")
    }
}

let list = SubObj()
list.someFunc() // static dispatching

let list2: Model = SubObj()
list2.someFunc() // dynamic dispatching

The output is nicely:

SubObj Implementation
ManObj baseFunc
Model implementation

But I dislike the casting in the line (self as! ManObj).baseFunc().

In fact, I only plan to apply Model protocol to subclasses of ManObj. (But not all subclasses of ManObj are Model though!) So, I tried to change Model to:

extension Model where Self: ManObj {
    func someFunc() {
        self.baseFunc() // No more casting needed!
        print("Model implementation")
    }
}

But I'm greeted with error:

list2.someFunc() <- error: 'Model' is not a subtype of 'ManObj'

So, is there a way for me to trigger Model.someFunc from list2 after I constrain Model to where Self: ManObj?

ewcy
  • 323
  • 2
  • 9

1 Answers1

0

Create an empty class just for type casting

class ManObj {
    func baseFunc() {
        print("ManObj baseFunc")
    }
}

class SubObj: ModelCaster {
    func someFunc() {
        print("SubObj Implementation")
    }
}

protocol Model {
}

extension Model where Self: ModelCaster { // This is protocol extension
    func someFunc() { // Protocol extension default implementation
        print("Model implementation")
    }
}

class ModelCaster: ManObj, Model{

}

let list = SubObj()
list.someFunc() //SubObj Implementation

let list2: ModelCaster = SubObj()
list2.someFunc() //Model implementation
vk.edward.li
  • 1,899
  • 16
  • 22