swift之訪問控制

官網地址:https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html#//apple_ref/doc/uid/TP40014097-CH41-ID3html

一、訪問控制種類swift

    swift3.0之後,訪問控制主要分爲五類:open、public、internal、fileprivate、private,其中open級別最高,private最低。app

訪問控制 定義
open 能夠訪問本身模塊中源文件裏面的任何實體,其餘模塊也能夠經過引入該模塊中源文件訪問全部的實體,而且其餘模塊能夠繼承本模塊的實體和從新本模塊中實體的方法
public 能夠訪問本身模塊中源文件裏面的任何實體,其餘模塊也能夠經過引入該模塊中源文件訪問全部的實體,但其餘模塊不能夠繼承本模塊的實體和從新本模塊中實體的方法
internal 能夠被本身模塊中代碼訪問其餘源文件裏的任何實體,可是其餘模塊不能訪問該模塊中源文件裏面的實體
fileprivate 文件內私有,只能在當前源文件使用
private 只能在類中訪問,離開了這個類或者結構體的做用域之後就沒法訪問

 

 

 

 

 

 

注:函數

模塊:以獨立單元構建和發佈的framework或app。經過XCODE bulid出來的target就能夠看作是一個獨立模塊。ui

源文件:一個模塊裏面的一個swift代碼文件,一個源文件裏面能夠包含多個類、結構等。spa

二、語法code

總法則有兩條:htm

1)不能給一個變量設置高於其類型訪問權限的訪問權限,好比blog

2)函數的訪問權限由函數參數和返回值的權限決定,取二者權限的最小值。繼承

默認權限

若是沒有給一個實體指定訪問權限,其默認權限爲internal

權限控制的語法

public class SomePublicClass {}
internal class SomeInternalClass {}
fileprivate class SomeFilePrivateClass {}
private class SomePrivateClass {}
 
public var somePublicVariable = 0
internal let someInternalConstant = 0
fileprivate func someFilePrivateFunction() {}
private func somePrivateFunction() {}

一個實體的權限控制也影響着該實體成員的權限:若是一個實體權限控制爲private或fileprivate,那麼他的成員默認訪問權限爲private或fileprivate;若是一個實體權限控制爲internal或public,那麼他的成員默認訪問權限爲internal。若是想讓一個訪問權限爲public的實體的成員權限也爲public,必須本身指定該成員的權限爲public。

public class SomePublicClass {                  // explicitly public class
    public var somePublicProperty = 0            // explicitly public class member
    var someInternalProperty = 0                 // implicitly internal class member
    fileprivate func someFilePrivateMethod() {}  // explicitly file-private class member
    private func somePrivateMethod() {}          // explicitly private class member
}
 
class SomeInternalClass {                       // implicitly internal class
    var someInternalProperty = 0                 // implicitly internal class member
    fileprivate func someFilePrivateMethod() {}  // explicitly file-private class member
    private func somePrivateMethod() {}          // explicitly private class member
}
 
fileprivate class SomeFilePrivateClass {        // explicitly file-private class
    func someFilePrivateMethod() {}              // implicitly file-private class member
    private func somePrivateMethod() {}          // explicitly private class member
}
 
private class SomePrivateClass {                // explicitly private class
    func somePrivateMethod() {}                  // implicitly private class member
}

元組的訪問權限

元組的訪問權限取決於他包含全部類型的權限最小值。好比一個元組包含兩個類型,一個類型的權限爲internal,一個類型的權限爲private,那麼該元組的訪問權限爲private。

函數的訪問權限

函數的訪問權限規則已經在上面說了,這裏再也不贅述。直接上例子:

枚舉類型的訪問權限

枚舉成員的訪問級別繼承自該枚舉,不能單獨爲枚舉中的成員單獨聲明不一樣的訪問權限

子類的訪問權限

子類的訪問權限不能高於父類的訪問權限。好比,父類的訪問權限爲internal,子類的訪問權限就不能爲public。另外,你能夠在子類裏面重寫父類裏面的(方法,屬性,構造函數,下表訪問器),可是要遵照三個原則(以方法爲例說明):一、能在子類中訪問到父類裏面的方法;二、能夠給重寫方法設置新的訪問權限;三、新賦予的權限須要大於等於父類該方法的訪問權限級別。例子以下:

常量、變量、屬性、下標的訪問權限

他們的訪問權限不能高於對應類型的訪問權限。

Getter和Setter訪問權限

常量、變量、屬性、下標索引的Getter和Setter的訪問權限繼承自他們所屬成員的訪問級別。你能夠把Setter的訪問權限設置地低於對應的Getter的權限,這樣就可以控制變量、屬性、下標索引的讀寫權限。設置Setter訪問權限的方法爲把fileprivate(set),private(set),internal(set)放在變量、屬性、下標索引的前面

struct TrackedString {
    //numberOfEdits的get權限爲internal,set權限爲private。因此numberOfEdits只能在TrackedString裏面修改
    private(set) var numberOfEdits = 0
    var value: String = "" {
        didSet {
            numberOfEdits += 1
        }
    }
}

若是既想對Getter進行修改,也想對Setter進行修改,能夠以下設置:

public struct TrackedString {
    //numberOfEdits的get權限爲public、set權限爲private
    public private(set) var numberOfEdits = 0
    public var value: String = "" {
        didSet {
            numberOfEdits += 1
        }
    }
    public init() {}
}

構造器和默認構造器的訪問權限

對自定義的構造器設置訪問權限的時候,不能高於他所屬類的訪問權限。可是對於必要構造器,他的訪問權限必須跟所屬類的訪問權限相同。

swift爲結構體、類提供了一個默認的無參初始化方法,用於給他們的全部屬性賦值,但不會給出具體指。默認初始化方法的訪問權限與所屬類型的訪問權限相同,注意當類、結構體的權限爲public時,默認構造器的訪問權限爲internal

協議的訪問權限

若是要爲一個協議設置訪問權限,那麼要確保該協議只在設置的訪問權限做用域中使用。一個類能夠實現一個比本身訪問權限低的協議,好比定義一個Public的類,他又實現了一個internal的協議,那麼這個類的訪問權限爲internal(取二者的最小值)。

擴展的訪問權限

擴展成員和原始類成員有一致的訪問權限,好比你擴展了一個帶有public權限的類,那麼新加的成員應該有和原始成員同樣的默認爲internal的訪問權限。另外,能夠給擴展設置明確的訪問權限(例如:private extension),擴展中成員也能夠設置本身的訪問權限。

相關文章
相關標籤/搜索