Reputation: 32271
I have a class with a delegate. I create a subclass, which also has a delegate. I wanted to let the protocol used for the second delegate extend the protocol used for first delegate:
protocol MySuperClassProtocol {
func foo()
}
class MySuperClass {
var delegate:MySuperClassProtocol?
}
protocol MySubClassProtocol:MySuperClassProtocol {
func bar()
}
class MySubClass: MySuperClass {
override var delegate:MySubClassProtocol? // compiler error - "cannot override..."
func test() {
delegate?.foo()
delegate?.bar()
}
}
class UserClass:MySubClassProtocol {
func foo() {
println("foo!")
}
func bar() {
println("bar")
}
}
Is there a way to solve this? The only possible solution I see is to make the 2 protocols independent of each other, and use different names. Like this:
protocol MySuperClassProtocol {
func foo()
}
class MySuperClass {
var mySuperClassDelegate:MySuperClassProtocol?
}
protocol MySubClassProtocol {
func bar()
}
class MySubClass: MySuperClass {
var mySubClassDelegate:MySubClassProtocol?
func test() {
mySuperClassDelegate?.foo()
mySubClassDelegate?.bar()
}
}
class UserClass:MySuperClassProtocol, MySubClassProtocol {
func foo() {
println("foo!")
}
func bar() {
println("bar")
}
}
But this looks a bit weird + will not let me use naming convention for delegate- "delegate".
Upvotes: 14
Views: 10581
Reputation: 339
Sorry for necroposting, the only one solution i found is:
protocol SuperClassDelegate {
func first_method()
}
class SuperClass {
var delegate: SuperClassDelegate?
func do_something() {
delegate?.first_method()
}
}
protocol SubClassDelegate: SuperClassDelegate {
func second_method()
}
class SubClass: SuperClass {
private var subDelegate: SubClassDelegate?
override var delegate: SuperClassDelegate? {
get { return self.subDelegate }
set { self.subDelegate = newValue as! SubClassDelegate? }
}
//override func do_something() {
// super.do_something()
// subDelegate?.second_method()
//}
func do_something_other() {
//subDelegate?.first_method()
self.do_something()
subDelegate?.second_method()
}
}
class InheritanceAndDelegation: SubClassDelegate {
let obj = SubClass()
init() {
obj.delegate = self
}
internal func first_method() {
print("Hello from SuperClass")
}
internal func second_method() {
print("Hello from SubClass")
}
func check() {
obj.do_something_other()
}
}
let inheritanceAndDelegation = InheritanceAndDelegation()
inheritanceAndDelegation.check()
//prints:
//Hello from SuperClass
//Hello from SubClass
Commented code works too. Hope it will be useful for someone.
Upvotes: 7
Reputation: 10136
I was trying to find an ideal solution to this for some time, but could not come up with anything better that this:
protocol BaseDelegateProtocol: class { }
class BaseDelegate: BaseDelegateProtocol { }
class BaseActor {
weak var delegate: BaseDelegate? = nil
}
// MARK: -
protocol ConcreteDelegateProtocol: class {
func doSomething()
}
class ConcreteDelegate: BaseDelegate, ConcreteDelegateProtocol {
func doSomething() {
// Do something
}
}
class ConcreteActor: BaseActor {
private weak var concreteDelegate: ConcreteDelegateProtocol? = nil
override var delegate: BaseDelegate? {
didSet {
concreteDelegate = delegate as? ConcreteDelegateProtocol
}
}
}
Above works in XCode 7 / Swift 2.
BaseDelegate
.didSet
observer on delegate
property is automatically called for superclasses, therefore no need to call super.<blah>
explicitly, and no risk to 'forget' doing soUpvotes: 6
Reputation: 107121
You can do it in another way, you can add the delegate
variable in Subclass and use it to access the SuperClassProtocol
also using delegate?.foo()
.
protocol MySuperClassProtocol {
func foo()
}
class MySuperClass {
//var delegate:MySuperClassProtocol?
}
protocol MySubClassProtocol:MySuperClassProtocol {
func bar()
}
class MySubClass: MySuperClass {
var delegate:MySubClassProtocol?
func test() {
delegate?.foo()
delegate?.bar()
}
}
class UserClass:MySubClassProtocol {
func foo() {
println("foo!")
}
func bar() {
println("bar")
}
}
But the issue with this approach is you can never use MySuperClassProtocol
independently unless you create a new SubClass of MySuperClass
only for declaring delegate
variable.
Upvotes: 1