簡體   English   中英

為什么傳遞給 function 的協議默認值不會改變,即使子類化時 function 會改變?

[英]Why does the protocol default value passed to the function not change, even though the function does when subclassing?

我有一個協議,我為其分配了一些默認值:

protocol HigherProtocol {
    var level: Int { get }
    
    func doSomething()
}

extension HigherProtocol {
    var level: Int { 10 }
    
    func doSomething() {
        print("Higher level is \(level)")
    }
}

然后我有另一個符合更高級別協議的協議,但具有不同的默認值和功能實現:

protocol LowerProtocol: HigherProtocol {}

extension LowerProtocol {
    var level: Int { 1 }
    
    func doSomething() {
        print("Lower level is \(level)")
    }
}

然后我創建一個符合上層協議的 class,然后創建一個符合下層協議的子類:

class HigherClass: HigherProtocol {}

class LowerClass: HigherClass, LowerProtocol {}

但是,當我實例化這個較低的 class 時,它會顯示一些奇怪的行為:

let lowerClass = LowerClass()

lowerClass.level // is 1

lowerClass.doSomething() // Prints "Lower level is 10" to the console.

默認屬性是正確的,但是 function 的默認實現似乎是兩者的混合。

我想知道這里發生了什么?

您似乎正在嘗試使用協議來創建多重繼承。 它們不是為此而設計的,即使你得到這個工作,你也會被咬幾次。 協議不能替代 inheritance,多個或其他。 (作為一項規則,Swift 傾向於組合而不是任何形式的 inheritance。)

這里的問題是 HigherClass 符合 HigherProtocol ,因此現在有leveldoSomething的實現。 LowerClass 繼承自它,並希望覆蓋這些實現。 但是覆蓋在協議擴展中,這是未定義的行為。 請參閱 Swift 編程語言的擴展

擴展可以為類型添加新功能,但不能覆蓋現有功能。

未定義的行為並不意味着“它不會覆蓋”。 這意味着“任何事情都可能發生”,包括這種奇怪的情況,有時會被覆蓋,有時不會。

(作為旁注,Objective-C 中的情況類似。在兩個不同類別中實現一個方法會導致不確定調用哪個類別,並且在發生這種情況時沒有警告或錯誤讓您。Swift 的優化可以使行為更加令人驚訝.)

我希望編譯器能夠檢測到這些類型的錯誤並引發錯誤,但事實並非如此。 你需要重新設計你的系統來避免這樣做。

協議是存在類型,這就是您感到困惑的原因。 您需要公開 class 類型的協議類型。 在您的情況下,您可以執行LowerProtocolHigherProtocol ,以便現在打印 10。 讓我們像這樣

let lowerClass: LowerProtocol = LowerClass()

或者

let lowerClass: HigherProtocol = LowerClass()

lowerClass.level // now prints 10

lowerClass.doSomething() // Prints "Lower level is 10" to the console.

暫無
暫無

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

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