คุณสมบัติภายในแบบอ่านอย่างเดียวภายนอกแบบอ่านอย่างรวดเร็ว


104

ใน Swift วิธีทั่วไปในการกำหนดรูปแบบทั่วไปที่คุณสมบัติคือการอ่านอย่างเดียวจากภายนอก แต่สามารถแก้ไขได้ภายในโดยคลาส (และคลาสย่อย) ที่เป็นเจ้าของ

ใน Objective-C มีตัวเลือกดังต่อไปนี้:

  • ประกาศคุณสมบัติเป็นแบบอ่านอย่างเดียวในอินเทอร์เฟซและใช้ส่วนขยายคลาสเพื่อเข้าถึงคุณสมบัติภายใน นี่คือการเข้าถึงแบบข้อความดังนั้นจึงใช้งานได้ดีกับ KVO, atomicity ฯลฯ
  • ประกาศคุณสมบัติเป็นแบบอ่านอย่างเดียวในอินเทอร์เฟซ แต่เข้าถึงการสำรองข้อมูลภายใน เนื่องจากการเข้าถึงเริ่มต้นสำหรับ ivar ได้รับการป้องกันสิ่งนี้จึงทำงานได้ดีในลำดับชั้นของคลาสโดยที่คลาสย่อยจะสามารถแก้ไขค่าได้ แต่ฟิลด์จะเป็นแบบอ่านอย่างเดียว

ใน Java การประชุมคือ:

  • ประกาศเขตข้อมูลที่มีการป้องกันและใช้ getter สาธารณะแบบอ่านอย่างเดียว (วิธีการ)

สำนวนของ Swift คืออะไร?

คำตอบ:


220

ด้วยคุณสมบัติคลาสคุณสามารถระบุระดับการเข้าถึงที่แตกต่างกันได้โดยนำหน้าการประกาศคุณสมบัติด้วยตัวแก้ไขการเข้าถึงตามด้วยgetหรือsetระหว่างวงเล็บ ตัวอย่างเช่นคุณสมบัติคลาสที่มี public getter และ private setter จะถูกประกาศเป็น:

private(set) public var readonlyProperty: Int

การอ่านที่แนะนำ: Getters and Setters

ข้อพิจารณาของ Martin เกี่ยวกับระดับการช่วยสำหรับการเข้าถึงยังคงใช้ได้นั่นคือไม่มีprotectedตัวปรับแต่งinternalจำกัด การเข้าถึงโมดูลเท่านั้นเฉพาะprivateไฟล์ปัจจุบันเท่านั้นและpublicไม่มีข้อ จำกัด

บันทึกย่อของ Swift 3

ตัวปรับการเข้าถึงใหม่ 2 ตัวfileprivateและopenได้ถูกเพิ่มเข้าไปในภาษาในขณะที่privateและpublicได้รับการแก้ไขเล็กน้อย:

  • openใช้กับคลาสและสมาชิกคลาสเท่านั้น: ใช้เพื่ออนุญาตให้คลาสเป็นคลาสย่อยหรือสมาชิกถูกแทนที่นอกโมดูลที่กำหนดไว้ publicทำให้ชั้นเรียนหรือสมาชิกสามารถเข้าถึงได้แบบสาธารณะแทน แต่ไม่สามารถสืบทอดหรือเขียนทับได้

  • privateตอนนี้ทำให้สมาชิกสามารถมองเห็นและเข้าถึงได้จากการปิดประกาศเท่านั้นในขณะfileprivateที่ไฟล์ทั้งหมดที่มีอยู่

รายละเอียดเพิ่มเติมที่นี่


ดี! (ฉันมีเสรีภาพในการเพิ่มvarคีย์เวิร์ดที่หายไปเพื่อให้คอมไพล์)
Martin R

ขอบคุณมาก :) ฉันมักจะคัดลอกจากสนามเด็กเล่นและวาง แต่คราวนี้ฉันอาจจะทำผิด
อันโตนิโอ

10
โปรดทราบว่าในเดือนมกราคม 2015 ไวยากรณ์นี้ไม่ถูกต้องนักหากคลาสภายนอกไม่publicควรเป็นinternalหรือไม่มีอะไรเลย (ซึ่งค่าเริ่มต้นจะเป็นคลาสใดก็ตาม - publicหรือinternal) - คือprivate(set) var readonlyProperty: Int
Grimxn

1
ไวยากรณ์นั้นถูกต้องโดยคำนึงถึงสิ่งนั้นก่อนโค้ดที่ฉันเขียนคุณสมบัติคลาสด้วยpublic getter และprivate setter - มันเป็นเพียงตัวอย่าง แต่ใช่ตัวปรับการเข้าถึงสำหรับคุณสมบัติต้อง "เข้ากันได้" กับตัวปรับการเข้าถึงคลาส / โครงสร้าง
อันโตนิโอ

เกี่ยวกับย่อหน้าสุดท้ายฉันเดาว่าสิ่งนี้มีการเปลี่ยนแปลงตั้งแต่เขียนคำตอบ แต่privateตอนนี้ จำกัด เฉพาะการประกาศปัจจุบัน(ไม่ใช่ไฟล์) และfileprivateสามารถใช้ได้สำหรับการ จำกัด เฉพาะไฟล์ปัจจุบัน นอกจากนี้ยังpublicมีข้อ จำกัด บางประการและopenจำเป็นสำหรับไม่มีข้อ จำกัด รายละเอียดที่นี่ .
Nigel

2

ตาม @Antonio เราสามารถใช้คุณสมบัติเดียวเพื่อเข้าถึงเป็นreadOnlyมูลค่าทรัพย์สินทั้งแบบสาธารณะและแบบreadWriteส่วนตัว ด้านล่างนี้เป็นภาพประกอบของฉัน:

class MyClass {

    private(set) public var publicReadOnly: Int = 10

    //as below, we can modify the value within same class which is private access
    func increment() {
        publicReadOnly += 1
    }

    func decrement() {
        publicReadOnly -= 1
    }
}

let object = MyClass()
print("Initial  valule: \(object.publicReadOnly)")

//For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible"
//object.publicReadOnly += 1

object.increment()
print("After increment method call: \(object.publicReadOnly)")

object.decrement()
print("After decrement method call: \(object.publicReadOnly)")

และนี่คือผลลัพธ์:

  Initial  valule: 10
  After increment method call: 11
  After decrement method call: 10
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.