Merhaba arkadaşlar, Swift dersleri serimize Swift Access Control (Erişim Belirleyicileri) ile devam ediyoruz. Erişim belirleyicileri sayesinde projemizdeki bazı modüllere, sınıflara, metodlara vb. erişim kısıtlanmıştır. Bu kısıtlamadaki amaç ise nesne yönelimli programlamanın temel taşlarından biri olan kapsülleme işlemini gerçekleştirmektedir. Kapsülleme sayesinde sınıflarımızı, değişkenlerimizi, methodlarımızı gereksiz erişimlerden kurtarabiliriz ve sadece izin verdiğimiz ölçüde değiştirilmesine ve erişilmesine imkan sağlamış oluruz. Nesne yönelimli programlama dersimizin detaylarını buradan okuyabilirsiniz.
Swift Access Control
Swift programlama dili 5 farklı erişim belirleyicisine sahiptir. Bunlar kısıtlama sıralamasına göre en az kısıtlayandan(least restrictive), en çok kısıtlayana doğru(most restrictive) göre şu şekildedir:
- open
- public
- internal
- fileprivate
- private
Bir değişken, sınıf vb. tanımladığımız durumda eğer erişim belirliyicisini yazmamıza gerek yoktur, bu durumda tanımladığımız bu değişken, sınıf vb. standart(default) erişim belirleyicisi olan internal olarak ayarlanmaktadır. Şimdi bu sıralama doğrultusunda erişim belirleyicilerimizi inceleyelim:
Not: Standart erişim belirleyicisinin internal olduğunu belirttik. Eğer bir sınıf, struct vb. bir erişim belirleyicisi almış ise o sınıfın, structın metot ve özellikleri sınıfın erişim belirleyicisinden daha az kısıtlanmış olamaz. Yani fileprivate bir sınıf oluşturduğumuzda bu sınıfın metot ve özellikleri minimum fileprivate olabilir ve bu sınıf için standart erişim belirleyicisi fileprivate olmuş olur. Aynı şey private için de geçerlidir. Eğer bir sınıf private tanımlanmış ise içindeki özellikler standart olarak private olur ve private’dan daha düşük bir kısıtlamaya sahip olamaz.
“open” ve “public” Access Control
open ve public erişim belirleyicileri beraber incelemek doğru olacaktır. Aralarında küçük fark olan bu belirleyiciler en az kısıtlamaya mevcuttur. Bunun anlamı sınıflar arasında erişilebilirlik sınırları en az olanlardır. open ve public belirleyicilere aynı modül içindeki bütün sınıflardan erişilebilir. Ancak farklı bir modülden erişilmek istendiğinde open metodlar override edilebilirken, public metodlar override edilemezler. Bunun en güzel ve anlaşılır örneğini yine tableview ile verebiliriz. Tableview projemize import ettiğimiz UIKit framework içerisinde yer almaktadır dolayısıyla farklı bir modül içerisindedir. Yukarıda da bahsettiğimiz gibi tableview metodlarını override edebilmek için open erişim belirleyicisine ihtiyaç duyarız. Aşağıda tableview sınıfının tanımlanırken kullanılan erişim belirleyicisini open olarak görmekteyiz.
Yukarıda gördüğümüz sınıfın erişim belirleyicisi public olsaydı metotlarını override edemez idik. Eğer farklı bir modül yazmayacak isek open erişim belirleyicisine ihtiyaç duymayız ve public erişim belirleyicisi ile bütün işlerimizi halledebiliriz.
“internal” Access Control
Yukarıda da bahsettiğimiz gibi internal standart erişim belirleyicidir. Eğer bir sınıfın, metodun vb. erişim belirleyicisini belirtmemiş isek internal olarak ayarlanacaktır. internal erişim belirleyicisi public erişim belirleyicisine göre biraz daha kısıtlanmıştır. public erişim belirleyicisine farklı modülden erişebiliriz ancak override edemeyiz demiştik, internal erişim belirleyicisine ise farklı bir modülden erişemeyiz. Sadece bulunduğumuz modülün içinde işlemler yapmamıza izin verir.
“fileprivate” Access Control
Erişim belirleyicilerimiz erişim kısıtlamalarını giderek artırmaktadır. fileprivate erişim belirleyicisinde ise sadece aynı dosya içinden erişim sağlanabilir. Aynı dosyadan derken, yeni oluşturduğumuz bir Cocoa Touch Class, Swift Class vb. kastedilmektedir. Oluşturduğumuz bu .swift uzantılı dosyalar içinde birden fazla sınıf, struct vb. oluşturabiliriz. fileprivate erişim belirleyicisi ile sadece bu dosya içinden erişilebilir. Farklı bir dosyadan erişmeye çalıştığımızda hata ile karşılaşırız. Aşağıda örnekler ile bunu açıklayacağız:
Yukarıdaki örnekte, Demo structı içinde oluşturduğumuz iki adet metoda erişim kontrolünü gösterdik. foo() metodu private bir metot ve farklı bir sınıftan erişilemez. Ancak aynı dosya içinde bulunan Check sınıfı ve Demo structı fileprivate erişim belirleyicisi ile erişime izin vermektedir ve içine string parametresi alan ve fileprivate erişim belileyicisine sahip olan food() metoduna erişebilir.
Yukarıda ise Check sınıfımızı alıp farklı bir dosyaya taşıdığımızda artık Demo structının metodlarından hiçbirine erişemediğini görürüz.
Bu metodu zorla eklediğimizde ise yukarıdaki hata ile karşılaşırız.
“private” Access Control
En kısıtlayıcı erişim seviyemiz ise “private”. Eğer bir metodu vb. private yapmış isek sadece aynı sınıf vb. içinden erişebiliriz. fileprivate olduğunda aynı dosya içindeki diğer sınıf, struct vb. erişebiliyorduk ancak private olduğunda sadece aynı sınıf içinden erişebiliriz. Swift 4’ten öncesinde aynı sınıfın eklentisinden(Extension) dahi erişime izin verilmemekteydi ancak Swift 4 ile birlikte extension içinden private özelliklere(property) ve metodlara erişim sağlanabilmektedir.
Demo structımızın içindeki private olan foo() metoduna erişemiyoruz ve yukarıdaki hata ile karşılaşıyoruz.
Getters and Setters !
Swift programlama dilinin gücü sayesinde tekli sınırlama da yapabiliriz. Tekli sınırlamadan kasıt bir değişkenin vb. okunmasına olanak veren (get) anahtar sözcüğü ve değiştirilebilmesine olanak veren (set) anahtar sözcüğü bu değişkenimiz için farklı erişim belirleyiciler ile kullanılabilir. Örneğin boolean bir parametremiz olsun. Bu parametremizin önüne public private(set) erişim belirleyicisi eklediğimizde bu parametrenin public olarak okunabileceğini ancak private olarak değişebileceğini belirtmiş oluruz. (set) anahtar kelimesini private, fileprivate ve internal ile kullanabiliriz.
public private(set) var gender: Bool? fileprivate private(set) var gender: Bool? internal fileprivate(set) var gender: Bool?
Yukarıda 3 farklı örnek görülmektedir. Bu örneklerde gender parametresi için iki adet erişim belirleyici kullanılmıştır. Daha açıklayıcı olması için ilk örneğimiz üzerinden inceleyelim; ilk erişim belirleyicisi public, ikinci erişim belirleyicisi ise private(set). Burada (set) anahtar kelimesinin yanında private bulunmaktadır ve bu gender parametresinin değerini değiştirmek için(set edebilmek için) private erişim belirleyicisinin kullanılması gerektiğini belirtir. Bu doğrultuda gender parametresinin değerini sadece içinde bulunduğu sınıf, struct vb. içinde değiştirebiliriz. Ancak ilk yazdığımız public erişim belirleyicisi bu parametrenin public olarak okunabilmesine(get edilebilmesine) izin verir. Kısacası yazdığımız bu gender parametresinin değerini değiştirmek istersek sadece içinde bulunduğu sınıfta değiştirebiliriz, ancak proje içindeki bütün sınıflardan erişebiliriz. Diğer örnekleri de ilk örneğimiz gibi değerlendirebiliriz ve daha farklı kombinasyonlar üretebiliriz. Örneğin: public internal(set) var gender: Bool? gibi. Getter ve setter için farklı erişim belirleyicisi yazmak bize kullanım kolaylığı ve esneklik sağlamaktadır.
Not: Yukarıda bir parametre için iki farklı erişim belirleyicisi yazabileceğimizi açıkladık. Bunlardan ilki getter için, ikincisi ise setter için kullanılıyordu. Bir parametrenin setterı için yazdığımız erişim belirleyicisi getterı için yazdığımız erişim belirleyicisinden daha az kısıtlayıcı olamaz.
fileprivate internal(set) var gender: Bool?
Yukarıda örneği görülen kullanım yanlıştır. Yukarıdaki örneği Xcode’a yazdığımızda ‘Fileprivate property cannot have an internal setter’ hatasını aldığımızı görürüz. Yani bir parametrenin getter ve setter değerleri için farklı erişim belirleyicisi kullanacak isek; setter için kullandığımız erişim belirleyici, getter erişim belirleyicisinden daha çok kısıtlayan olmalıdır.
Not: Getter ve setter için farklı erişim belirleyicisi kullandığımız farklı bir kullanım daha mevcuttur:
private(set) var gender: Bool?
Yukarıdaki örnekte setter için private erişim belirleyicisi belirlenmiş ancak getter için bir erişim belirleyicisi bulunmamaktadır. Bu durumda getterın erişim belirleyicisi gender parametresinin bulunduğu sınıf vb. standart(default) erişim belirleyicisi olacaktır.
Özet
Bu dersimizde nesne yönelimli programlamanın temel taşlarından biri olan encapsulation(kapsülleme) gerçeklememize olanak veren Swift Access Control konusunu inceledik. Access Control için kullanılan anahtar kelimeleri ve detaylarını inceledik. Bu dersi burada bitirirken herkese faydalı olmasını umarak, mutluluklar dilerim.
Soru, görüş ve önerilerinizi yorum kısmından veya soru-cevap kısmından iletebilirsiniz. Sağlıcakla…
Kaynak: https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html
38