Petr Mánek
Petr Mánek

Reputation: 1066

Abstract methods in Swift?

I have few questions for Swift developers regarding the concept of abstract classes.

  1. How do you define an abstract class in Swift? Is there any way to prevent a class from being instantiated, while providing an initializer for its subclasses to use?
  2. How do you define abstract methods, while implementing others? When defining abstract methods, Apple generally points you to protocols (interfaces). But they only solve the first part of my question, since all of the methods they define are abstract. What do you do when you want to have both abstract and non-abstract methods in your class?
  3. What about generics? You might have thought about using protocols together with extensions (categories). But then there is an issue with generics because protocols can't have generic types, only typealiases.

I have done my homework and I know about solving these issues using methods, such as fatalError() or preconditionFailure() in the superclass and then overriding them in a base class. But that seems like ugly object design to me.

The reason I'm posting this is to find out whether there exists more general and universal solution.

Thanks in advance, Petr.

Upvotes: 11

Views: 5718

Answers (3)

mojuba
mojuba

Reputation: 12227

How do you define abstract methods, while implementing others?

The "swifty" way of achieving this is combining protocols and extensions, sometimes also typealiases. For data, you are going to define abstract properties in your protocol, then re-define them in a concrete class, then unite all that using a typealias and the & operator:

protocol BaseAbstract: class {
    var data: String { get set }
    func abstractMethod()
    func concreteMethod()
}


extension BaseAbstract {
    // Define your concrete methods that use the abstract part of the protocol, e.g.:
    func concreteMethod() {
        if !data.isEmpty {
            abstractMethod()
        }
    }
}


class BaseImpl {
    // This is required since we can't define properties in extensions.
    // Therefore, we define a class with a concrete property and then 
    // unite it with the protocol above in the typealias below.
    var data: String = "Hello, concrete!"
}


typealias Base = BaseAbstract & BaseImpl // et voila, `Base` is now ready to be subclassed


class Subclass: Base {
    func abstractMethod() { // enforced by the compiler
    }
}

(It can get tricker if you have generics in this scenario. Currently trying to figure it out.)

Upvotes: 1

Kiran K
Kiran K

Reputation: 949

There is no Abstract concept in Swift. But we can achieve that scenario by using Inheritance concept like the code below:

class ParentVC:UIViewController {

    func loadInformation() {
    }
}

class ChildVC:ParentVC {

    // This is an Abstract Method
    override func loadInformation() { 
    }
}

Upvotes: -1

Guillaume Algis
Guillaume Algis

Reputation: 11016

As of today (April 7, 2016), the proposal to introduce abstract classes and methods to Swift (SE-0026) has been deferred.

Joe Groff posted the following in swift-evolution-announce on March 7, 2016:

The proposal has been deferred from Swift 3. Discussion centered around whether abstract classes fit in the direction of Swift as a "protocol-oriented" language. Beyond any religious dogmas, Swift intends to be a pragmatic language that lets users get work done. The fact of the matter today is that one of Swift's primary target platforms is the inheritance-heavy Cocoa framework, and that Swift 2's protocols fall short of abstract classes in several respects [...].

We'd like to revisit this feature once the core goals of Swift 3 have been addressed, so we can more accurately consider its value in the context of a more complete generics implementation, and so we can address the finer points of its design.

I encourage you to read the full email, but I think the conclusion is the same as what you came up with in your question: we're currently stuck with the Objective-C way of doing things (raising exceptions).

Upvotes: 8

Related Questions