簡體   English   中英

所需初始化的訪問控制

[英]Access control for required init

必需的初始值設定項的訪問控制規則似乎與未指定要求的規則不同。 為什么?

public class A {
  // required init() must be public, why?
  public required init() { }
}

public class B {
  // init() does not need to be public, why?
  init() { }
}

首先,讓我們闡明規則。 不需要將required初始化程序標記為public 僅要求required初始化程序與類一樣易於訪問。 如果您的課程是public ,則必需的初始化程序也必須是public 如果您的類是internal類,則其必需的初始化器也必須是internal (從技術上講,您可以將其設置為public ,但這沒有任何意義,並且會生成警告 )。 當然,如果您的類是private ,則所需的初始化器也應該是private


所以為什么?

這里有兩個原因,但是它們需要了解required關鍵字實際上在做什么。


首先, required關鍵字保證了此類,並且其所有子類都實現了此特定的初始化程序。 要求使用初始化程序的主要原因之一是為了實現協議一致性,其中最流行的示例是NSCoding ,它需要使用init(coder:)初始化程序。 因此,考慮到這一點,讓我們考慮一個試圖實現此協議的類:

public class MySwiftClass: NSObject, NSCoding {
    // some implementations
    // including the two requirements of the NSCoding protocol
}

現在,考慮嘗試使用此方法:

let mySwiftObject = MySwiftClass(coder: aCoder)

我們應該能夠毫無問題地做到這一點,對嗎? 我的意思是,畢竟MySwiftClass符合NSCoding協議,並且NSCoding協議保證會有一個init(coder:)初始化程序。

但是,如果允許您將init(coder:)標記為比類更低的訪問級別,則可以在某個范圍內看到該類,但無法訪問其所需的初始化程序...因此盡管知道此類符合帶有必需的初始化程序的協議,或者是從帶有必需的初始化程序的父類繼承的,我們將無法以某種方式調用該必需的初始化程序,因為對於我們所在的范圍,它似乎不存在。


第二個原因是對自身進行子類化。

讓我們以該示例父類為例:

public class ParentClass {
    required init() {}
}

我們希望零參數初始化程序是必需的。 這意味着,如果任何東西都繼承自ParentClass ,則還必須確保實現了零參數初始化程序。 但是,如果允許我們允許所需的初始化程序具有比類本身小的范圍,則可以在其中看到一個類,但看不到所需的初始化程序,因此在該范圍內創建的子類如何管理甚至知道他們必須實現一個必需的初始化程序?

暫無
暫無

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

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