컴파일러가 저장된 속성을 다른 저장된 값으로 재정의하는 것을 허용하지 않는다는 것을 알았습니다 (이상하게 보입니다).
class Jedi {
var lightSaberColor = "Blue"
}
class Sith: Jedi {
override var lightSaberColor = "Red" // Cannot override with a stored property lightSaberColor
}
그러나 계산 된 속성으로이 작업을 수행 할 수 있습니다.
class Jedi {
let lightSaberColor = "Blue"
}
class Sith: Jedi {
override var lightSaberColor : String{return "Red"}
}
다른 가치를 부여 할 수없는 이유는 무엇입니까?
저장된 속성으로 재정의하는 것이 혐오스러운 일이고 계산 된 코셔로하는 이유는 무엇입니까? 그들은 무엇을 생각합니까?
답변
다른 가치를 부여 할 수없는 이유는 무엇입니까?
상속 된 속성에 다른 값을 부여 할 수 있습니다. 해당 초기 값을 사용하는 생성자에서 속성을 초기화하고 파생 클래스에서 다른 값을 전달하면이 작업을 수행 할 수 있습니다.
class Jedi {
// I made lightSaberColor read-only; you can make it writable if you prefer.
let lightSaberColor : String
init(_ lsc : String = "Blue") {
lightSaberColor = lsc;
}
}
class Sith : Jedi {
init() {
super.init("Red")
}
}
let j1 = Jedi()
let j2 = Sith()
println(j1.lightSaberColor)
println(j2.lightSaberColor)
속성을 재정의하는 것은 새 값을 제공하는 것과는 다릅니다. 클래스에 다른 속성을 제공하는 것과 비슷합니다. 실제로는 계산 된 속성을 재정의 할 때 발생합니다. 기본 클래스의 속성 을 계산하는 코드는 파생 클래스의 해당 속성에 대한 재정의를 계산하는 코드 로 대체 됩니다.
실제 저장된 속성을 재정의 할 수
lightSaberColor
있습니까? 즉, 다른 동작이 있습니까?
관찰자 외에 저장된 속성에는 동작이 없으므로 실제로 재정의 할 것이 없습니다. 위에 설명 된 메커니즘을 통해 속성에 다른 값을 부여 할 수 있습니다. 이것은 다른 구문으로 질문의 예가 달성하려는 것을 정확히 수행합니다.
답변
나를 위해 귀하의 예제는 Swift 3.0.1에서 작동하지 않습니다.
놀이터에이 코드를 입력했습니다.
class Jedi {
let lightsaberColor = "Blue"
}
class Sith: Jedi {
override var lightsaberColor : String {
return "Red"
}
}
Xcode에서 컴파일 타임에 오류가 발생합니다.
변경 불가능한 ‘let’속성 ‘lightsaberColor’를 ‘var’의 getter로 재정의 할 수 없습니다.
아니요, 저장된 속성의 유형을 변경할 수 없습니다. Liskov Substitution Principle 은 수퍼 클래스가 필요한 곳에서 서브 클래스가 사용되도록 강제 합니다.
그러나이를로 변경 하여 계산 된 속성에 var
추가하는 set
경우 동일한 유형의 계산 된 속성으로 저장된 속성을 재정의 할 수 있습니다.
class Jedi {
var lightsaberColor = "Blue"
}
class Sith: Jedi {
override var lightsaberColor : String {
get {
return "Red"
}
set {
// nothing, because only red is allowed
}
}
}
이것은 저장된 속성에서 계산 된 속성으로 전환하는 것이 합리적 일 수 있기 때문에 가능합니다.
그러나 저장된 var
속성을 저장된 속성으로 재정의하는 var
것은 의미가 없습니다. 속성 값만 변경할 수 있기 때문입니다.
그러나 저장된 속성을 저장된 속성으로 재정의 할 수는 없습니다.
나는 Sith가 Jedi라고 말하지 않을 것이다 :-P. 따라서 이것이 작동하지 않는다는 것이 분명합니다.
답변
class SomeClass {
var hello = "hello"
}
class ChildClass: SomeClass {
override var hello: String {
set {
super.hello = newValue
}
get {
return super.hello
}
}
}
답변
속성에 다른 값을 지정하고 싶을 것입니다.
class Jedi {
var lightSaberColor = "Blue"
}
class Sith: Jedi {
override init() {
super.init()
self.lightSaberColor = "Red"
}
}
답변
Swift 4의 경우 Apple 문서에서 :
상속 된 인스턴스 또는 유형 속성을 재정 의하여 해당 속성에 대한 고유 한 사용자 정의 getter 및 setter를 제공하거나 재정의 속성이 기본 속성 값이 변경 될 때 관찰 할 수 있도록 속성 관찰자를 추가 할 수 있습니다.
답변
Swift에서는 안타깝게도 불가능합니다. 가장 좋은 대안은 다음과 같습니다.
class Jedi {
private(set) var lightsaberColor = "Blue"
}
class Sith: Jedi {
override var lightsaberColor : String {
get {
return "Red"
}
}
}
답변
뷰 컨트롤러에 상수를 설정하는 데 동일한 문제가 발생했습니다.
인터페이스 빌더를 사용하여 뷰를 관리하기 init()
때문에를 사용할 수 없으므로 해결 방법은 기본 및 상속 된 클래스 모두에서 읽기 전용 계산 변수를 사용한 것을 제외하고는 다른 답변과 유사했습니다.
class Jedi {
var type: String {
get { return "Blue" }
}
}
class Sith: Jedi {
override var type: String {
get { return "Red" }
}
}