programing

Swift에서 저장된 속성 재정의

bestprogram 2023. 5. 27. 12:03

Swift에서 저장된 속성 재정의

컴파일러가 저장된 속성을 다른 저장된 값(이상하게 보이는 값)으로 재정의하지 못하게 합니다.

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()

print(j1.lightSaberColor)
print(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'의 게터로 재정의할 수 없습니다.

아니요, 저장된 속성의 유형을 변경할 수 없습니다.리스코프 대체 원칙은 슈퍼 클래스가 필요한 장소에서 하위 클래스를 사용하도록 강제합니다.

하지만 만약 당신이 그것을 바꾼다면.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속성 값만 변경할 수 있으므로 속성이 의미가 없습니다.

그러나 저장된 속성을 저장된 속성으로 재정의할 수는 없습니다.


나는 시타레 제다이라고 말하지 않을 것입니다 :-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"
    }
}

Apple 문서에서 Swift 4의 경우:

상속된 인스턴스 또는 유형 속성을 재정의하여 해당 속성에 대한 고유한 사용자 지정 게터 및 세터를 제공하거나 기본 속성 값이 변경될 때 재정의하는 속성을 관찰할 수 있도록 속성 관찰자를 추가할 수 있습니다.

만약 당신이 스위프트 5에서 그것을 시도한다면 당신은 당신을 맞이할 것입니다.

불변 'let' 속성 'lightSaberColor'를 'var'의 게터로 재정의할 수 없습니다.

계산된 속성으로 선언하는 것이 가장 좋습니다.

이것은 우리가 단지 위에 있을 때 작동합니다.get {}기능.

class Base {
   var lightSaberColor: String { "base" }
}

class Red: Base {
   override var lightSaberColor: String { "red" }
}

Swift에서는 안타깝게도 이 작업을 수행할 수 없습니다.최상의 대안은 다음과 같습니다.

class Jedi {
    private(set) var lightsaberColor = "Blue"
}


class Sith: Jedi {
    override var lightsaberColor : String {
        get {
            return "Red"
        }
    }
}

저장된 속성을 신속하게 재정의합니다.

Swift는 사용자가 오버라이드하는 것을 허용하지 않습니다.stored property이것 대신에 당신은 사용할 수 있습니다.computed property

class A {
    //var
    var property1 = "A: Stored Property 1"
    var property2: String {
        get {
            return "A: Computed Property 2"
        }
    }

    //let
    let property3 = "A: Constant Stored Property 3"
    //let can not be a computed property
    
    func foo() -> String {
        return "A: foo()"
    }
}

class B: A {
    //now it is a computed property
    override var property1: String {
        set { }
        get {
            return "B: overrode Stored Property 1"
        }
    }

    override var property2: String {
        get {
            return "B: overrode Computed Property 2"
        }
    }
    
    override func foo() -> String {
        return "B: foo()"
    }

    //let can not be overrode
}
func testPoly() {
    let a = A()
    
    XCTAssertEqual("A: Stored Property 1", a.property1)
    XCTAssertEqual("A: Computed Property 2", a.property2)
    
    XCTAssertEqual("A: foo()", a.foo())
    
    let b = B()
    XCTAssertEqual("B: overrode Stored Property 1", b.property1)
    XCTAssertEqual("B: overrode Computed Property 2", b.property2)
    
    XCTAssertEqual("B: foo()", b.foo())
    
    //B cast to A
    XCTAssertEqual("B: overrode Stored Property 1", (b as! A).property1)
    XCTAssertEqual("B: overrode Computed Property 2", (b as! A).property2)
    
    XCTAssertEqual("B: foo()", (b as! A).foo())
}

컴파일 시간에 정의되어 있기 때문에 클래스 필드를 오버로드할 수 없고 다형성을 지원하지 않는 Java와 비교하면 더 명확합니다(효율적으로 실행).숨김 변수라고[About] 합니다. 읽기/지원하기 어렵기 때문에 이 기술을 사용하지 않는 것이 좋습니다.

[빠른 속성]

뷰 컨트롤러에 상수를 설정하는 것과 같은 문제가 있었습니다.

인터페이스 작성기를 사용하여 보기를 관리하고 있으므로 사용할 수 없습니다.init()기본 클래스와 상속된 클래스 모두에서 읽기 전용 계산 변수를 사용했다는 점을 제외하고는 해결 방법이 다른 답변과 유사했습니다.

class Jedi {
    var type: String {
        get { return "Blue" }
    }
}

class Sith: Jedi {
    override var type: String {
        get { return "Red" }
    }
}

기능을 사용하여 재정의할 수도 있습니다.직접적인 대답은 아니지만 이 주제를 풍부하게 할 수 있습니다.)

클래스 A

override func viewDidLoad() {
    super.viewDidLoad()

    if shouldDoSmth() {
       // do
    }
}

public func shouldDoSmth() -> Bool {
    return true
}

클래스 B: A

public func shouldDoSmth() -> Bool {
    return false
}

위의 예에 추가로,

class SomeClass {
    var hello = "hello"
}
class ChildClass: SomeClass {
    override var hello: String {
        set {
            _hello = newValue
        }
        get {
            _hello
        }   
    }
    private var _hello: String = ""
}


// Testing...
let c = ChildClass()
c.hello = "test"
print(c.hello) // test
    //declaring class
class Games {
       var  no_player:Int = 0
        var name_game :String = ""
        var player_value:String {
            return "low"
        }
        func playing(){
            print( "the \(name_game) is played by \(no_player) players and the player value is \(player_value)")
        }
    }
//chess class inherits Games
    class Chess : Games {
        var location:String = ""
    }
//cricket class inherits Games
    class cricket : Games{
        var ball_brand = "sg"
    }
    //making object of Chess()
     let Chess1 = Chess()
    Chess1.name_game = "Chess "
    Chess1.no_player = 2
    Chess1.palying()
//polo inherits Games

    class polo:Games {
        override var player_value: String{
            return "high"
        }
        
        override func playing() {
            print("holla we are playing cricket with 10 members and the palyer value is  \(player_value) ")
        }
    }
    var polo1 = polo()
    polo1.playing()

저는 다음과 같은 접근 방식을 사용합니다.

class Class {
    
    private lazy var _instance: AType = {
        return AType()
    } ()
    
    var instance: AType {
        return _instance
    }
    
}

class Subclass: Class {
    
    private lazy var _instance: AType = {
        return ASubType()
    } ()
    
    override var instance: AType {
        return _instance
    }
    
}

이 방법을 사용하여 값을 업데이트할 수 있습니다.

class A {

    var lightSaberColor : String = "Red"
}

변수를 재정의할 필요는 없습니다.변수의 값을 변경할 수 있습니다.

class B: A {
     * **Change Value when the class will initialize.**

     override init() {
        super.init()
          self.lightSaberColor = "Orange"
     }

    /*
     * **Change Value when you will use this function.**
     */
    func test() {
       lightSaberColor = "Green"
    }
}

let b = B()

b.test()

언급URL : https://stackoverflow.com/questions/26691935/overriding-a-stored-property-in-swift