Is there a standard way to make a "pure virtual function" in Swift, ie. one that must be overridden by every subclass, and which, if it is not, causes a compile time error?
-
You could implement it in the super class and make an assertion. I've seen this used in Obj-C, Java and Python. – David Skrundz Jun 08 '14 at 22:12
-
9@NSArray This causes a runtime, and not a compile time, error – JuJoDi Jun 08 '14 at 22:35
-
This answer will help you too. [enter link description here](http://stackoverflow.com/questions/24110362/abstract-functions-in-swift-language) – Chamath Jeevan Apr 04 '16 at 10:11
-
A pure virtual function is implemented by `protocol`s (compared to `interface`s in Java) If you need to use them like abstract methods have look at this question/answer: http://stackoverflow.com/a/39038828/2435872 – jboi Aug 19 '16 at 12:23
8 Answers
You have two options:
1. Use a Protocol
Define the superclass as a Protocol instead of a Class
Pro: Compile time check for if each "subclass" (not an actual subclass) implements the required method(s)
Con: The "superclass" (protocol) cannot implement methods or properties
2. Assert in the super version of the method
Example:
class SuperClass {
func someFunc() {
fatalError("Must Override")
}
}
class Subclass : SuperClass {
override func someFunc() {
}
}
Pro: Can implement methods and properties in superclass
Con: No compile time check

- 93,393
- 28
- 139
- 128
-
I like the idea of combining both options. So, you have a superclass that conforms to the protocol while each subclass must have its own implementation. – Jens Wirth Jun 08 '14 at 22:24
-
3
-
6The protocol can't implement methods but you can provide them via extension methods instead. – David Moles Mar 11 '15 at 18:22
-
2As of Swift 2.0 there are now protocol extensions too :) [Apple Reference](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID521). – Ephemera Sep 13 '15 at 09:25
-
The problem of using protocols to emulate Virtual and/or abstract functions is that you would need to both inherit from the template class and adopt the relative protocol, of course being careful of not adopting the protocol in the template class otherwise it would adopt it for the sub-class. All in all a quite complex mechanism and so at the end a useless one. I hope now Swift is open to developers, one of the first action be to implement full-fledged virtual functions! – Fabrizio Bartolomucci Dec 04 '15 at 18:14
-
4While `fatalError` doesn't provide compile-time checking, it is nice that the compiler is at least smart enough to not require you to provide a return value for the method when the execution path calls `fatalError`. – bugloaf Mar 07 '17 at 18:29
-
4*Case 2:* Mind the fact, that if you call `super.someFunc()` from the overridden method, you get the error despite the fact that you overridden it. You know that you are not suppose to call it, but someone else doesn't have to know that and just follow the standard practice. – Jakub Truhlář Jul 13 '18 at 12:46
-
There is also third option. You can pass function as constructor argument. Please check my answer for more details. – Pikacz Dec 29 '20 at 13:03
-
The following allows to inherit from a class and also to have the protocol's compile time check :)
protocol ViewControllerProtocol {
func setupViews()
func setupConstraints()
}
typealias ViewController = ViewControllerClass & ViewControllerProtocol
class ViewControllerClass : UIViewController {
override func viewDidLoad() {
self.setup()
}
func setup() {
guard let controller = self as? ViewController else {
return
}
controller.setupViews()
controller.setupConstraints()
}
//.... and implement methods related to UIViewController at will
}
class SubClass : ViewController {
//-- in case these aren't here... an error will be presented
func setupViews() { ... }
func setupConstraints() { ... }
}

- 1,459
- 1
- 10
- 12
-
4
-
Any way to stop users of this API from deriving their clild classes from ViewControllerClass instead of from ViewController? This is great solution for me because I'll be deriving from my type alias a few years from now and will have forgotten about what functions need to be overridden by then. – David Rector Jan 03 '19 at 21:46
-
1@David Rector, are you able to make your class private and your typealias public? Sorry messaging from my phone, can’t check myself. – ScottyBlades Feb 03 '19 at 18:24
-
1Perfect solution, thank you for that. As underlined by @DavidRector, it would be great if there was a solution to also make it so only the typealias was public, but it doesn't seem to be possible unfortunately. – CyberDandy May 14 '19 at 09:28
-
1
-
Nice! This is the most elegant solution. However, it's still possible to instantiate the base itself. I added an assertion in the init of the base class, i.e: internal init(...) { ... assert(self is ViewController) } Admittedly this doesn't solve the problem, but at least we can detect it early on – Ariel Steiner Nov 25 '21 at 07:12
-
Everyone calls this elegant and perfect solution, probably nice for short term development until you hit what @DavidRector said – Farid Dec 24 '22 at 12:07
There isn't any support for abstract class/ virtual functions, but you could probably use a protocol for most cases:
protocol SomeProtocol {
func someMethod()
}
class SomeClass: SomeProtocol {
func someMethod() {}
}
If SomeClass doesn't implement someMethod, you'll get this compile time error:
error: type 'SomeClass' does not conform to protocol 'SomeProtocol'

