He visto muchas razones por las que diseñar una API usando variables en lugar de funciones es problemático y para mí el uso de propiedades calculadas se siente como una solución alternativa. Hay buenas razones para mantener sus variables de instancia encapsuladas. Aquí he creado un protocolo de automóvil con el que se ajusta el automóvil. Este protocolo tiene un método de acceso que devuelve un objeto Chassis. Dado que Car lo cumple, la subclase RaceCar puede anularlo y devolver una subclase de Chasis diferente. Esto permite que la clase Car programe en una interfaz (Automóvil) y la clase RaceCar que conoce sobre RacingChassis puede acceder directamente a la variable _racingChassis.
class Chassis {}
class RacingChassis: Chassis {}
protocol Automobile {
func chassis() -> Chassis
}
class Car: Automobile {
private var _chassis: Chassis
init () {
_chassis = Chassis()
}
func chassis() -> Chassis {
return _chassis
}
}
class RaceCar: Car {
private var _racingChassis: RacingChassis
override init () {
_racingChassis = RacingChassis()
super.init()
}
override func chassis() -> Chassis {
return _racingChassis
}
}
Otro ejemplo de por qué el diseño de una API usando variables se desglosa es cuando tienes variables en un protocolo. Si desea dividir todas las funciones del protocolo en extensiones, puede hacerlo, excepto que las propiedades almacenadas no se pueden colocar en extensiones y deben definirse en la clase (para obtener esto para compilar, debe descomentar el código en AdaptableViewController clase y eliminar la variable de modo de la extensión):
protocol Adaptable {
var mode: Int { get set }
func adapt()
}
class AdaptableViewController: UIViewController {
// var mode = 0
}
extension AdaptableViewController: Adaptable {
var mode = 0 // compiler error
func adapt() {
//TODO: add adapt code
}
}
El código anterior tendrá este error de compilación: "Las extensiones pueden no tener propiedades almacenadas". Así es como puede volver a escribir el ejemplo anterior para que todo en el protocolo pueda separarse en la extensión mediante el uso de funciones:
protocol Adaptable {
func mode() -> Int
func adapt()
}
class AdaptableViewController: UIViewController {
}
extension AdaptableViewController: Adaptable {
func mode() -> Int {
return 0
}
func adapt() {
// adapt code
}
}
strong
propiedad y recibí un error al intentar anularlo, pero parece que me perdí que se traduce en un "opcional implícitamente sin envolver" (chassis!
) en Rápido, asíoverride var chassis : Chassis!
que lo arregla.