İşlevler yerine değişkenler kullanarak bir API tasarlamanın neden sorunlu olduğuna dair birçok neden gördüm ve hesaplanmış özellikleri kullanmak bana geçici bir çözüm gibi geliyor. Örnek değişkenlerinizi kapsüllenmiş halde tutmak için iyi nedenler vardır. Burada Arabanın uyduğu bir Otomobil protokolü oluşturdum. Bu protokol, bir Chassis nesnesi döndüren bir erişimci yöntemine sahiptir. Araba buna uygun olduğundan, RaceCar alt sınıfı onu geçersiz kılabilir ve farklı bir Şasi alt sınıfı döndürebilir. Bu, Car sınıfının bir arabirime (Otomobil) programlamasına olanak tanır ve RacingChassis hakkında bilgi sahibi olan RaceCar sınıfı, _racingChassis değişkenine doğrudan erişebilir.
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
}
}
Değişkenler kullanarak bir API tasarlamanın neden bozulduğuna dair başka bir örnek, bir protokoldeki değişkenlere sahip olduğunuz zamandır. Tüm protokol işlevlerini bir uzantıya bölmek isterseniz, depolanan özelliklerin uzantılara yerleştirilememesi ve sınıfta tanımlanması gerekmesi dışında (bunu derlemek için kodun açıklamasını kaldırmanız gerekir) AdaptableViewController sınıfı ve mod değişkenini uzantıdan kaldırı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
}
}
Yukarıdaki kodda şu derleyici hatası olacaktır: "Uzantıların depolanmış özellikleri olmayabilir". Protokoldeki her şeyin işlevler kullanılarak uzantıda ayrılması için yukarıdaki örneği nasıl yeniden yazabileceğiniz aşağıda açıklanmıştır:
protocol Adaptable {
func mode() -> Int
func adapt()
}
class AdaptableViewController: UIViewController {
}
extension AdaptableViewController: Adaptable {
func mode() -> Int {
return 0
}
func adapt() {
// adapt code
}
}
strong
özelliği olan bir Objective-C sınıfı ve onu geçersiz kılmaya çalışırken bir hata alıyordum - ancak bunun "örtük olarak açılmamış isteğe bağlı" (chassis!
) Swift, bu yüzdenoverride var chassis : Chassis!
düzeltir.