Swift | Initializers 🏗️

cemal tüysüz
3 min readDec 25, 2022

Herkese selamlar 🖖 Bu yazıda temelden başlayarak initializer nedir, class ve struct yapılarında initializer, Convenience, Failable ve Required initializer konularına değineceğiz 🚀 Hazırsanız başlayalım.

Nedir bu Initializer ? ⚒️

Bu yapı Object Oriented Programming desteği olan dillerin neredeyse hepsinde bulunur.

Initializer yapısı sınıfların oluşturucu fonksiyonudur. Sınıfınız oluşurken hangi init yöntemini tercih ettiyseniz o yöntem ile sınıfınız oluşturulur. Eğer bir init yöntemi belirtmediyseniz her sınıfta var olan default boş bir init yöntemi yine run ediliyor olur.

Swift de kullanılan default initializer (‘init()’ ) aslında Designated Initializer olarak geçer.

Init yapısını class ve struct sınıf tipleri için ayrı ayrı inceliyor olacağız.

Class’larda Initializer 👷

Yukarıda üç adet field ve 1 adet init tanımı yapılmış bir sınıf görüyoruz. Üçüncü field i top kısım yerine en aşağıya bilerek tanımladım. Bunun sebebi bir sınıfın oluşma aşamasına dikkat çekmekti. Sınıf yaratılırken ilk olarak tanımı yapılan değişken/sabitler belleğe alınır.( Zaten ilk olarak belleğe alınmasaydı init yönteminde field3 u yazdıramazdık.) Sonrasında tercih edilen init yöntemi çalışır.

Yukarıda bizim tanımlandığımız init yöntemi aslında boş bir init yöntemi. Bunu tanımlamak zorunda değildik. Çünkü yukarıda da belirttiğim gibi hiç bir initializer tanımının olmadığı sınıflarda bizim için otomatik olarak empty bir initializer zaten oluşturuluyor . Lakin sınıfımıza başlangıç değerleri atamak zorunda kalsaydık bunun için mecbur bir adet initializer oluşturmak zorunda kalacaktık.

Yukarıdaki örnekte oluşturduğum ikinci bir init yöntemini görüyorsunuz. Bu yöntem ile propertylerime sınıfın oluşma aşaması tamamlanırken başlangıç değerlerini atıyorum.

Swift programlama dilinde oluşturacağınız her tip fonksiyon eğer bir protocole tanımlanmıyorsa parametresi default bir değer alabiliyor. Tıpkı satır 7 deki init yönteminde olduğu gibi.

Bu sayede bir sınıfın genelde 2 farklı init yöntemi oluyor. Bir adet boş initializer ve bir adet dolu initializer. Dolu olanda default atama yapılarak farklı farklı şekillerde kullanılabiliyor.

Aşağıdaki örneği inceleyelim :

Default atama yapısının olmadığı programlama dillerinde bazen bir sürü yapıcı method görebilirsiniz. Hatta bu durumdan ötürü oluşan fazla constructor sorununu çözmek için Builder adında bir design pattern bile mevcut.

Struct’larda Initializer 👷‍♀️

Struct yapılarıdanki initializer mantığı ile class yapısındaki initializer aslında birebir aynı. Yine hiç bir initializer developer tarafından oluşturulmadı ise sistem default bir initializer oluşturuyor. Aradaki fark ise default initializer in oluşturulurken struct içerisindeki stored property lere göre oluşturulmasıdır.

Stored property kulağınıza yabancı geliyorsa swift de properties isimli yazımı okumanızı öneririm.

Struct içerisinde bir field nullable veya default ise o field initializer içerisinde default bir değeri var olarak görülür. Dolayısı ile doldurulması zorunlu kılınmaz.

Yukarıda oluşturulan struct da developer tarafından tanımlanan hiç bir initializer olmadığı için otomatik olarak bir initializer oluşturuluyor.

Satır 2 ve 4 de yer alan field1 ve field3 hem nullable değil hem de default değere sahip değiller. Yani ne olursa olsun doldurulmalılar. Lakin satır 3 de yer alan field2 sistem tarafından optional algılanıp default bir biçimde initializer a eklenir.

Convenience Initializer 👷‍♂️

Convenience initializer sürekli olarak kullanıdığımız default initializer ile birebir aynıdır aslında. Tek farkı tanımlandığında, kapsamı içerisinde designated initializer i çağırmak zorundadır.

Aşağıdaki örnek ile kullanım amacı ve nedenini anlayabilirsiniz :

Convenience initializer sadece Class yapılarında tanımlanabilir. Struct yapılarında kullanılamaz.

Failable Initializers 👨‍🏭

Bazı koşullar sağlanmadığında bir initializer ın o sınıfı oluşturmamasını sağlayabiliriz.

Aşağıdaki örneği inceleyelim :

Human sınıfından bir nesne oluşturulmak isteniyorsa name field i nullable olmamalıdır. Peki ya name field i boş bir string ise ? Bunun da yasak olduğunu varsayarsak her Human nesnesi oluşturulmadan evvel ismin boş olup olmadığını kontrol etmek zorunda kalacağız.

Failable initializer ile bu durumdan aşağıdaki gibi kurtulabiliriz :

Human sınıfını bu şekilde modify ettiğimizde artık isim empty biçimde gelirse sınıf oluşmayacaktır.

Required Initializers 👩‍🏭

Required initializer yapısını sınıfınızda kullandığınızda ve sınıfınız başka bir sınıf tarafından kalıtım alındığında alt sınıf bu yöntemi implement etmek zorunda kalır.

Aşağıdaki örneği inceleyelim :

Child sınıfı Human sınıfından kalıtım aldığında otomatik olarak üst sınıfın yapıcı yöntemini de almak zorunda kalır. Eğer burada required keyword u kullanılmasaydı Child sınıfı bu yöntemi implement etmek zorunda kalmayacaktı.

Required kullanılmasaydı, Child sınıfı bu yöntemi implement etmek zorunda olmazdı evet ama name field i üst sınıf tarafından zorunlu kılındığı için Child sınıfı kendi initializer i üzerinden super kullanarak yinede üst sınıfın initializerini çağırmak zorunda kalacaktı.

Umarım faydalı bir yazı olmuştur 🙏 Bir başka yazıda görüşmek üzere, kendinize iyi bakın 🙌

--

--