swift3学习笔记:访问控制(private,fileprivate,internal,public,open)

访问控制
(private,fileprivate,internal,public,open)

访问权限从高到低:open > public > interal > fileprivate > private

访问级别知道原则:
Access levels in Swift follow an overall guiding principle: No entity can be defined in terms of another entity that has a lower (more restrictive) access level.

For example:

A public variable cannot be defined as having an internal, file-private, or private type, because the type might not be available everywhere that the public variable is used.

A function cannot have a higher access level than its parameter types and return type, because the function could be used in situations where its constituent types are not available to the surrounding code.

The specific implications of this guiding principle for different aspects of the language are covered in detail below.

1. private

  • private修饰类,表示该类只能在当前Swift源文件中访问,且该类不能被继承。


    private修饰类,该类不能被继承
  • private修饰的属性或者方法,表示该属性或方法只能在当前类里访问,且不能override。


    swift3学习笔记:访问控制(private,fileprivate,internal,public,open)_第1张图片
    private修饰的方法不能override

    swift3学习笔记:访问控制(private,fileprivate,internal,public,open)_第2张图片
    private修饰的方法不能在其他类中访问

    swift3学习笔记:访问控制(private,fileprivate,internal,public,open)_第3张图片
    private修饰的属性不能在其他类中访问

2. fileprivate

  • fileprivate修饰类,表示该类只能在当前Swift源文件中访问,且该类不能被继承。


    fileprivate修饰类,该类不能被继承
  • fileprivate修饰的属性或方法,被修饰的属性或方法可以在当前的Swift源文件里访问,但不能在其他源文件中访问。


    swift3学习笔记:访问控制(private,fileprivate,internal,public,open)_第4张图片
    fileprivate修饰的属性或方法可以在当前的Swift源文件里访问

    fileprivate修饰的属性或方法不能在其他源文件中访问

3. internal(默认访问级别,internal修饰符可写可不写)

  • internal修饰的属性或方法在源代码所在的整个模块都可以访问。
  • 如果是框架或者库代码,则在整个框架内部都可以访问,框架由外部代码所引用时,则不可以访问。
  • 如果是App代码,也是在整个App代码,也是在整个App内部可以访问。


    internal修饰的属性或方法在源代码所在的整个模块都可以访问

    internal修饰的属性或方法在其他Swift源代码可以访问

4. public

  • piblic修饰类,可以被任何人访问,但只能在本模块(sdk)中被继承。
  • public修饰属性和方法,可以被任何人访问,在module内可以被override和继承,但其他module中不可以被override和继承。

5. open

可以被任何人使用,不限制module,包括override和继承。

6. 部分说明

6-1 访问控制语法(Access Control Syntax)
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() {}

//默认为internal
class SomeInternalClass {}              // implicitly internal
let someInternalConstant = 0            // implicitly internal
6-2 自定义类型(Custom Types)

类的访问控制级别会影响该类成员的默认访问级别。

  • 如果将类的访问级别定义为private(私有)或fileprivate(文件私有),其成员的默认访问级别也将为private(私有)或fileprivate(文件私有)。
  • 如果将类的访问级别定义为internal或public(或者使用内部的默认访问级别,但未明确指定访问级别),那么类型成员的默认访问级别将是internal。
  • 一个访问控制级别是public的类,它的成员默认的访问控制级别是internal。如果你想要一个类型成员是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
}
6-3 元组类型(Tuple Types)
  • 元组类型的访问级别是该元组中使用的所有类型的最严格的访问级别。例如,如果一个元祖中有两种不同类型,一个具有internal(内部访问)权限,另一个具有private(私有访问)权限,则该复合元组类型的访问级别将是private(私有的)。

元组类型没有类,结构,枚举和函数所做的独立定义。当使用元组类型时,元组类型的访问级别会自动推断,并且不能明确指定。

6-4 函数类型(Function Types)
  • 函数类型的访问级别为函数的参数类型和返回类型的最严格的访问级别。如果函数的计算访问级别与指定的访问级别不一致,必须修改指定的访问级别相一致。
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // function implementation goes here
}
//函数的返回类型是一个元组类型,由被定义为internal的类和被定义为private的类组成。因此,复合元组类型的总体访问级别是`private`(元组的组成类型的最小访问级别)。
//因为函数的返回类型是private(私有的),所以必须private使用函数声明的修饰符将函数的总体访问级别标记为private。
//someFunction()使用public或internal修饰符 ,或者使用内部的默认设置,定义的都是无效的,因为函数的公共或内部用户可能没有对函数返回类型中使用的私有类的适当访问。
6-5 子类
  • 子类的访问级别不能高于父类访问级别。例如:父类的访问级别是interal,子类的访问级别不能是public/open。
  • 可以覆盖 (override)任何类成员(方法、属性、初始化或下标)。
public class A {
    fileprivate func someMethod() {}
}
internal class B: A {
    override internal func someMethod() {}
}  
//使用internal修饰的class B继承自使用public修饰的class A,class B中可以修改class A中使用fileprivate修饰的someMethod()访问权限为internal。
//----------------------------------------
public class A {
    fileprivate func someMethod() {}
}
internal class B: A {
    override internal func someMethod() {
        super.someMethod()
    }
}
//由于父类A和子类B在同一个源文件中,子类B在重写someMethod()时可以调用super.someMethod()。
6-6 常量,变量,属性和下标
  • 常量,变量,属性和下标的访问权限不能高于定义该变量所引用的类型或者返回类型。
//privateInstance的返回值访问权限类型是private,所以定义privateInstance的访问权限类型不能高于private。
private var privateInstance = SomePrivateClass()

7. final

链接
Swift中,final关键字可以在class、func和var前修饰。
类或者方法的功能确实已经完备了,或避免子类继承和修改造成危险,或为了让父类中某些代码一定会执行。
也就是说这个类或方法不希望被继承和重写。

  • 用final关键字来防止重写
  • final,最后的,最终的;决定性的;不可更改的
  • final 修饰类的话,表示这个类不可以被继承。
  • 如果修饰属性或者方法,表示相应的属性或者方法不能被重写。

使用final修饰的类或属性或方法无论是在同一个module中还是在其他module中都不能被继承或者修改(override)。

//MARK: - ViewController:
//这个类在ViewController:的范围内不能被继承,只能能被访问;
//在ViewController:的范围外不能被继承,只能能被访问
final class NonSubclassAnyParentClass{}

//出错,在ViewController:范围不能被继承
class NonSubclassAny: NonSubclassAnyParentClass {}

//MARK: - LoginViewController
//出错,在ViewController:范围外不能被继承
class NonSubclassAny: NonSubclassAnyParentClass {}

参考链接1
参考链接2
参考链接3

用来记录平时遇到的问题,不对之处还望指教。

你可能感兴趣的:(swift3学习笔记:访问控制(private,fileprivate,internal,public,open))