Abstract functions in Swift Language
Solution 1
There no concept of abstract in Swift (like Objective-C) but you can do this :
class BaseClass {
func abstractFunction() {
preconditionFailure("This method must be overridden")
}
}
class SubClass : BaseClass {
override func abstractFunction() {
// Override
}
}
Solution 2
What you want is not a base class, but a protocol.
protocol MyProtocol {
func abstractFunction()
}
class MyClass : MyProtocol {
func abstractFunction() {
}
}
If you don't supply abstractFunction in your class it's an error.
If you still need the baseclass for other behaviour, you can do this:
class MyClass : BaseClass, MyProtocol {
func abstractFunction() {
}
}
Solution 3
I port a fair amount of code from a platform that supports abstract base classes to Swift and run in to this a lot. If what you truly want is the functionality of an abstract base class, then that means that this class serves both as an implementation of shared based class functionality (otherwise it would just be an interface/protocol) AND it defines methods that must be implemented by derived classes.
To do that in Swift, you will need a protocol and a base class.
protocol Thing
{
func sharedFunction()
func abstractFunction()
}
class BaseThing
{
func sharedFunction()
{
println("All classes share this implementation")
}
}
Note that the base class implements the shared method(s), but does not implement the protocol (since it doesn't implement all of the methods).
Then in the derived class:
class DerivedThing : BaseThing, Thing
{
func abstractFunction()
{
println("Derived classes implement this");
}
}
The derived class inherits sharedFunction from the base class, helping it satisfy that part of the protocol, and the protocol still requires the derived class to implement abstractFunction.
The only real downside to this method is that since the base class does not implement the protocol, if you have a base class method that needs access to a protocol property/method you will have to override that in the derived class, and from there call the base class (via super) passing self
so that the base class has an instance of the protocol with which to do its work.
For example, lets say that sharedFunction needed to call abstractFunction. The protocol would stay the same, and the classes would now look like:
class BaseThing
{
func sharedFunction(thing: Thing)
{
println("All classes share this implementation")
thing.abstractFunction()
}
}
class DerivedThing : BaseThing, Thing
{
func sharedFunction()
{
super.sharedFunction(self)
}
func abstractFunction()
{
println("Derived classes implement this");
}
}
Now the sharedFunction from the derived class is satisfying that part of the protocol, but the derived class is still able to share the base class logic in a reasonably straightforward way.
Solution 4
This one seems to be the "official" way how Apple is handling abstract methods in UIKit.
Take a look at UITableViewController
and the way it's working with UITableViewDelegate
. One of the very first things you do, is to add a line: delegate = self
. Well, that's exactly the trick.
protocol AbstractMethodsForClassX {
func abstractMethod() -> String
}
2. Write your base class
/// It takes an implementation of the protocol as property (same like the delegate in UITableViewController does)
/// And does not implement the protocol as it does not implement the abstract methods. It has the abstract methods available in the `delegate`
class BaseClassX {
var delegate: AbstractMethodsForClassX!
func doSomethingWithAbstractMethod() -> String {
return delegate.abstractMethod() + " - And I believe it"
}
}
3. Write the Subclass(es).
/// First and only additional thing you have to do, you must set the "delegate" property
class ClassX: BaseClassX, AbstractMethodsForClassX {
override init() {
super.init()
delegate = self
}
func abstractMethod() -> String {return "Yes, this works!"}
}
Here is, how to you use all that
let x = ClassX()
x.doSomethingWithAbstractMethod()
Check with Playground to see the output.
Some Remarks
- First, a lot of answers were given already. I hope somebody finds all the way down to this one.
- The question actually was, to find a pattern that implements:
- A class calls a method, that has to be implemented in one of its derived subclasses (overridden)
- In best case, if the method is not overridden in the subclass, get an error during compile time
- The thing about abstract methods is, that they're a mixture of an interface definition and part of an actual implementation in the base class. Both at the same time. As swift is very new and very clean defined, it has no such convienience but "unclean" concepts (yet).
- To me (a poor old Java guy), this problem evolves from time to time. I've read thru all the answers in this post and this time I think I found a pattern, that looks feasable - at least to me.
- Update: It looks like the UIKit implementers at Apple use the same pattern.
UITableViewController
implementsUITableViewDelegate
but still needs to be registers as delegate by explicitely setting thedelegate
property. - This all is tested on Playground of Xcode 7.3.1
Solution 5
Well, I know that I am late to the game and that I might be taking advantage of the changes that have happened. Sorry about that.
In any case, I would like to contribute my answer, because I love doing testing and the solutions with fatalError()
is, AFAIK, not testable and the ones with exceptions are much harder to test.
I would suggest to use a more swifty approach. Your goal is to define an abstraction that has some common details, but that is not fully defined, i.e. the abstract method(s). Use a protocol that defines all the expected methods in the abstraction, both the ones that are defined, and also the ones that aren't. Then create a protocol extension that implements the methods that are defined in your case. Finally, any derived class must implement the protocol, which means all the methods, but the ones that are part of the protocol extension already have their implementation.
Extending your example with one concrete function:
protocol BaseAbstraction {
func abstractFunction() {
// How do I force this function to be overridden?
}
}
extension BaseAbstraction {
func definedFunction() {
print("Hello")
}
class SubClass : BaseAbstraction {
func abstractFunction() {
// No need to "Override". Just implement.
}
}
Notice that by doing this, the compiler is again your friend. If the method is not "overridden", you will get an error at compile time, instead of the ones that you would get with fatalError()
or exceptions that would happen at run time.
![kev](https://i.stack.imgur.com/hgDHG.jpg?s=256&g=1)
kev
Updated on August 20, 2020Comments
-
kev almost 4 years
I'd like to create an abstract function in swift language. Is it possible?
class BaseClass { func abstractFunction() { // How do I force this function to be overridden? } } class SubClass : BaseClass { override func abstractFunction() { // Override } }
-
David Berry about 10 yearsThis is pretty close to your other question but the answer here seems a little better.
-
kev about 10 yearsThe questions are similar but the solutions are far different because a abstract class has different use cases than an abstract function.
-
David Berry about 10 yearsYep, why I didn't vote to close either, but the answers there won't be useful beyond "you can't" Here you got the best available answer :)
-
-
Erik about 10 yearsAlternatively you can use
assert(false, "This method must be overriden by the subclass")
. -
nathan about 10 yearsor
fatalError("This method must be overridden")
-
André Fratelli almost 10 yearsassertions will require a return statement when a method has a return type. I think fatalError() is better for this one reason
-
JeremyP almost 10 yearsAssertions also seem not to be compiled in for release builds.
-
JeremyP almost 10 yearsApparently, neither is
fatalError()
-
Jageen over 9 years@jaumard If you write something like (No concept of abstract in swift) reference link from apple is appreciated.
-
Dan Rosenstark over 9 yearsGreat understanding and good depth on the "the base class does not implement the protocol"... which is kind of the point of an abstract class. I'm baffled that this basic OO feature is missing, but then again, I was raised on Java.
-
bandejapaisa over 9 yearsThis doesn't quite work. If BaseClass wants to call those empty functions, then it would also have to implement the protocol, and then implement the functions. Also the subclass still isn't forced to implement the functions at compile time, and you not compelled to implement the protocol either.
-
Steve Waddicor over 9 yearsBaseclass has nothing to do with the protocol. I said "for other behaviour". The protocol is introduced for MyClass. As to not being forced to implement at compile time, you clearly haven't actually tried it.
-
bandejapaisa over 9 yearsThat's my point.... BaseClass has nothing to do with the protocol, and to act like an abstract class it should have something to do with it. To clarify what I wrote "If BaseClass wants to call those empty functions, then it would also have to implement the protocol which would force you to implement the functions - which then leads to the Subclass not being forced to implement the functions at compile time, because the BaseClass has already done it".
-
Steve Waddicor over 9 yearsBaseclass has nothing to do with the protocol. Making it so would be changing the code I presented. There is nothing wrong with the code given.
-
Steve Waddicor over 9 yearsTo be clear, an abstract function has two features: It no functionality, and it must be overridden. In Swift this is provided by a protocols. There is no other way. Certain other languages allow a base thingy to provide both abstract functions and ordinary virtual functions. Baseclass appears in my example to indicate this is possible with swift but requires both a protocol AND a base class to achieve. "It doesn't quite work" is nonsense. It works perfectly. If you want to say that Swift doesn't provide abstract funcs in the same way as some other particular language, well that's different.
-
Steve Waddicor over 9 yearsIt is an abstract function in the Swift language. Period. It works perfectly. That it isn't the same as some other unnamed language you're used to is irrelevant.
-
Joshcodes over 9 yearsDo you mean
AbstractMethodException().raise()
? -
André Fratelli over 9 yearsErr... Probably. I can't test right now, but if it works that way, than yes
-
Kametrixom about 9 yearsAlso there is
preconditionFailure("Bla bla bla")
in Swift which will execute in release builds and also eliminates the need of a return statement. EDIT: Just found out that this method basically is equal tofatalError()
but it's the more proper way (Better documentation, introduced in Swift along withprecondition()
,assert()
andassertionFailure()
, read here) -
LoveMeow about 9 yearswhat if the function has a return type?
-
ProgrammierTier almost 9 yearsWhat I like about this approach is that I don't have to remember to implement a protocol in the inheriting class. I have a base class for my ViewControllers, and this is how I enforce ViewController specific, optional functionality (e.g. app became active, etc.) that might get invoked by base class functionality.
-
Puppy almost 9 yearsThat really depends on how you define "abstract". The whole point of an abstract function is that you can put it on a class that can do normal class things. For example, the reason I want this is because I need to define a static member which you can't seem to do with protocols. So it's hard for me to see that this meets the useful point of an abstract function.
-
Glenn Howes over 8 yearsI think you can use a combination of Protocols and the new Protocol Extensions to get a better solution than abstract base classes.
-
David James over 8 yearsI think the concern with the upvoted comments above is that this does not conform to the Liskov Substitution principle which states "objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program." It's assumed this is an abstract type. This is particularly important in the case of Factory Method pattern where the base class is responsible for creating and storing properties that originate from the sub class.
-
Fabrizio Bartolomucci over 8 yearsYet the implementation does not allow to seamlessly implement the Template Function method where the template method calls a wide number of abstract methods implemented in the subclasses. In this case you should write them both as normal methods in the super class, as methods in the protocol and again as implementations in the subclass. In practice you have to write three times the same stuff and only rely on the override check to be sure of not making any disastrous misspelling! I really hope now that Swift is open to developers, full-fledged abstract function shall be introduces.
-
Fabrizio Bartolomucci over 8 yearsThe benefit of abstract methods is that the checks are done at compile time.
-
Shoerob over 7 yearsAn abstract base class and a protocol are not the same thing.
-
Shoerob over 7 yearsSo much time, and code could be saved by introducing the "protected" keyword.
-
Radian Jheng about 7 yearsIf the instance of the SubClass is upCasted to BaseClass, it will call the methods of BaseClass. This is not a good way to do implement abstract methods.
-
Christophe about 7 yearsThis main feature of an abstract class is that there is a compile time check to prevent it from getting instantiated, and the same for the derived (abstract) classes which haven't overridden the pure virtual function. While this solution is a nice work around, it transfers this check to runtime. This is nicely explained by Apple here: github.com/apple/swift-evolution/blob/master/proposals/…
-
Zaporozhchenko Oleksandr over 6 yearsdon't use assert, because on archiving, u will get 'Missing return in a function expected to return' error. Use fatalError("This method must be overriden by the subclass")
-
Tomasz Nazarenko over 6 yearsMaybe not perfect, because I have problems hiding the interface of the class from other classes, but this is enough what I needed to implement classic Factory Method in Swift.
-
Jake T. over 6 yearsHmmm. I like the looks of this answer a lot more, but I'm also not sure it's suitable. I.e., I have a ViewController that can be displaying information for a handful of different types of objects, but the purpose of displaying that information is all the same, with all the same methods, but pulling and putting together the information differently based on the object. So, I have a parent delegate class for this VC, and a subclass of that delegate for each type of object. I instantiate a delegate based on the object passed in. In one example, each object has some relevant comments stored.
-
Jake T. over 6 yearsSo I have a
getComments
method on the parent delegate. There's a handful of comment types, and I want the ones relevant to each object. So, I want the subclasses to not compile when I dodelegate.getComments()
if I don't override that method. The VC just knows it has aParentDelegate
object calleddelegate
, orBaseClassX
in your example, butBaseClassX
does not have the abstracted method. I'd need the VC to specifically know that it is using theSubclassedDelegate
. -
jboi over 6 yearsI hope I understand you right. If not, do you mind to ask a new question where you can add some code? I think you just need to have an if-statement in ‚doSomethingWithAbstractMethod‘ checking, if delegate is set or not.
-
Apfelsaft almost 6 yearsImo the best answer.
-
joehinkle11 over 4 yearsGood answer, but your base abstraction isn't capable on storing properties, however
-
Enricoza over 4 yearsAlso if you want to call an "abstract" method in another method inside your base class you will end up calling your base method even if it is actually overridden.
-
Enricoza over 4 yearsIt' worth mentioning that assigning self to the delegate creates a retain cycle. Maybe it's better to declare it as weak (which is commonly a good idea for delegates)