Свифт - метод класса, который должен быть переопределен подклассом
есть ли стандартный способ сделать "чистую виртуальную функцию" в Swift, т. е. тот, который должны переопределяется каждым подклассом, и что, если это не так, вызывает ошибку времени компиляции?
5 ответов:
у вас есть два варианта:
1. Используйте протокол
определите суперкласс как протокол вместо класса
Pro: проверка времени компиляции, если каждый "подкласс" (не фактический подкласс) реализует требуемый метод(ы)
Con: на "суперкласс" (протокол) не может реализовать методы или свойства
2. Утверждать в супер версии метод
пример:
class SuperClass { func someFunc() { fatalError("Must Override") } } class Subclass : SuperClass { override func someFunc() { } }
Pro: можно реализовать методы и свойства в суперклассе
Con: нет проверки времени компиляции
нет никакой поддержки абстрактных классов / виртуальных функций, но вы, вероятно, можете использовать протокол для большинства случаев:
protocol SomeProtocol { func someMethod() } class SomeClass: SomeProtocol { func someMethod() {} }
Если SomeClass не реализует someMethod, вы получите эту ошибку времени компиляции:
error: type 'SomeClass' does not conform to protocol 'SomeProtocol'
другой обходной путь, если у вас не слишком много "виртуальных" методов, заключается в том, чтобы подкласс передавал "реализации" в конструктор базового класса как объекты функции:
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) } }
следующее позволяет наследовать от класса, а также иметь проверку времени компиляции протокола:)
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() { ... } }
будучи новичком в разработке iOS, я не совсем уверен, когда это было реализовано, но один из способов получить лучшее из обоих миров-реализовать расширение для протокола:
protocol ThingsToDo { func doThingOne() } extension ThingsToDo { func doThingTwo() { /* Define code here */} } class Person: ThingsToDo { func doThingOne() { // Already defined in extension doThingTwo() // Rest of code } }
расширения, что позволяет вам иметь значение по умолчанию для функции, а функция в обычном протоколе все равно дает ошибку времени компиляции, если не определено