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
?
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