Swift - class method which must be overridden by subclass

我只是一个虾纸丫 提交于 2020-01-19 04:38:16

问题


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?


回答1:


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




回答2:


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

}



回答3:


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'



回答4:


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



回答5:


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.




回答6:


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



来源:https://stackoverflow.com/questions/24111356/swift-class-method-which-must-be-overridden-by-subclass

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!