19

I've a base class that implements an extension that conforms to a protocol as below:

protocol OptionsDelegate {
    func handleSortAndFilter(opt: Options)
}

extension BaseViewController: OptionsDelegate {
    func handleSortAndFilter(opt: Options) {
        print("Base class implementation")
    }
}

I've a subclass "InspirationsViewController" that inherits from BaseViewController. And I'm overriding protocol method in the extension as below:

extension InspirationsViewController {
    override func handleSortAndFilter(opt: Options) {
        print("Inside inspirations")
    }
}

I'm getting error when I override "handleSortAndFilter" function in subclass extension: "Declerations in extensions cannot override yet"

But I'm not seeing similar problem when I implemented UITableView datasource and delegate methods.

How to avoid this error?

Satyam
  • 15,493
  • 31
  • 131
  • 244
  • `InspirationsViewController` is not a subclass, its an extension. I think you defined it wrong. It should be a class `InspirationsViewController: BaseViewController` – Hossam Ghareeb Dec 27 '16 at 11:31
  • 2
    @HossamGhareeb he already said `InspirationsViewController` is subclass of `BaseViewController` , this is extension for it. This problem is probably haven't got implemented in Swift, you should do override from main class, extension is for adding more function – Tj3n Dec 27 '16 at 11:34
  • In extension we can not override methods of the super class. – Aman Gupta Dec 27 '16 at 11:39
  • Please post the class definitions also. The code compiles fine here adding `class BaseViewController: UIViewController{}` and `class InspirationsViewController: BaseViewController {}`. – shallowThought Dec 27 '16 at 12:19
  • @shallowThought, Class declaration that you mentioned is correct. – Satyam Dec 27 '16 at 12:36

2 Answers2

27

Use protocol extension with where clause. It works. But I would not recommend you to have such things in your codebase.

class BaseViewController: UIViewController {

}

extension OptionsDelegate where Self: BaseViewController {
  func handleSortAndFilter(opt: Options) {
    print("Base class implementation")
  }
}

extension BaseViewController: OptionsDelegate {

}

class InsipartionsViewController: BaseViewController {

}

extension OptionsDelegate where Self: InsipartionsViewController {
  func handleSortAndFilter(opt: Options) {
    print("Inspirations class implementation")
  }
}
Igor Bidiniuc
  • 1,540
  • 1
  • 16
  • 27
  • Thanks a lot for the answer. Can you please provide some explanation to understand the implementation? – Satyam Dec 27 '16 at 12:18
  • 1
    Its compiling perfect. But its never calling override function implemented in "InsipartionsViewController". – Satyam Dec 27 '16 at 12:35
  • https://talk.objc.io/episodes/S01E29-protocols-class-hierarchies checkout this video about protocols and class hierarchies in swift. – Igor Bidiniuc Dec 28 '16 at 11:52
  • Hmmm. I tried this, but I'm not able to call the protocol method. E.g., let x = InsipartionsViewController(); x.handleSortAndFilter(opt:...) doesn't compile for me. – Chris Prince Jul 11 '17 at 03:41
  • Ah. Got it now, I had to make UIViewController abide by the protocol. – Chris Prince Jul 11 '17 at 03:44
  • This is great! Unfortunately the methods cannot access internal properties (private) to the class. Ex: it can't access private vars in InspirationsViewController – TheJeff Dec 27 '20 at 00:29
5

As far as I know you can't override methods in extensions. Extensions can only do the following: “Extensions in Swift can:

  • Add computed instance properties and computed type properties
  • Define instance methods and type methods
  • Provide new initializers
  • Define subscripts
  • Define and use new nested types
  • Make an existing type conform to a protocol”

Excerpt From: Apple Inc. “The Swift Programming Language (Swift 3.0.1).”

Hossam Ghareeb
  • 7,063
  • 3
  • 53
  • 64