Android Programlamanın Yeni Dili Kotlin — 2

Yazımızın önceki bölümüne buradan ulaşabilirsiniz.

Bu yazımızda Kotlin Dili’nin biraz daha detaylarına giriyor olacağız.

İ.K. Notu: Bu yazı için linkteki pluralsight eğitiminden yararlanılmıştır.

arabirim(interface) ve sınıf(class)

arabirim tanımlaması Java’ya benzer şekilde olur. Kotlin’de her şey varsayılan olarak public olduğu için ayrıca public demeye ihtiyaç yoktur. Bir metodu, arabirimi veya sınıfı public yerine kısıtlamak istediğimizde, o zaman belirteç kullanırız.

Bir arabirim ve o arabirimi gerçekleyen bir sınıfın görünümü şöyledir.

Imzalayan arabiriminde bir adet imzala adında bir fonksiyon var. Burada sadece metodun imzası tanımlanır, detay tanımlanması yapılmaz. Insan sınıfıda bu arabirimi gerçekler. imzala metodumuzun/fonksiyonumuzun üzerine yazdığımız için, override anahtar sözcüğünü kullanırız.

Ayrıca, imzala metodunun tanımına bakarsak, eşittir(=) ile bir atama yapılabildiğini görürüz. Buna da metod ifadeleri denir. Tek satırlı metod tanımlarında bu yöntem kullanılabilir. Bu şekilde daha sade kodlar ortaya çıkar. Bu Java’da olmayan bir özelliktir.

Burada Imzalayan arabirimini illa Imzalayan.kt adında dosyada saklanması gerekmez. Java’da public arabirim veya sınıfları, kendi adıyla aynı olan dosyada saklama zorunluluğu vardı ama bu Kotlin’de yok.

Tek bir dosya içinde birçok public arabirim veya sınıf tanımlanabilir.

Bu kodu çalıştırmak istersek, main fonksiyonu ile şu şekilde yapılır.

$ bin/kotlinc insan.kt -include-runtime -d insan.jar && java -jar insan.jar komutuyla tek seferde çalıştırabiliriz.

Dikkat ederseniz sınıftan nesne türetmek için new anahtar sözcüğü kullanılmaz. Her satırın sonunda da noktalı virgül eklemek şart değil, iki koşulda da kod çalışır. Bunun sonucunda, ekrana “Belgeleri imzalayabilirim” yazar.

Sınıflar

Kotlin sınıflarının diğer dillere nazaran çok daha sade bir yapısı vardır. Sınıflarda birincil ve ikincil olmak üzere iki çeşit yapılandırıcı bulunur.

Birincil Yapılandırıcılar

Sınıfa birincil yapılandırıcı(primary constructor) eklemek istenirse, şu şekilde olurdu.

isim adında, tipi String parametre alan bir yapılandırıcı ekledik. Bu sınıfın örneğini oluşturmak için,

Artık parametresi olmayan varsayılan yapılandırıcı yok, o yüzden yeni bir nesne oluşturmak için muhakkak istenilen parametreler, yapılandırıcıda kullanılmak zorunda. Bu kod sonucunda, “Beyza bu belgeyi imzalayabilir” yazar.

Aynı sınıfa yas adında, Int tipinde bir değişken daha ekleyelim.

Burada dikkat ederseniz, isim değişkeni val olarak tanımlanmış. Bu demek oluyor ki, yapılandırıcı sonrası bu alana yeni değer atanamaz. yas alanı ise var ile tanımlandığı için sonradan değeri değiştirilebilir.

Sınıftan yeni bir örnek oluşturursak,

isim alanına yeni değer atamaya çalışırsak, hata alırız ama yas alanına değer atayabiliriz.

Sınıflar Varsayılan Olarak final’dır

Kotlin’de sınıflar varsayılan olarak final oldukları için bu sınıflardan yeni sınıflar türetilemez. Bu özelliği açmak için open ile sınıfı belirtmek gerekir.

Ogrenci sınıfını, Insan sınıfından türetildiğini düşünürsek, bunu yapabilmek için open ile Insan sınıfını dışa açılmalıdır. Aksi takdirde hata alınır.

Dikkat edilecek bir diğer noktada, Ogrenci içinde tanımlanan alanlar için, var ve val kullanmamış olmamız. Bunları kullanmak istesek derleyici bize hata üretir. İlla kullanacağım derseniz override anahtar sözcüğünü kullanmak gerekir. Bu seferde üst sınıf olan Insan’dan farklı alanlar tanımlanmış oluyor ve alt-üst sınıf miras hiyerarşisi bozuluyor.

