metodo - que es self en swift
Método de clase Swift que debe ser anulado por subclase (5)
¿Existe una forma estándar de hacer una "función virtual pura" en Swift, es decir. uno que debe ser anulado por cada subclase, y que, si no lo es, provoca un error de tiempo de compilación?
Lo siguiente permite heredar de una clase y también tener la verificación del tiempo de compilación del protocolo :)
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() { ... }
}
No hay soporte para clases abstractas / funciones virtuales, pero probablemente podría usar un protocolo para la mayoría de los casos:
protocol SomeProtocol {
func someMethod()
}
class SomeClass: SomeProtocol {
func someMethod() {}
}
Si SomeClass no implementa SomeMethod, obtendrá este error de tiempo de compilación:
error: type ''SomeClass'' does not conform to protocol ''SomeProtocol''
Otra solución, si no tiene demasiados métodos "virtuales", es hacer que la subclase pase las "implementaciones" al constructor de la clase base como objetos de función:
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)
}
}
Siendo nuevo en el desarrollo de iOS, no estoy del todo seguro de cuándo se implementó esto, pero una forma de obtener lo mejor de ambos mundos es implementar una extensión para un protocolo:
protocol ThingsToDo {
func doThingOne()
}
extension ThingsToDo {
func doThingTwo() { /* Define code here */}
}
class Person: ThingsToDo {
func doThingOne() {
// Already defined in extension
doThingTwo()
// Rest of code
}
}
La extensión es lo que le permite tener el valor predeterminado para una función mientras que la función en el protocolo regular aún proporciona un error de tiempo de compilación si no está definido
Tienes dos opciones:
1. Usa un protocolo
Defina la superclase como un protocolo en lugar de una clase
Pro : Comprobación de tiempo de compilación para si cada "subclase" (no una subclase real) implementa el (los) método (s) requerido (s)
Con : La "superclase" (protocolo) no puede implementar métodos o propiedades
2. Afirmar en la versión súper del método
Ejemplo:
class SuperClass {
func someFunc() {
fatalError("Must Override")
}
}
class Subclass : SuperClass {
override func someFunc() {
}
}
Pro : puede implementar métodos y propiedades en superclase
Con : No hay tiempo de compilación