関数の代わりに変数を使用してAPIを設計することが問題であり、計算されたプロパティを使用することが回避策のように思える多くの理由を見てきました。インスタンス変数をカプセル化しておくことには十分な理由があります。ここでは、Carが準拠するプロトコルAutomobileを作成しました。このプロトコルには、Chassisオブジェクトを返すアクセサーメソッドがあります。Carはそれに準拠しているので、RaceCarサブクラスはそれをオーバーライドして、別のChassisサブクラスを返すことができます。これにより、Carクラスはインターフェース(Automobile)にプログラムでき、RacingChassisを認識しているRaceCarクラスは_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
}
}
変数を使用してAPIを設計すると失敗するもう1つの例は、プロトコルに変数がある場合です。すべてのプロトコル関数を拡張機能に分割したい場合は、保存されたプロパティを拡張機能に配置できず、クラスで定義する必要があります(これをコンパイルするには、コードのコメントを外す必要があります) AdaptableViewControllerクラスとモード変数を拡張機能から削除します):
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
}
}
上記のコードには、「拡張機能にプロパティが格納されていない可能性があります」というコンパイラエラーが発生します。上記の例を書き換えて、代わりに関数を使用して、プロトコルのすべてを拡張機能で分離できるようにする方法は次のとおりです。
protocol Adaptable {
func mode() -> Int
func adapt()
}
class AdaptableViewController: UIViewController {
}
extension AdaptableViewController: Adaptable {
func mode() -> Int {
return 0
}
func adapt() {
// adapt code
}
}
strong
プロパティを持つObjective-Cクラスであり、それをオーバーライドしようとしてエラーが発生したため、問題が発生chassis!
しました。スウィフト、それをoverride var chassis : Chassis!
修正します。