init Kullanımı

init ile sınıflar içinde yapılandırıcı sonrası tanımlama yapılabilen kod bloğu oluşturabilir. Loglama, veritabanı bağlantıları veya benzer işleri burada yapılabilir.

Basit bir örnekle gösterecek olursak, init içinde yas alanı 10'dan küçük olduğunda hata fırlat. Yukarıda yas alanı 7 tanımlandığı için, bu kodu çalıştırırsak hata oluşur.

isim alanını da kontrole eklersek, şöyle kod oluşur.

Burada ki diğer noktada, isim alanının kontrolünü çift eşit(==) ile kolayca yapılabilmesi. Java’da bunun için equals tarzı metodlar kullanılması gerekiyordu.

İkincil Yapılandırıcılar

Birincil yapılandırıcıların dışında ikincil yapılandırıcılar tanımlanmak istenirse, bu constructor anahtar sözcüğü ile yapılabilir.

Eklenen 3.parametre olan evlimi değişkenini, yapılandırıcı içinde kendimiz değer atamamız gerekiyor. Bunu da this kullanarak yaparız.

İkincil yapılandırıcılar Kotlin’de çok tercih edilen bir yöntem değildir. Bunun yerine daha çok varsayılan değerli parametreler kullanılır.

İkincil yapılandırıcıları sildik ve birincil yapılandırıcıya 3.seçenek olan evlimi değişkenini, varsayılan değer false ile, ekledik. Insan sınıfından 2 tür nesne türetme imkanımız oldu artık. Insan sınıfından oluşturulan 6.satırdaki birinci nesneye bakarsak, 3.parametreye bir değer set etmedik bu yüzden değeri varsayılan olan false olarak kaldı. İkinci nesnede ise 8.satırdaki gibi true olarak değer gönderdik ve varsayılan evlimi=false değerini ezdik.

Çıktılar şu şekilde olur.

Ahmet, 30 yasinda ve evlimi=false bu belgeyi imzalayabilir

Mehmet, 30 yasinda ve evlimi=true bu belgeyi imzalayabilir

Statik Nesneler(Companion Objects)

Kotlin’de Java’dakine benzer statik nesne ve metodlar için companion object bloğu kullanılır. Sınıfın tekilliğini(singleton) sağlamak için yine burası kullanılabilir.

imzala metodunu her çağırdığımızda, ID adlı statik değişkeninin değerini bir artırıyoruz. Bunu da her Insan nesnesini ayrıştırmak için kullanabiliriz.

Tekillik örneğini göstermek için Kotlin’in kendi sitesinden şöyle bir örnek verebiliriz.

Yine aynı sitede, şöyle güzel(!) bir açıklamada bulunuyor.

companion object içinde tanımlı olan nesneler başka dillerdeki statik üyelere benziyor gibi gözükse de, çalışma zamanında gerçek nesnelerin örnek üyeleridir, bu nedenle bir arabirimi gerçeklerken dahi kullanılabilir.

Biraz kafa karıştırıcı değil mi? Şöyle bir örnek verilmiş.

Veri Sınıfları

Bazen sadece verileri tutan sınıflara ihtiyacımız olur. Bunu data class anahtar sözcüğü ile sağlayabiliriz.

Veri sınıflarında Kotlin bize, Java’da olan equals, hashCode, toString ve benzer diğer fonksiyonlarını sağlar. Ayrıca, sınıfı çoklamak için kopyalama özelliği gibi diğer özelliklerde hazır gelir. Veri sınıflarının örneğini println ile yazdırmak istediğimizde bütün alanları açık şekilde yazar.

Diğer iki özelliği de bir örnek ile gösterelim.

8. satırda yazılan kodda, fonksiyonel programlamada çokca kullanılan, destructuring/deconstruction gibi adlar verilen, bir nesneyi tekrar alanlarına ayıran özelliği gösteriliyor. Bu özellik, sınıf alanının çok olduğu durumlarda işleri bayağı kolaylaştırır.

12.satırdaki kopyalama ile bir veri sınıfının istenilen alanlarına yeni değer vererek kopyalama gösteriliyor. Bu da aynı şekilde veri sınıflarının kullanışlı özelliklerinden.


Bir sonraki yazımızda görüşmek üzere…