Swift 2协议扩展没有正确调用重写方法

Rau*_*ait 8 swift swift2

我一直在使用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”
Run Code Online (Sandbox Code Playgroud)

Qby*_*yte 7

不幸的是,协议没有这种动态行为(尚未).

但是你可以通过实现和覆盖它来实现(commonBehavior()在类的帮助下).您还需要或另一个类符合哪个类是以下的超类:ParentClassChildClassCommonThingCommonTraitParentClass

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"
Run Code Online (Sandbox Code Playgroud)

由于这只是您问题的简短解决方案,我希望它适合您的项目.

  • 这意味着父类需要知道它的子类,不是吗?而是打破封装. (2认同)