함수 대신 변수를 사용하여 API를 디자인하는 데 문제가 있고 계산 속성을 사용하는 것이 해결 방법처럼 느껴지는 많은 이유를 보았습니다. 인스턴스 변수를 캡슐화해야하는 좋은 이유가 있습니다. 여기에 자동차가 준수하는 프로토콜 자동차를 만들었습니다. 이 프로토콜에는 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를 설계하는 이유의 또 다른 예는 프로토콜에 변수가있는 경우입니다. 저장된 속성을 확장에 배치 할 수없고 클래스에 정의해야한다는 점을 제외하고 모든 프로토콜 기능을 확장으로 나누려면 (컴파일하기 위해 코드를 주석 해제해야합니다.) 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!
수정하십시오.