@objc protocol Protocol: AnyObject {
@objc optional func protocolFunction()
}
class Class: Protocol {
func classFunction() {
(self as? Protocol)?.protocolFunction?()
}
}
class SubclassA: Class {
func protocolFunction() {
print("subclass a function")
}
}
class SubclassB: Class {
func protocolFunction() {
print("subclass b function")
}
}
Basically, in Class, protocolFunction() is called from inside classFunction(), but Class's implementation of protocolFunction() is not important.
When an instance of a Class subclass calls classFunction(), if it has implemented protocolFunction(), then its own implementation of it is called (in this case a SubclassA instance prints "subclass a function"). Not every subclass needs this functionality.
What I am having trouble with is doing the same thing but without having to use objc protocols.
However, when I call classFunction() on a Subclass instance it uses the default implementation of protocolFunction() rather than the implementation in Subclass (in this case it prints "default function" rather than the desired "subclass function").
Could anyone please let me know how I can have it so that I can use the inherited classFunction() with Subclass but have it call the subclass's implementation of protocolFunction() instead?
This happens because you are not overridingprotocolFunction in Subclass. You are defining your custom implementation of protocolFunction for Subclass, while Class.classFunction continues to use the default implementation. So
Subclass().classFunction() // "default function"
// Calls Class.classFunction, and thus Class.protocolFunction === Protocol.protocolFunction
// (the default implementation of protocolFunction)
Subclass().protocolFunction() // "subclass function"
// Calls Subclass.protocolFunction
If you want classFunction to call Subclass.protocolFunction, you can either override it:
or define a custom implementation of protocolFunction in Class and then override it in Subclass:
class Class: Protocol {
func classFunction() {
protocolFunction()
}
func protocolFunction() {
print("class function")
}
}
class Subclass: Class {
override func protocolFunction() {
print("subclass function")
}
}
Subclass().classFunction()
// Calls Class.classFunction, which calls the overridden Subclass.protocolFunction ("subclass function")
In your example with objc protocols, protocolFunction is called if there is an implementation. Considering Class doesn't have any implementation available, the subclass implementations are called.
I am not entirely sure though that I haven't messed up with stating who calls who – @jrose can you help out if needed?
If you want classFunction to call Subclass.protocolFunction, you can either override it
I understand that I can override classFunction in Subclass but since the code would be identical in each subclass I was hoping to not have to duplicate so much.
Or define a custom implementation of protocolFunction in Class and then override it in Subclass
Also, unfortunately this second alternative behaves the same way as my code in the original post. (i.e. Subclass().classFunction() still performs Class's implementation of protocolFunction rather than the overridden one in Subclass).
In your example with objc protocols, protocolFunction is called if there is an implementation. Considering Class doesn’t have any implementation available, the subclass implementations are called.
With the objc protocol, even when Class has its own implementation of protocolFunction, calling Subclass().classFunction() will still print the desired "subclass function".
Of course, because, just like in the above example, you would be overridingprotocolFunction. Overriding equally applies to both native and objc protocols.