使用默认实现的Swift 2协议扩展遇到了一个问题。基本要点是,我已经提供了协议方法的默认实现,我将在实现该协议的类中重写该方法。该协议扩展方法是从基类中调用的,然后该基类将调用在派生类中已重写的方法。结果是未调用重写的方法。
我试图将问题提炼到最小的游乐场,以说明以下问题。
protocol CommonTrait: class { func commonBehavior() -> String } extension CommonTrait { func commonBehavior() -> String { return "from protocol extension" } } class CommonThing { func say() -> String { return "override this" } } class ParentClass: CommonThing, CommonTrait { override func say() -> String { return commonBehavior() } } class AnotherParentClass: CommonThing, CommonTrait { override func say() -> String { return commonBehavior() } } class ChildClass: ParentClass { override func say() -> String { return super.say() // it works if it calls `commonBehavior` here and not call `super.say()`, but I don't want to do that as there are things in the base class I don't want to have to duplicate here. } func commonBehavior() -> String { return "from child class" } } let child = ChildClass() child.say() // want to see "from child class" but it's "from protocol extension”
不幸的是,协议还没有这样的动态行为。
但是,您可以(在类的帮助下)通过commonBehavior()在中实现ParentClass并在中进行覆盖来做到这一点ChildClass。您还需要一个CommonThing或另一个类来遵循,CommonTrait然后才是的超类ParentClass:
commonBehavior()
ParentClass
ChildClass
CommonThing
CommonTrait
class CommonThing: CommonTrait { func say() -> String { return "override this" } } class ParentClass: CommonThing { func commonBehavior() -> String { // calling the protocol extension indirectly from the superclass return (self as CommonThing).commonBehavior() } override func say() -> String { // if called from ChildClass the overridden function gets called instead return commonBehavior() } } class AnotherParentClass: CommonThing { override func say() -> String { return commonBehavior() } } class ChildClass: ParentClass { override func say() -> String { return super.say() } // explicitly override the function override func commonBehavior() -> String { return "from child class" } } let parent = ParentClass() parentClass.say() // "from protocol extension" let child = ChildClass() child.say() // "from child class"
由于这只是您问题的一个简短解决方案,我希望它适合您的项目。