簡體   English   中英

Swift 屬性封裝

[英]Swift Property Encapsulation

我只是想知道在 Swift 中聲明屬性的“標准”方式是什么。 特別是,Apple 的所有 Swift 示例代碼似乎都沒有封裝屬性(您可以自由獲取和設置屬性,而無需通過 getter 和 setter 方法)。 (我習慣了 Java,所以我很難相信這就是 Apple 希望開發人員編寫代碼的方式。)

現在,我有:

private var x: Int
private var xListener: XListener?
public func getX() -> Int {
    return x
}
public func setX(newValue: Int) {
    x = newValue
    if (let listener = xListener) {
        listener.onXSet(x)
    }
}

但我覺得必須有一種更簡單的方法來做到這一點。 我看到一些關於計算屬性的提及,但似乎那些不存儲值,所以要使用它們你必須這樣做:

private storedX: Int
public var x: Int {
    get {
        return storedX
    }
    set {
        storedX = newValue
    }
    didSet {
        if (let listener = xListener) {
            listener.onXSet(storedX)
        }
    }
}

我只是很難相信這兩種方法中的任何一種都是執行此操作的“正確”方法,因為它們非常復雜。 Swift 通常不封裝屬性,還是我只是遺漏了什么?

與僅使用屬性相比,什么都不做的 setter 和 getter 根本不提供任何封裝。 從字面上看,這之間沒有語義上的區別:

private storedX: Int
public var x: Int {
    get {
        return storedX
    }
    set {
        storedX = newValue
    }
}

還有這個

public var x: Int

你可以隨時返回並更改(盡管有一個限制,你必須重新編譯所有鏈接的代碼,除非你啟用了庫進化)x 稍后成為計算屬性,或添加 didSet/willSet 等......

你能更詳細地解釋一下你想通過封裝 x 來獲得什么嗎?

(編輯:不過要直接回答問題,我會這樣做:

public var x : Int {
    didSet {
        xListener?.onXSet(storedX)
    }
}

)

仔細查看后,我找到了一個稍微優雅一些的解決方案。 看起來有一個 private(set) 修飾符可以訪問一個變量 public 但阻止寫入它。 所以仍然沒有完全封裝,但絕對比允許完全訪問該字段要好。 因此,除非有人有更好的建議,否則我的代碼最終將如下所示:

private(set) var x: Int
public func incrementX() {
    x++
    xListener?.onXIncremented()
}

只是為了完善鯰魚的答案(應該標記為您已回答):

在 Java(和 C++)中,您沒有屬性,因此“約定規則”是始終使用 getter 和 setter 方法。 在 Swift 中,如果您不想更改代碼的使用方式,您可以稍后將 myClass.x 設置為計算屬性(這基本上是一個 get set 方法)。

在您自己的應用程序中,即使在 Java 中,這也並不重要,因為大多數 IDE 具有非常好的重構工具,但是如果您創建一個庫供其他人使用,它不會破壞接口。 (至少在源代碼級別)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM