برای کسانی که تا به حال از Access Level ها استفاده نمیکردند شاید در شروع کار با آن کمی مقاومت نشان دهند!
اما استفاده از سطوح دسترسی مختلف جدا از این که آسان است، برنامه شما را بسیار حرفه ای تر میکند و حتی در برخی اوقات استفاده از آن از نظر امنیتی بسیار مهم و حائز اهمیت هست!
حال میخواهیم انواع Access Level را در سوئیفت بررسی کنیم.
بصورت کلی در سوئیفت ۵ سطح دسترسی وجود دارد که ما از محدود ترین شروع میکنیم و مرحله به مرحله تا بیشترین سطح دسترسی جلو میریم.
این حالت کمترین سطح دسترسی و محدود ترین حالت ممکن است!
متغیر ها یا متود هایی که با این سطح دسترسی تعریف شوند فقط امکان استفاده در بلاک خود (مثلا فقط در داخل کلاس یا استراکچری که تعریف شده اند) را دارند.
و در خارج محدوده خود restrict یا محدود هستند.
پس اگر نیاز داشتید که خارج کلاس یا استراکچر امکان دسترسی به برخی متغیر ها و متود ها وجود نداشته باشد میتونید از private
استفاده کنید.
به مثال زیر دقت کنید:
class Wallet {
var cardNumber: String
var balance: Double
private var password: String
init(cardNumber: String, balance: Double, password: String) {
self.cardNumber = cardNumber
self.balance = balance
self.password = password
}
}
var myWallet = Wallet(cardNumber: "1234123412341234", balance: 0, password: "SomePassword1234")
print(myWallet.cardNumber) // ✅ این خط به درستی اجرا میشود
print(myWallet.password) // 🛑 این خط با خطا مواجه میشود چون در حال تلاش برای دسترسی به یک متغیر خصوصی هستیم!
در این حالت در تمام File ای که در آن متود یا کلاس تعریف شده است، به آن دسترسی داریم.
یعنی برای مثال اگر در فایل Test.swift یک متغیر از یک کلاس را fileprivate
کنیم در خود فایل Test.swift میتوانیم به آن دسترسی داشته باشیم. اما در یک فایل دیگر دسترسی نداریم.
به مثال زیر دقت کنید، کد های مربوط به فایل 1 برنامه هست:
// 👀 File 1
struct Iphone {
private func faceIdPassword() {
print("unlock face id")
}
fileprivate func photoApp() {
print("access to photo app")
}
func showTime() {
print("show current time")
}
}
let myIphone = Iphone()
myIphone.showTime() // ✅ بدون مشکل اجرا میشود
myIphone.photoApp() // ✅ چون در خود فایل فراخوانی شده مشکلی ندارد و اجرا میشود
myIphone.faceIdPassword() // 🛑 با خطا مواجه میشود! چون خصوصی است فقط در داخل استراکچر آیفون در دسترس است
حال در فایل 2 میخواهیم از این استراکچر استفاده کنیم:
// 👀 File 2
let myIphone = Iphone()
myIphone.showTime() // ✅ بدون مشکل اجرا میشود
myIphone.photoApp() // 🛑 با خطا مواجه میشود! چون در یک فایل دیگر فراخوانی شده است
myIphone.faceIdPassword() // 🛑 چون خصوصی است فقط در داخل استراکچر آیفون در دسترس است
این حالت، حالت پیش فرض تمام متغیر ها و کلاس ها و ... است.
پس در واقع اگر سطح دسترسی را مشخص نکنیم (مثل اکثر اوقات که نمیکنیم) حالت دسترسی بصورت خودکار Internal میشود. که از پرکاربرد ترین سطح های دسترسی در سوئیفت است.
تمام اعضایی که با این سطح دسترسی تعریف شوند در تمام سطح ماژول در دسترس هستند.
به مثال زیر که کد های فایل 1 است دقت کنید:
// 👀 File 1
struct Programmer {
var name: String // چون مشخص نکردیم، سطح دسترسی داخلی است
internal var lastName: String
internal func showName() {
print("اسم برنامه نویس \(name)")
}
func showLastName() { // چون مشخص نکردیم، سطح دسترسی داخلی است
print("نام خانوادگی برنامه نویس \(lastName)")
}
}
let programmer = Programmer(name: "میلاد", lastName: "خط شب")
programmer.showName()
programmer.showLastName()
حالا بریم سراغ فایل 2:
// 👀 File 2
let anotherProgrammer = Programmer(name: "داریوش", lastName: "ایرانی")
// ✅ هر دو خط بدون مشکل اجرا میشوند چون هر دو سطح دسترسی داخلی دارند و در تمام فایل های ماژول امکان استفاده دارند
anotherProgrammer.showName()
anotherProgrammer.showLastName()
پس اگر نیاز داشتید در تمام پروژه به اعضا دسترسی داشته باشید سطح دسترسی آن را internal بذارید. (در واقع چیزی ننویسید خودش internal میشود!)
اگر دارید یک فریمورک یا پکیج مینویسید، طبیعتا نیاز درید متود ها و متغیر هاتون خارج از ماژول خود هم امکان دسترسی داشته باشند.
در این حالت میتوانید از سطح دسترسی public
استفاده کنید.
به مثال زیر از ماژول 1 دقت کنید: (فرض کنید این لایبرری هست که دارید مینویسید)
// 👀 Module 1 (your framework)
public class CustomView {
public func drawSomeView() {
print("draw some view")
}
public init() {}
}
حال میتوانیم از این استراکچر در یک ماژول دیگر مثل اپ اصلی استفاده کنیم:
// 👀 Module 2 (your standard app)
let myView = CustomView()
myView.drawSomeView() // ✅ بدون مشکل اجرا میشود
و اما بالاترین سطح دسترسی open
هست که تفاوتی که با حالت public
دارد این است که در این حالت امکان override
و ارث بری از این اعضا را داریم.
تو حالت قبلی یعنی public
میتوانستیم از کلاس استفاده کنیم اما نمیتوانستیم از آن ارث بری کنیم.
در حالت open
این دسترسی نیز در اختیار ما قرار دارد. به مثال زیر از ماژول 1 دقت کنید:
// 👀 Module 1 (your framework)
open class CustomView {
public func drawSomeView() {
print("draw some view")
}
public init() {}
}
حال میتوانیم از این کلاس در پروژه اصلی خودمان استفاده و در صورت نیاز ارث بری کنیم:
// 👀 Module 2 (your standard app)
class NewCustomView: CustomView {
func drawOrangeView() {
print("draw orange view")
}
}
let myView = NewCustomView()
myView.drawSomeView() // ✅ بدون مشکل اجرا میشود
myView.drawOrangeView() // ✅ بدون مشکل اجرا میشود
تو این مقاله جامع تمام سطح های دسترسی سوئیفت را بررسی کردیم و سعی کردیم با مثال برایتان توضیح دهیم.
و در مرحله اخر هم میخواهیم یک مقایسه بین تمام حالت ها داشته باشیم که حسن ختامی برای این مقاله باشد.
سطح دسترسی | داخل بلاک | در فایل | در ماژول | خارج ماژول | ارث بری خارج ماژول |
---|---|---|---|---|---|
private |
✅ |
🛑 |
🛑 |
🛑 |
🛑 |
privatefile |
✅ |
✅ |
🛑 |
🛑 |
🛑 |
internal |
✅ |
✅ |
✅ |
🛑 |
🛑 |
public |
✅ |
✅ |
✅ |
✅ |
🛑 |
open |
✅ |
✅ |
✅ |
✅ |
✅ |
اگر سوالی داشتید در زیر همین مقاله یا اینستاگرام بپرسید با افتخار پاسختون رو میدم 🚀