Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Abstract functions in Swift Language

People also ask

What are abstract functions?

An abstraction function maps a state of the concrete machine to a state of the abstract machine. It explains how to interpret each state of the concrete machine as a state of the abstract machine. It solves the problem of the concrete and abstract machines having different sets of states.

Are there abstract classes in Swift?

There are no abstract classes in Swift (just like Objective-C). Your best bet is going to be to use a Protocol, which is like a Java Interface. With Swift 2.0, you can then add method implementations and calculated property implementations using protocol extensions.

Does Swift support abstraction?

Abstract classes aren't supported in Swift and this solution is nothing more than an attempt to patch the absence of abstract classes in Swift. A more important downside is that a missing implementation isn't detected at compile time. Which method is invoked is decided at runtime through dynamic dispatch.

How do you declare an abstract function?

To declare an abstract method, use this general form: abstract type method-name(parameter-list); As you can see, no method body is present. Any concrete class(i.e. class without abstract keyword) that extends an abstract class must override all the abstract methods of the class.


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
     } 
}

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() {
    }
}

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.


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.

1. Put the abstract method in a protocol
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 implements UITableViewDelegate but still needs to be registers as delegate by explicitely setting the delegate property.
  • This all is tested on Playground of Xcode 7.3.1

One way of doing this is to use an optional closure defined in the base class, and the children can choose to implement it or not.

class BaseClass {
    var abstractClosure?:(()->())?
    func someFunc()
    {
        if let abstractClosure=abstractClosure
        {
            abstractClosure()
        }
    } 
}

class SubClass : BaseClass {
    init()
    {
        super.init()
        abstractClosure={ ..... }
    }
}

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.


I understand what you're doing now, I think you'd be better off using a protocol

protocol BaseProtocol {
    func abstractFunction()
}

Then, you just conform to the protocol:

class SubClass : BaseProtocol {

    func abstractFunction() {
        // Override
        println("Override")
    }
}

If you class is also a subclass, protocols follow the Superclass:

class SubClass: SuperClass, ProtocolOne, ProtocolTwo {}