Eu já vi várias razões pelas quais projetar uma API usando variáveis em vez de funções é problemático e, para mim, usar propriedades computadas parece uma solução alternativa. Existem boas razões para manter suas variáveis de instância encapsuladas. Aqui eu criei um protocolo Automóvel com o qual o carro está em conformidade. Este protocolo possui um método acessador que retorna um objeto Chassis. Como o carro está em conformidade, a subclasse RaceCar pode substituí-lo e retornar uma subclasse Chassis diferente. Isso permite que a classe Car programe para uma interface (Automóvel) e a classe RaceCar que conhece o RacingChassis pode acessar diretamente a variável _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
}
}
Outro exemplo de por que o design de uma API usando variáveis é interrompido é quando você tem variáveis em um protocolo. Se você quiser dividir todas as funções de protocolo em extensões, você pode, exceto que as propriedades armazenadas não podem ser colocadas em extensões e precisam ser definidas na classe (para compilar isso, você precisa descomentar o código em Classe AdaptableViewController e remova a variável mode da extensão):
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
}
}
O código acima terá este erro do compilador: "As extensões podem não ter propriedades armazenadas". Aqui está como você pode reescrever o exemplo acima, para que tudo no protocolo possa ser separado na extensão usando as funções:
protocol Adaptable {
func mode() -> Int
func adapt()
}
class AdaptableViewController: UIViewController {
}
extension AdaptableViewController: Adaptable {
func mode() -> Int {
return 0
}
func adapt() {
// adapt code
}
}
strong
propriedade e estava recebendo um erro ao tentar substituí-la - mas parece que perdi que isso se traduz em um "opcional implicitamente desembrulhado" (chassis!
) em Swift, entãooverride var chassis : Chassis!
conserta.