- 63,902
- 28
- 145
- 142
-
32Note this only works for the topmost class that implements the protocol. Any subclasses can blithely ignore the protocol requirements. – memmons Oct 15 '15 at 17:05
-
3
Another workaround, if you don't have too many "virtual" methods, is to have the subclass pass the "implementations" into the base class constructor as function objects:
class MyVirtual {
// 'Implementation' provided by subclass
let fooImpl: (() -> String)
// Delegates to 'implementation' provided by subclass
func foo() -> String {
return fooImpl()
}
init(fooImpl: (() -> String)) {
self.fooImpl = fooImpl
}
}
class MyImpl: MyVirtual {
// 'Implementation' for super.foo()
func myFoo() -> String {
return "I am foo"
}
init() {
// pass the 'implementation' to the superclass
super.init(myFoo)
}
}

- 48,006
- 27
- 136
- 235
-
1
-
@xs2bush If more of your methods are virtual than not you're probably better off declaring them in a protocol, and providing the 'non-virtual' ones via extension methods. – David Moles Mar 11 '15 at 18:22
-
1
You can use protocol vs assertion as suggested in answer here by drewag
.
However, example for the protocol is missing. I am covering here,
Protocol
protocol SomeProtocol {
func someMethod()
}
class SomeClass: SomeProtocol {
func someMethod() {}
}
Now every subclasses are required to implement the protocol which is checked in compile time. If SomeClass doesn't implement someMethod, you'll get this compile time error:
error: type 'SomeClass' does not conform to protocol 'SomeProtocol'
Note: this only works for the topmost class that implements the protocol. Any subclasses can blithely ignore the protocol requirements. – as commented by memmons
Assertion
class SuperClass {
func someFunc() {
fatalError("Must Override")
}
}
class Subclass : SuperClass {
override func someFunc() {
}
}
However, assertion will work only in runtime.

- 1
- 1

- 37,929
- 33
- 189
- 256
This is what I usually do, to causes the compile-time error :
class SuperClass {}
protocol SuperClassProtocol {
func someFunc()
}
typealias SuperClassType = SuperClass & SuperClassProtocol
class Subclass: SuperClassType {
func someFunc() {
// ...
}
}

- 143
- 1
- 8
You can achieve it by passing function into initializer.
For example
open class SuperClass {
private let abstractFunction: () -> Void
public init(abstractFunction: @escaping () -> Void) {
self.abstractFunction = abstractFunction
}
public func foo() {
// ...
abstractFunction()
}
}
public class SubClass: SuperClass {
public init() {
super.init(
abstractFunction: {
print("my implementation")
}
)
}
}
You can extend it by passing self as the parameter:
open class SuperClass {
private let abstractFunction: (SuperClass) -> Void
public init(abstractFunction: @escaping (SuperClass) -> Void) {
self.abstractFunction = abstractFunction
}
public func foo() {
// ...
abstractFunction(self)
}
}
public class SubClass: SuperClass {
public init() {
super.init(
abstractFunction: {
(_self: SuperClass) in
let _self: SubClass = _self as! SubClass
print("my implementation")
}
)
}
}
Pro:
- Compile time check for if each subclassimplements the required method(s)
- Can implement methods and properties in superclass
- Note that you can't pass self to the function so you won't get memory leak.
Con:
- It's not the prettiest code
- You can't use it for the classes with
required init

- 431
- 1
- 5
- 10
Being new to iOS development, I'm not entirely sure when this was implemented, but one way to get the best of both worlds is to implement an extension for a protocol:
protocol ThingsToDo {
func doThingOne()
}
extension ThingsToDo {
func doThingTwo() { /* Define code here */}
}
class Person: ThingsToDo {
func doThingOne() {
// Already defined in extension
doThingTwo()
// Rest of code
}
}
The extension is what allows you to have the default value for a function while the function in the regular protocol still provides a compile time error if not defined

- 494
- 4
- 10