swiftinheritanceoverriding

Overriding @objc method from superclass


I want to override an @objc method in my derived class. The method declaration is the exact same as in the superclass:

class Test: DGCharts.LineChartView {
    @objc private func doubleTapGestureRecognized(_ recognizer: NSUITapGestureRecognizer)
    {
    }
}

This fails, obviously:

Method 'doubleTapGestureRecognized' with Objective-C selector 'doubleTapGestureRecognized:' conflicts with method 'doubleTapGestureRecognized' from superclass 'BarLineChartViewBase' with the same Objective-C selector

But if I add override:

class Test: DGCharts.LineChartView {
    @objc override private func doubleTapGestureRecognized(_ recognizer: NSUITapGestureRecognizer)
    {
    }
}

Then it does not work either:

Method does not override any method from its superclass

Why? Is there an issue with the method being private, or that it is @objc, or ...?


Solution

  • The private access control prevents you from overriding the method. There is also a doubleTapGestureRecognized version in DGCharts, specifically in BarLineChartViewBase.

    You can make a quick example to see how it work:

    class Bar {
        @objc private func foo() { }
    }
    
    class Bar2: Bar {
        @objc func foo() { } //an error occurs here
    
        @objc override func foo() { } //an error occurs here
    }
    

    And then try to remove private:

    class Bar {
        @obj func foo() { }
    }
    
    class Bar2: Bar {
        @objc override func foo() { } //OK
    }
    

    The difference in this scenario with @objc is that, if both sub-class and parent-class have the same method, it will cause conflict. It works fine without @objc:

    class Bar {
        private func foo() { }
    }
    
    class Bar2: Bar {
        func foo() { } //OK
    }
    

    So, since the doubleTapGestureRecognized private method was inside the framework, you cannot override it, it must be open.