التحكم في الوصول
جزء من قسم البرمجة كائنية التوجه في رحلة Swift على Coddy. الدرس 17 من 57.
التغليف يعني أن النوع يتحكم في كيفية استخدام بياناته. يحدد التحكم في الوصول من يمكنه رؤية خاصية أو طريقة. يؤدي وضع وسم private على عضو إلى إخفائه عن جميع التعليمات البرمجية الموجودة خارج النوع (وعن امتداداته في الملف نفسه):
struct Account {
private var balance = 0
mutating func deposit(_ amount: Int) {
balance += amount
}
}
var a = Account()
a.deposit(50)
// a.balance = 1_000_000 // خطأ: 'balance' غير قابل للوصول بسبب مستوى الحماية 'private'لا يمكن للكود الخارجي بعد ذلك استخدام سوى ما يقدّمه النوع. ويمكن للنوع التحقق من كل تغيير، لذلك لا تنتهي بياناته أبدًا إلى حالة لا يسمح بها النوع:
struct Account {
private var balance = 0
mutating func deposit(_ amount: Int) {
if amount > 0 { balance += amount }
}
func report() -> String {
"balance: \(balance)"
}
}
var a = Account()
a.deposit(50)
a.deposit(-999)
print(a.report())الناتج:
balance: 50لدى Swift خمسة مستويات للوصول. من دون كلمة مفتاحية، يكون العضو internal: مرئيًا في كل مكان ضمن الوحدة نفسها (تطبيقك أو حزمتك). المستويات من الأكثر انفتاحًا إلى الأكثر تقييدًا:
open // يمكن للوحدات الأخرى استخدامه وإنشاء فئات فرعية منه (الفئات فقط)
public // يمكن للوحدات الأخرى استخدامه
internal // الافتراضي: الوحدة بأكملها
fileprivate // ملف المصدر هذا فقط
private // هذا النوع (وامتداداته في الملف)تحافظ أساليب المساعدة الخاصة على صِغر الواجهة العامة: إذ يرى المستدعون ما يفعله النوع، لا كيف يفعله.
struct Password {
private let text: String
init(_ text: String) { self.text = text }
var isStrong: Bool {
hasDigit() && text.count >= 8
}
private func hasDigit() -> Bool {
text.contains { $0.isNumber }
}
}
print(Password("secret123").isStrong)
print(Password("short1").isStrong)الناتج:
true
falseالتحدي
سهلأكمل البنية Locker. إنّ code وitems خاصّتان private. تضيف store(_:code:) عنصرًا فقط عندما يتطابق الرمز، وتُرجع ما إذا كانت قد فعلت ذلك؛ وتُرجع items(code:) العناصر المخزّنة مفصولةً بـ , (أو empty) عندما يتطابق الرمز، وwrong code بخلاف ذلك.
يقرأ الكود المُ supplied رمز الخزانة، ثم يتعامل مع الأوامر put <code> <item> أو open <code>. ويطبع stored أو denied لكل أمر put، والنتيجة لكل أمر open.
ضع كودك في Locker.swift. يحتوي main.swift على كود الإدخال/الإخراج المُ supplied ولا يمكن تعديله.
جرّب بنفسك
// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
var input: [String] = []
while let line = readLine() { input.append(line) }
var locker = Locker(code: input[0])
for cmd in input.dropFirst() {
let p = cmd.split(separator: " ").map(String.init)
if p[0] == "put" {
print(locker.store(p[2], code: p[1]) ? "stored" : "denied")
} else {
print(locker.items(code: p[1]))
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأصناف والكائنات
العمل مع الملفاتتعريف الأصنافالأساليب وselfالمُهيِّئاتالأصناف هي مراجعمراجعة - بطاقة المكتبة4التغليف
التحكم في الوصولللقراءة فقط من الخارجحماية الحالةالمهيئات القابلة للفشلمراجعة - الحساب البنكي7تعدد الأشكال والأنواع العامة
تعدد الأشكالتحويل الأنواعالدوال العامةالأنواع العامةمراجعة - حاسبة الأشكالتدرّب بنفسك: Playground لـ Swift