iOS學習筆記49-Swift(九)訪問控制

1、Swift的訪問控制

Swift中的訪問控制模型基於模塊源文件這兩個概念swift

  1. 模塊
    指的是FrameworkApp bundle。在Swift中,能夠用import關鍵字引入本身的工程。
  2. 源文件
    指的是Swift中的Swift File,就是編寫Swift代碼的文件,它一般是屬於某一個模塊。
Swift提供了三種不一樣的訪問級別:
  • Public:【使用public修飾】【範圍大】
    能夠訪問當前模塊及其餘模塊中的任何實體(一般用於Framework
  • Internal:【使用internal修飾】【範圍中】
    能夠訪問當前模塊中的任何實體,可是在模塊外沒法訪問,這是全部實體的默認訪問級別(一般在一個單目標Application中不須要自行設置訪問級別)
  • Private:【使用private修飾】【範圍小】
    只能訪問當前源文件中的實體,用做隱藏某些功能的實現細節

訪問級別從低到高:Private < Internal < Publicide

訪問控制的使用規則挺多的,我這裏進行了歸納:
  1. 【成員(屬性和方法) <= 類】
  2. 【(常量、變量、屬性、下標腳本) <= 類型】
  3. 【Setter <= Getter】
  4. 【required方法 == 類】【默認逐一構造函數 <= 全部成員】
  5. 【子類 <= 父類】【子協議 <= 父協議】
  6. 子類重寫父類成員修改訪問範圍
  7. 【協議成員 == 協議】【類 >= 協議】【協議實現 >= 協議要求】
  8. 【元組 = Min(全部元素類型)】
  9. 【函數 = Min(參數類型,返回值類型)】
  10. 【枚舉成員 == 枚舉】【(原始值,關聯值) >= 枚舉】
  11. 【泛型類型 = Min(類類型,泛型參數)】
  12. 【類型別名 <= 原類型】

2、訪問控制使用規則詳解

1.【成員(屬性和方法) <= 類】
/* 
    1.【成員(屬性和方法) <= 類】
    若是你將類申明爲private類,那麼該類的全部成員的默認訪問級別也會成爲private
    若是你將類申明爲public或者internal類,那麼該類的全部成員默認訪問級別是internal。
*/
public class SomePublicClass {          // 顯示的public類
    public var somePublicProperty = 0    // 顯示的public類成員
    var someInternalProperty = 0         // 隱式的internal類成員
    internal var someInternalProperty2 = 0 //顯示的internal類成員
    private func somePrivateMethod() {}  // 顯示的private類成員
}
internal class SomeInternalClass {        // 顯示的internal類
    var someInternalProperty = 0         // 隱式的internal類成員
    private func somePrivateMethod() {}  // 顯示的private類成員
    //Error:-> public var somePublicProperty = 0 
    
}
private class SomePrivateClass {        // 顯示的private類
    var somePrivateProperty = 0          // 隱式的private類成員
    func somePrivateMethod() {}          // 隱式的private類成員
    //Error:-> public var somePublicProperty = 0 
    //Error:-> internal var someInternalProperty = 0
}
2.【(常量、變量、屬性、下標腳本) <= 類型】
/* 2.【(常量、變量、屬性、下標腳本) <= 本身類型】 */
private let somePrivate1 = SomePrivateClass() //變量爲private <= 類型爲private
private let somePrivate2 = SomeInternalClass()//變量爲private <= 類型爲internal
private let somePrivate3 = SomePublicClass()//變量爲private <= 類型爲public
//Error:internal let someInternal1 = SomePrivateClass() //變量internal大於類型private,錯誤
internal let someInternal2 = SomeInternalClass()//變量爲internal <= 類型爲internal
internal let someInternal3 = SomePublicClass()//變量爲internal <= 類型爲public
//Error:public let somePublic1 = SomePrivateClass() //變量public大於類型private,錯誤
//Error:public let somePublic2 = SomeInternalClass() //變量public大於類型internal,錯誤
public let somePublic3 = SomePublicClass()//變量爲public <= 類型爲public
3.【Setter <= Getter】
/* 3.【setter <= getter】,private(set)修飾將setter權限設置爲private */
/* 
    這個規定適用於用做存儲的屬性或用做計算的屬性。
    即便你不明確的申明存儲屬性的Getter、Setter,
    Swift也會隱式的爲其建立Getter和Setter,用於對該屬性進行讀取操做。
*/
public class SetterPrivateClass {//該類能夠在任何模塊中使用
    private(set) var value = 0 //設置存儲屬性的setter爲private
    //設置計算屬性的setter屬性爲private
    private(set) var setPrivateProperty:Int {
        set{//此時setter爲private,也就是隻能在本文件中使用,其餘文件沒法使用
            value = newValue + 1
        }
        get{//getter默認爲internal
            return value + 1
        }
    }
}
4.【required方法 == 類】【默認逐一構造函數 <= 全部成員】
/* 4.【required修飾的方法 == 類】,(結構體)【默認逐一構造函數 <= 全部成員】 */
protocol RequiredTestProtocol {
    //初始化構造器要求
    init(aprot: Int)
}
public class RequiredTestClass: RequiredTestProtocol {
    var aprot: Int //默認爲internal
    //實現協議的初始化要求時,必須使用required關鍵字確保子類必須也得實現這個構造器
    public required init(aprot: Int) {//此時必須設置爲public,由於默認是internal的
        self.aprot = aprot
    }
}
//該結構體的默認逐一構造方法爲private,但默認構造方法仍是internal
public struct StructInitTest{
    private var somePrivateProperty = 0
    internal var someInternalProperty = 0
    public var somePublicProperty = 0
}
5.【子類 <= 父類】【子協議 <= 父協議】
/* 5.【子類 <= 父類】,【子協議 <= 父協議】 */
private class PrivateSuperClass {  } //private父類
internal class InternalSuperClass {  }//internal父類
public class PublicSuperClass {  }//public父類
private class PrivateSubClass1:PrivateSuperClass {  } //子類private <= private父類
private class PrivateSubClass2:InternalSuperClass {  } //子類private <= internal父類
private class PrivateSubClass3:PublicSuperClass {  } //子類private <= public父類

//Error:internal class InternalSubClass1:PrivateSuperClass {  } //子類internal大於private父類,錯誤
internal class InternalSubClass2:InternalSuperClass {  } //子類internal <= internal父類
internal class InternalSubClass3:PublicSuperClass {  } //子類internal <= public父類

//Error:public class PublicSubClass1:PrivateSuperClass {  } //子類public大於private父類,錯誤
//Error:public class PublicSubClass2:InternalSuperClass {  } //子類public大於internal父類,錯誤
public class PublicSubClass3:PublicSuperClass {  } //子類public <= public父類
6. 子類重寫父類成員修改訪問範圍
/* 6.不違反前面規則,子類能夠經過重寫父類方法來修改訪問權限範圍 */
public class OverrideSuperClass {
    private func someMethod() {}
}
internal class OverrideSubClass: OverrideSuperClass {
    override internal func someMethod() {
        super.someMethod()//子類和父類在同一個源文件中,因此能夠訪問super的someMethod()方法
    }
}
7.【協議成員 == 協議】【類 >= 協議】【協議實現 >= 協議要求】
/* 7.【協議全部必須實現的成員 == 協議】,【類 >= 協議】,【協議實現 >= 協議要求】 */
internal protocol InternalProtocol {
    //協議成員不能夠添加訪問控制關鍵字,默認等於協議的訪問權限範圍
    var someProperty:Int { get set }
    func someMethod()
}
//類必須大於或等於要遵循的協議
public class ProtocolTestClass:InternalProtocol {
    //Error:-> private var someProperty = 0 //協議實現必須大於或等於協議要求
    public var someProperty = 0
    internal func someMethod() {
        print("ProtocolTestClass someMethod")
    }
}
8.【元組 = Min(全部元素類型)】
/* 8.【元組 = Min(全部元素類型)】,注意是類型而不是變量 */
private var privateValue =  SomePrivateClass() //注意,看類型訪問級別而不是變量訪問級別
var internalValue =  SomeInternalClass()
var publicValue = SomePublicClass() //這裏變量是internal的,但類型是public的
private let privateTupleValue = (privateValue, internalValue, publicValue)
internal let internalTupleValue = (internalValue, internalValue, publicValue)
public let publicTupleValue = (publicValue, publicValue, publicValue)
9.【函數 = Min(參數類型,返回值類型)】
/* 9.【函數 = Min(參數類型,返回值類型)】 */
private func someFunction(value:SomeInternalClass) -> SomePrivateClass {
    //函數體
    return SomePrivateClass()
}
10.【枚舉成員 == 枚舉】【(原始值,關聯值) >= 枚舉】
/* 10.【枚舉成員 == 枚舉】,枚舉成員無法單獨設置訪問級別,【(原始值,關聯值) >= 枚舉】 */
private enum PrivateEnum {
    case PrivateEnumCase( SomePrivateClass )
    case InternalEnumCase( SomeInternalClass )
    case PublicEnumCase( SomePublicClass )
}
internal enum InternalEnum {
    //Error:-> case PrivateEnumCase( SomePrivateClass ) //關聯值必須大於枚舉
    case InternalEnumCase( SomeInternalClass )
    case PublicEnumCase( SomePublicClass )
}
11.【泛型類型 = Min(類類型,泛型參數)】
/* 11.【泛型類型 = Min(類類型,泛型參數)】 */
public class GenericityClass<T> {
    var value = [T]()
    func someFunction(value:T) { }
}
private let genericityPrivate = GenericityClass<SomePrivateClass>() //泛型類型爲private
internal let genericityInternal = GenericityClass<SomeInternalClass>() //泛型類型爲internal
public let genericityPublic = GenericityClass<SomePublicClass>() //泛型類型爲public
//Error:public let genericityInternal = GenericityClass<SomeInternalClass>() //泛型類型爲internal
12.【類型別名 <= 原類型】
/* 12.【類型別名 <= 原類型】 */
//包含類型別名的類,遵循【成員<=類】
public class MyClass {
    //聲明一個類型別名,類型別名是一個爲已存在類型定義的一個可選擇的名字
    private typealias privateName1 = SomePrivateClass
    private typealias privateName2 = SomeInternalClass
    private typealias privateName3 = SomePublicClass
    //internal的類型別名能夠是internal、public的類型,不能夠是private類型
    //Error:-> internal typealias internalName1 = SomePrivateClass
    internal typealias internalName2 = SomeInternalClass
    internal typealias internalName3 = SomePublicClass
    //public的類型別名只能是public的類型
    //Error:-> public typealias publicName1 = SomePrivateClass
    //Error:-> public typealias publicName2 = SomeInternalClass
    public typealias publicName3 = SomePublicClass
    
    private var someProperty = privateName1()
}
有什麼問題能夠在下方評論區中提出!O(∩_∩)O哈!
相關文章
相關標籤/搜索