Reputation: 15266
Is it possible to add protocol compliance to a different protocol by way of an extension?
For instance we would like A to comply with B:
protocol A {
var a : UIView {get}
}
protocol B {
var b : UIView {get}
}
I want to give a default implementation (compliance) of B to objects of type A
// This isn't possible
extension A : B {
var b : UIView {
return self.a
}
}
The motivation being to reuse objects of A in cases where a B is required without creating my own "bridge"
class MyClass {
func myFunc(object : A) {
...
...
let view = object.a
... do something with view ...
myFunc(object) // would like to use an 'A' without creating a 'B'
}
func myFunc2(object : B) {
...
...
let view = object.b
... do something with view ...
}
}
As a side note we can extend a class to implement a protocol
class C {
let C : UIView
}
// this will work
extension C : B {
var B : UIView {
return self.c
}
}
and protocols can give default implementations
extension A {
// a default implementation
var a : UIView {
return UIView()
}
}
Upvotes: 25
Views: 17780
Reputation: 22939
When extending A
, you could specify that the type also conforms to B
:
extension A where Self: B {
var b : UIView {
return self.a
}
}
Then make your type conform to A
and B
, e.g.
struct MyStruct : A, B {
var a : UIView {
return UIView()
}
}
Due to the protocol extension, instances of MyStruct
will be able to use a
and b
, even though only a
was implemented in MyStruct
:
let obj = MyStruct()
obj.a
obj.b
Upvotes: 21
Reputation: 93161
You can make A
inherits from B
:
protocol A: B { var a: String { get } }
protocol B { var b: String { get } }
// Default implementation of property b
extension A {
var b: String { get { return "PropertyB" } }
}
class MyClass: A {
var a: String { get { return "PropertyA" } }
func printA(obj: A) {
print(obj.a)
printB(obj)
}
func printB(obj: B) {
print(obj.b)
}
}
let obj = MyClass()
obj.printA(obj)
Since A
inherits from B
, every property in B
is available in A
.
Upvotes: 5