简体   繁体   English

Swift重写协议扩展保持扩展行为

[英]Swift overriding protocol extension keeping the extension behaviour

I have this simple class and an hypothetical protocol called 'ShowAlert', it's extension to do the default implementation and a default ViewController and it's ShowAlert protocol implementation. 我有这个简单的类和一个名为'ShowAlert'的假设协议,它是执行默认实现的扩展,默认的ViewController和它的ShowAlert协议实现。

protocol ShowAlert {
    var titleForAlert: String! { get }
    func messageForAlert() -> String!
    func show()
}

extension ShowAlert where Self: UIViewController {

    func show(){
        let alert = UIAlertController(title: self.titleForAlert, message: self.messageForAlert(), preferredStyle: .Alert)
        alert.addAction(UIAlertAction(title: "Ok", style: .Cancel, handler: nil))
        self.presentViewController(alert, animated: true, completion: nil)
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }


    @IBAction func showItNow(sender: AnyObject) {
        self.show()
    }



}

extension ViewController: ShowAlert {
    var titleForAlert: String! {
        get{
            return "Foo"
        }
    }


    func messageForAlert() -> String! {
        return "Bar"
    }

    func show() {
    // here I want to call the default implementation of the protocol to show the alert, then do something else
        print("Good day sir!")
    }
}

It's like on a subclass where I could call a 'super.show()' and then continue implementing whatever I want to do after that. 就像在子类中我可以调用'super.show()'然后继续实现我想要做的任何事情之后。

There's any way to do it? 有办法吗? Or my logic go against what protocols are design for and that don't suppose to happen? 或者我的逻辑违背了设计的协议,并且不会发生这种情况?

There is a simple solution: Just add a defaultShow method to the extension. 有一个简单的解决方案:只需将defaultShow方法添加到扩展。

extension ShowAlert where Self: UIViewController {

    func defaultShow(){
        let alert = UIAlertController(title: self.titleForAlert, message: self.messageForAlert(), preferredStyle: .Alert)
        alert.addAction(UIAlertAction(title: "Ok", style: .Cancel, handler: nil))
        self.presentViewController(alert, animated: true, completion: nil)
    }

    func show() {
        defaultShow()
    }
}

So in your code you can just call defaultShow : 所以在你的代码中你可以调用defaultShow

extension ViewController: ShowAlert {
    // ...

    func show() {
        self.defaultShow()
        print("Good day sir!")
    }
}

There is also another solution where you can call .show() instead of .defaultShow() . 还有另一种解决方案,您可以调用.show()而不是.defaultShow() However it uses casting and breaks encapsulation. 然而,它使用铸造和破坏封装。 If you want to see it let me know. 如果你想看到它让我知道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM