Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extend a Class that conforms a protocol?

How can I make an extension of a class that implements a protocol ?

Something like that :

protocol proto {
    func hey()
}

and a class that conforms to proto :

Class MyClass: UIViewController, proto {
     func hey() {
         print("Hey!")
     }
}

and then an extension of that class that would look like :

extension UIViewController where Self:proto {
     func test() {
         print("I'm extended!")
     }
}

So that I can call self.test() in MyClass.

Thanks.

like image 907
Que20 Avatar asked Apr 08 '16 09:04

Que20


People also ask

Can we use extension for protocol types?

An extension can extend an existing type to make it adopt one or more protocols. To add protocol conformance, you write the protocol names the same way as you write them for a class or structure: extension SomeType: SomeProtocol, AnotherProtocol {

What is a protocol extension?

Protocols let you describe what methods something should have, but don't provide the code inside. Extensions let you provide the code inside your methods, but only affect one data type – you can't add the method to lots of types at the same time.

Can you extend a struct Swift?

A Swift extension allows you to add functionality to a type, a class, a struct, an enum, or a protocol.


2 Answers

You can just extend protocol, not the type. Please, try the following:

protocol proto {
    func hey()
}

class MyClass: UIViewController, proto {
    func hey() {
        print("Hey!")
    }

    func test2() {
        self.test()
    }
}

extension proto where Self: UIViewController {
    func test() {
        print("I'm extended!")
    }
}
like image 110
Maxim Kosov Avatar answered Nov 15 '22 04:11

Maxim Kosov


First, you have to declare test method in proto so that MyClass knows it implements this method.

protocol proto {
    func hey()
    func test()
}

Also you have to "reverse" the statements in the protocol extension:

extension proto where Self : UIViewController {
    func test() {
        print("I'm extended!")
    }
}

After that, MyClass is magically extended and you can call test method on it:

class MyClass: UIViewController, proto {

    override func viewDidLoad() {
        super.viewDidLoad()
        test()
    }
}
like image 39
Michał Ciuba Avatar answered Nov 15 '22 05:11

Michał Ciuba