Swift is really very powerful language, but for developers coming from other OO languages it might be a bit tricky sometimes (for example: absence of abstract classes) and sometimes has neat features for which developers usually don't know util they come to the problem. One of such things is method overriding - it works the same way for procedures (void) and functions (return value). For easier demonstration purposes in playgrounds functions will be used.
Methods can be distinguished as follows:
- instance methods: can be called on instance. Unless the method has final keyword in the declaration it can be overridden in the child class (subclass).
- static methods: can be called on class. This methods are internally marked as final, so they cannot be overridden by the child class (subclass).
- class methods: can be called on class. Unless the method has final keyword in the declaration it can be overridden in the child class (subclass).
class Parent { // Multiplies input parameter by 100 func instanceFunction(parameter: Int) -> Int { return parameter * 100 } // Subscracts from input parameter 10 (class function) static func staticFunction(parameter: Int) -> Int { return parameter - 10 } // Multiplies parameters with itself class func classFunction(parameter: Int) -> Int { return parameter * parameter } } class Child : Parent { // Multiplies input parameter by 100 (call to parent) and substracts 100 override func instanceFunction(parameter: Int) -> Int { let result = super.instanceFunction(parameter) return result - 100 } // Static functions are final so this is not possible - solution? /*override static func staticFunction(parameter: Int) -> Int { return result - 9 }*/ // Multiplies parameter with itself and substracts 1 override class func classFunction(parameter: Int) -> Int { let result = super.classFunction(10) return result - 1 } } // Instance functions override let parent = Parent() let child = Child() print(parent.instanceFunction(10)) print(child.instanceFunction(10)) // Static functions override print(Parent.staticFunction(10)) print(Child.staticFunction(10)) // Call the same implementation ... // Class functions override print(Parent.classFunction(10)) print(Child.classFunction(10))
There are interesting consequences of the example code from above:
- to prevent overriding of instance or class (marked with class) methods use final keyword
- class method marked as final behaves the same way as static method
- when using OO principles it happens many times that we override method of parent class. In the overridden method (in child) so often also call method of parent (super-class). The interesting thing is, that this can be done for instance and class methods by using the same reserved word - super. The only thing I am asking myself is, why having static and class methods, if the same behaviour can be achieved by using class methods...
The possibility of overriding class methods is Swift's very neat feature - it is not supported in all popular languages, for example in Java. In Java we have only static methods and static method with the same name can be defined in both parent and subclass, but this is not real overriding. It is also not possible to invoke method of the parent class via super (for static methods only) without hardcoding the class name. Please note: Java has tremendously powerful reflection API and via it - it is possible to solve this problem, but this is not something what you would like to use on daily basis :)
public class Parent { public static int staticFunction(int parameter) { return parameter * parameter; } } public class Child extends Parent { public static int staticFunction(int parameter) { int result = Parent.staticFunction(parameter); return result - 1; } }