การควบคุมการเข้าถึงที่รวดเร็ว
การควบคุมการเข้าถึงสามารถกำหนดในไฟล์ที่มาหรือโมดูลรหัสอื่น ๆ เพื่อให้ระดับการเข้าถึงรหัสของคุณ
คุณสามารถอย่างชัดเจนเป็นชนิดเดียว (ชั้น struct, enum) เพื่อกำหนดระดับการเข้าถึงยังสามารถให้เหล่านี้ประเภทของคุณสมบัติฟังก์ชั่นเริ่มต้นวิธีการพิมพ์พื้นฐานดัชนีห้อยกำหนดระดับการเข้าถึง
ข้อตกลงนี้ยังอาจจะ จำกัด การใช้ในช่วงหนึ่งรวมทั้งข้อตกลงในการคงระดับโลกตัวแปรและฟังก์ชั่น
โมดูลการควบคุมการเข้าถึงตามที่มีไฟล์ที่มา
โมดูลจะถูกกำหนดโดยหน่วยที่แยกต่างหากเพื่อสร้างและเผยแพร่กรอบหรือแอพลิเคชัน โมดูลสามารถนำมาใช้ในสวิฟท์ในคำหลักที่นำเข้าแนะนำโมดูลอื่น
แฟ้มแหล่งที่มาเป็นแฟ้มแหล่งเดียวซึ่งมักจะเป็นโมดูลที่มีไฟล์ที่มาสามารถกำหนดหลายชั้นเรียนและฟังก์ชั่น
สวิฟท์มีสามระดับที่แตกต่างกันของกิจการรหัสการเข้าถึง: สาธารณะภายในส่วนตัว
ระดับการเข้าถึง | คำจำกัดความ |
---|---|
สาธารณะ | นิติบุคคลใด ๆ ที่สามารถเข้าถึงไฟล์ของคุณในโมดูลแหล่งที่มาของคนอื่น ๆ สามารถเข้าถึงไฟล์ที่มาของทุกหน่วยงานที่ผ่านการแนะนำของโมดูล |
ภายใน | : นิติบุคคลใด ๆ ที่สามารถเข้าถึงไฟล์ของคุณในโมดูลแหล่งที่มา แต่คนอื่น ๆ ไม่สามารถเข้าถึงหน่วยงานแฟ้มแหล่งที่มาโมดูล |
ส่วนตัว | ใช้นิติบุคคลเฉพาะในแฟ้มแหล่งที่ปัจจุบันรู้จักกันในนามนิติบุคคลเอกชน |
เข้าถึงประชาชนให้อยู่ในระดับที่ทันสมัยที่สุดส่วนตัวเป็นระดับต่ำสุดของการเข้าถึง
ไวยากรณ์
ด้วยการประกาศปรับเปลี่ยนสาธารณะภายในการเข้าถึงหน่วยงานภาคเอกชนระดับ:
public class SomePublicClass {} internal class SomeInternalClass {} private class SomePrivateClass {} public var somePublicVariable = 0 internal let someInternalConstant = 0 private func somePrivateFunction() {}
เว้นแต่มีคำแนะนำพิเศษสำหรับหน่วยงานอย่างอื่นใช้ระดับการเข้าถึงเริ่มต้นภายใน
ประเภทการเข้าถึงฟังก์ชั่น
ระดับการเข้าถึงตามพารามิเตอร์ที่ฟังก์ชั่นที่ได้มาต้องใช้ชนิดของประเภทกลับของฟังก์ชันและระดับของการเข้าถึง
ตัวอย่างต่อไปนี้กำหนดชื่อ someFunction ฟังก์ชั่นทั่วโลกและไม่แน่ชัดยืนยันระดับการเข้าถึงของพวกเขา
func someFunction() -> (SomeInternalClass, SomePrivateClass) { // 函数实现 }
ฟังก์ชั่นในหนึ่งในชั้นเรียน SomeInternalClass ระดับการเข้าถึงภายในระดับการเข้าถึงข้อมูลอื่น ๆ SomePrivateClass ความเป็นส่วนตัว ดังนั้นตามหลักการของ tuple ระดับการเข้าถึง, ระดับการเข้าถึง tuple มีความเป็นส่วนตัว
เพราะฟังก์ชั่นส่งกลับชนิดของระดับการเข้าถึงที่มีความเป็นส่วนตัวดังนั้นคุณจะต้องใช้เครื่องปรับส่วนตัวประกาศแน่ชัดว่าฟังก์ชั่น:private func someFunction() -> (SomeInternalClass, SomePrivateClass) { // 函数实现 }
ฟังก์ชั่นนี้ถูกประกาศเป็นที่สาธารณะหรือภายในหรือใช้ค่าเริ่มต้นระดับการเข้าถึงภายในเป็นสิ่งที่ผิด
การเข้าถึงประเภทแจกแจง
สมาชิกระดับการเข้าถึงการแจงนับสืบทอดมาจากการแจงนับที่คุณไม่สามารถระบุสมาชิกของการประกาศแยกระดับที่แตกต่างกันในการเข้าถึง
ตัวอย่าง
ยกตัวอย่างเช่นตัวอย่างต่อไปนี้การแจงนับนักศึกษามีการประกาศอย่างชัดเจนว่าระดับประชาชนแล้วชื่อสมาชิกระดับมาร์คของการเข้าถึงยังเป็นส่วนกลาง:
public enum Student { case Name(String) case Mark(Int,Int,Int) } var studDetails = Student.Name("Swift") var studMarks = Student.Mark(98,97,95) switch studMarks { case .Name(let studName): print("学生名: \(studName).") case .Mark(let Mark1, let Mark2, let Mark3): print("学生成绩: \(Mark1),\(Mark2),\(Mark3)") }
เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:
学生成绩: 98,97,95
เข้าถึง subclasses
ระดับการเข้าถึง subclass ต้องไม่เกินกว่าระดับการเข้าถึงของชนชั้นปกครอง ยกตัวอย่างเช่นระดับการเข้าถึงของผู้ปกครองชั้นเรียนคือภายในระดับการเข้าถึงของ subclass ไม่สามารถได้รับการประกาศให้เป็นสาธารณะ
public class SuperClass { private func show() { print("超类") } } // 访问级别不能低于超类 internal > public internal class SubClass: SuperClass { override internal func show() { print("子类") } } let sup = SuperClass() sup.show() let sub = SubClass() sub.show()
เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:
超类 子类
ค่าคงที่ตัวแปรคุณสมบัติการเข้าถึงดัชนี
ค่าคงที่ตัวแปรคุณลักษณะที่ไม่สามารถมีมากกว่าชนิดของพวกเขาในระดับการเข้าถึง
ตัวอย่างเช่นคุณสามารถกำหนดระดับของทรัพย์สินของประชาชน แต่มันเป็นชนิดของระดับส่วนตัวซึ่งไม่ได้รับอนุญาตโดยรวบรวม
ในทำนองเดียวกันดัชนีไม่สามารถมีผลตอบแทนที่สูงกว่าชนิดดัชนีหรือชนิดของระดับการเข้าถึง
หากค่าคงที่ตัวแปรคุณสมบัติประเภทดัชนีห้อยกำหนดระดับส่วนตัวพวกเขาจะต้องระบุไว้อย่างชัดเจนในระดับของการเข้าถึงส่วนตัว:
private var privateInstance = SomePrivateClass()
มุ่งมั่นและการเข้าถึง Setter
getters และการเข้าถึง Setters คงระดับตัวแปรคุณสมบัติดัชนีห้อยสืบทอดมาจากระดับการเข้าถึงที่พวกเขาอยู่กับสมาชิก
ระดับการเข้าถึง Setter อาจต่ำกว่าระดับการเข้าถึงทะเยอทะยานที่สอดคล้องกันเพื่อให้คุณสามารถควบคุมตัวแปรคุณสมบัติหรือดัชนีห้อยอ่านและเขียนสิทธิ์
class Samplepgm { private var counter: Int = 0{ willSet(newTotal){ print("计数器: \(newTotal)") } didSet{ if counter > oldValue { print("新增加数量 \(counter - oldValue)") } } } } let NewCounter = Samplepgm() NewCounter.counter = 100 NewCounter.counter = 800
เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:
计数器: 100 新增加数量 100 计数器: 800 新增加数量 700
คอนสตรัคและสร้างการเริ่มต้นการเข้าถึง
การเขียนอักษรย่อ
เราสามารถปรับแต่งวิธีการเริ่มต้นที่จะประกาศระดับการเข้าถึง แต่มันอยู่ในชั้นเรียนหรือระดับอื่นที่สูงขึ้นของการเข้าถึง แต่ยกเว้นจำเป็นคอนสตรัคจะต้องเข้าถึงระดับและการเข้าถึงในระดับเดียวกันของชั้นเรียนของตน
ในฐานะที่เป็นฟังก์ชั่นหรือวิธีพารามิเตอร์วิธีการของพารามิเตอร์เริ่มต้นระดับการเข้าถึงไม่สามารถจะน้อยกว่าระดับการเข้าถึงวิธีการเริ่มต้น
วิธีการเริ่มต้นเริ่มต้น
สวิฟท์คือโครงสร้างชั้นมีวิธีการเริ่มต้นเริ่มต้นด้วยไม่มีพารามิเตอร์สำหรับทุกสถานที่ให้บริการของพวกเขาเพื่อให้ได้รับมอบหมาย แต่ไม่ได้ให้ค่าเฉพาะ
วิธีการเริ่มต้นเริ่มต้นอยู่ในระดับเดียวกันของการเข้าถึงและชนิดของระดับการเข้าถึง
ตัวอย่าง
ใช้คำสั่งคำหลักที่จำเป็นก่อนที่จะเข้าถึง () วิธี init ในแต่ละประเภทรอง
class classA { required init() { var a = 10 print(a) } } class classB: classA { required init() { var b = 30 print(b) } } let res = classA() let show = classB()
เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:
10 30 10
ข้อตกลงการเข้าถึง
หากคุณต้องการข้อตกลงที่ชัดเจนยืนยันระดับการเข้าถึงที่เราต้องทราบว่าคุณต้องการให้แน่ใจว่าข้อตกลงดังกล่าวจะใช้เฉพาะในบทบาทระดับการเข้าถึงข้อมูลที่คุณระบุโดเมน
หากคุณกำหนดโปรโตคอลระดับการเข้าถึงของประชาชนเพื่อให้บรรลุฟังก์ชั่นที่จำเป็นของข้อตกลงดังกล่าวจะถูกจัดไว้ให้โดยระดับการเข้าถึงประชาชน ซึ่งแตกต่างจากชนิดอื่น ๆ เช่นชนิดอื่น ๆ ของระดับการเข้าถึงของประชาชนระดับการเข้าถึงสำหรับสมาชิกของภายในของพวกเขา
public protocol TcpProtocol { init(no1: Int) } public class MainClass { var no1: Int // local storage init(no1: Int) { self.no1 = no1 // initialization } } class SubClass: MainClass, TcpProtocol { var no2: Int init(no1: Int, no2 : Int) { self.no2 = no2 super.init(no1:no1) } // Requires only one parameter for convenient method required override convenience init(no1: Int) { self.init(no1:no1, no2:0) } } let res = MainClass(no1: 20) let show = SubClass(no1: 30, no2: 50) print("res is: \(res.no1)") print("res is: \(show.no1)") print("res is: \(show.no2)")
เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:
res is: 20 res is: 30 res is: 50
การเข้าถึงเพิ่มเติม
คุณสามารถภายใต้เงื่อนไขที่ช่วยให้ระดับโครงสร้างการขยายตัวของการแจงนับ สมาชิกขยายของสมาชิกชั้นเรียนเดิมควรจะได้ในระดับเดียวกันในการเข้าถึง ตัวอย่างเช่นคุณขยายชนิดที่พบบ่อยแล้วคุณเพิ่มสมาชิกใหม่ควรจะมีสมาชิกเดียวกันของระดับการเข้าถึงภายในเริ่มต้นเดิม
หรือคุณสามารถประกาศอย่างชัดเจนในระดับขยายการเข้าถึง (เช่นการใช้นามสกุลส่วนตัว) ภายในขยายไปยังสมาชิกทุกคนยืนยันระดับการเข้าถึงเริ่มต้นใหม่ ระดับการเข้าถึงเริ่มต้นใหม่ยังสามารถยืนยันสมาชิกรายบุคคลปกคลุมด้วยระดับการเข้าถึง
การเข้าถึงทั่วไป
ระดับการเข้าถึงประเภททั่วไปหรือฟังก์ชั่นทั่วไปที่จะใช้ประเภททั่วไป, ฟังก์ชั่นของตัวเองชนิดพารามิเตอร์ทั่วไปของสามระดับต่ำสุดของการเข้าถึง
public struct TOS<T> { var items = [T]() private mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push("Swift") print(tos.items) tos.push("泛型") print(tos.items) tos.push("类型参数") print(tos.items) tos.push("类型参数名") print(tos.items) let deletetos = tos.pop()
เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "类型参数"] ["Swift", "泛型", "类型参数", "类型参数名"]
นามแฝงประเภท
สิ่งที่คุณพิมพ์ชื่อแทนจะถูกกำหนดเป็นชนิดที่แตกต่างกันเพื่อความสะดวกในการควบคุมการเข้าถึง ระดับการเข้าถึงข้อมูลของประเภทชนิดนามแฝงไม่สามารถจะสูงกว่าระดับเดิมในการเข้าถึง
ยกตัวอย่างเช่นประเภทระดับส่วนตัวนามแฝงสามารถกำหนดให้กับประชาชนภายในประเภทส่วนตัว แต่ประเภทระดับประชาชนนามแฝงเท่านั้นที่สามารถตั้งค่าให้เป็นประเภทระดับประชาชนไม่สามารถตั้งค่าประเภทระดับภายในหรือส่วนตัว .
หมายเหตุ: กฎนี้ยังนำไปใช้ในกรณีเพื่อตอบสนองโปรโตคอลสอดคล้องกับชื่อประเภทที่เกี่ยวข้องและนามแฝง
public protocol Container { typealias ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } } struct Stack<T>: Container { // original Stack<T> implementation var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } // conformance to the Container protocol mutating func append(item: T) { self.push(item) } var count: Int { return items.count } subscript(i: Int) -> T { return items[i] } } func allItemsMatch< C1: Container, C2: Container where C1.ItemType == C2.ItemType, C1.ItemType: Equatable> (someContainer: C1, anotherContainer: C2) -> Bool { // check that both containers contain the same number of items if someContainer.count != anotherContainer.count { return false } // check each pair of items to see if they are equivalent for i in 0..<someContainer.count { if someContainer[i] != anotherContainer[i] { return false } } // all items match, so return true return true } var tos = Stack<String>() tos.push("Swift") print(tos.items) tos.push("泛型") print(tos.items) tos.push("Where 语句") print(tos.items) var eos = ["Swift", "泛型", "Where 语句"] print(eos)
เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "Where 语句"] ["Swift", "泛型", "Where 语句"]