Swift 2协议扩展未正确调用重写的方法 [英] Swift 2 protocol extension not calling overridden method correctly

查看:155
本文介绍了Swift 2协议扩展未正确调用重写的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用默认实现的Swift 2协议扩展遇到了一个问题.基本要点是,我已经提供了协议方法的默认实现,我将在实现该协议的类中重写该方法.该协议扩展方法是从基类中调用的,然后该基类将调用在派生类中已重写的方法.结果是未调用重写的方法.

I've been running into an issue using Swift 2's protocol extensions with default implementations. The basic gist is that I've provided a default implementation of a protocol method which I am overriding in a class that implements the protocol. That protocol extension method is being called from a base class, which is then calling a method which I have overridden in a derived class. The result is that the overridden method is not being called.

我试图将问题提炼到最小的游乐场,以说明下面的问题.

I've tried to distill the problem to the smallest possible playground which illustrates the issue below.

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"

推荐答案

不幸的是,协议还没有这样的动态行为.

Unfortunately protocols don't have such an dynamic behavior (yet).

但是您可以(在类的帮助下)通过在ParentClass中实现commonBehavior()并在ChildClass中覆盖它来做到这一点.您还需要CommonThing或其他类来符合CommonTrait的要求,该类才是ParentClass的超类:

But you can do that (with the help of classes) by implementing commonBehavior() in the ParentClass and overriding it in the ChildClass. You also need CommonThing or another class to conform to CommonTrait which is then the superclass of ParentClass:

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"

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

Since this is only a short solution for your problem I hope it fits in your project.

这篇关于Swift 2协议扩展未正确调用重写的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