Kotlinde Fonksiyonlar-2

İsmail Talha DENGİZ
4 min readApr 16, 2020

İlk yazımızda fonksiyon tanımlamadan, bazı kavramlarından ve infix methodu gibi konulardan bahsetmiştik. Şimdi kaldığımız yerden devam edelim. :)

Extension Function(Ek Fonksiyon diyebiliriz :))

Javadan farklı olarak kotlinin bize kattığı diğer bir güzellik de extension function. Örnekler üzerinde daha net anlaşılacaktır fakat tanımlamamız gerekirse şöyle söyleyebiliriz: Üzerinde değişiklik yapamadığımız sınıflara(readOnly) veya sınıfın özünde bir değişiklik yapmak istemediğimizde, o sınıfın içerisine yazmadan istediğimiz özelliği kazandırmak için sanki o classın üye fonksiyonuymuş gibi yazdığımız fonksiyonlara extension function adı verilir.

Yapısı şu şekildedir →fun receiverType.functionName()

Normal fonksiyon tanımından farklı olarak fun keywordünden sonra fonksiyon ismini yazmadan önce extension etmek istediğimiz sınıf yazılır. ReceiverType bu sınıfı temsil eder.

Şimdi elimizde üç tane Int tipinde değişkenimiz olsun ve bunları ekrana yazdıralım. Normalde bu işlemleri şu şekilde gerçekleştirirdik:

Şimdi aynı işlemi normal bir fonksiyon tanımıyla yapalım.

Şimdi ise extension fonksiyon ile nasıl olduğunu görelim. Int classının içeriğine baktığımızda println kavramı yoktur. Biz bu özelliği kazandırmak ve her değişken için println fonksiyonunu çağırmamak için extension function tanımı yapacağız.

infix methodu anlatırken infix method için bir sınıfa ait ya da extension fonksiyon olmalıdır diye söylemiştik. Şimdi nasıl olduğunu görelim.

Aşağıdaki örnekte int, double, long gibi sayı tiplerini içinde bulunduran Number sınıfına extension fonksiyon oluşturduk ve bunu infix method olarak yazdık. Infix olmasından dolayı bir parametre verdik. Fonksiyon içerisinde yer alan this, receiverType olan Number sınıfını(extension yapılan değeri verir) temsil eder. Main fonksiyonu içerisinde ise infix extension fonksiyonumuzu çağırırken ilk verdiğimiz değer Number sınıfına karşılık, ikinci verdiğimiz değer ise number parametresine karşılık geldi. Yine infix method olmasından dolayı nokta kullanmadan konuşuyormuş gibi düz bir şekilde kod yazdık.

Dilersek infix extension fonksiyonu expression formunda kullanabiliriz.

Şimdi kendimiz bir class oluşturalım ve içerisinde normal bir fonksiyon bulunsun(üye fonksiyon-method). Aynı class için üye fonksiyonla aynı isimde, aynı parametre sayısına ve tipine sahip classın alanları dışında extension fonksiyon oluşturalım. Eğer biz aynı isimdeki bu fonksiyonu çağırırsak class içerisindeki üye fonksiyon mu çalışır, yoksa extension fonksiyon mu çalışır?

Kodu kendiniz de denediğinizde üye fonksiyonun extension fonksiyona göre öncelikli olduğunu ve üye fonksiyonun çalıştığını görebilirsiniz(Şartların eşit olduğu durumda :) ).

Şimdi ise yine aynı isime, aynı parametre sayısına ve tipine sahip bir extension fonksiyonumuz ve bir de normal fonksiyonumuz bulunsun fakat her iki fonksiyonda aynı class içerisinde bulunsun. Bu durumda öncelik hangisindedir?(Bir class içerisinde extension fonksiyon tanımladığımızda o fonksiyonu class dışında kullanamayız.)

Aşağıda görüldüğü üzere debug ederek çalıştırdığımızda class içerisinde extension fonksiyon normal fonksiyona göre öncelikli çalışır.(Aynı isime, aynı sayıda parametreye ve geri dönüş tipine sahip olduklarında)

Eğer biz extension fonksiyonun değil de class içerisindeki diğer fonksiyonun(Üye fonksiyonun) çağrılmasını istiyorsak aşağıdaki şekilde bir kullanım yapılmalıdır.

Higher Order Function(Yüksek Seviye Fonksiyon)

Kotlinde fonksiyonlar “First Class Citizen”dır. Yani değişkenlere değer olarak atanabilir, başka fonksiyonlara parametre olarak verilebilir veya bir fonksiyonun geri dönüş değeri olabilir anlamına gelmektedir.

Higher order fonksiyonlar ise basitçe bir fonksiyona parametre olarak verilebilen fonksiyonlardır. Burada parametre olarak vermekten kasıt fonksiyon çağrım işleminin parametre kısmında yapılması değil, fonksiyonun süslü parantezleri arasında kalan alanın başka bir fonksiyona parametre olarak verilmesidir. Yapısal olarak normal fonksiyon tanımı yapılır, parametre parantezleri arasına higher order fonksiyon ismi yazılır, : koyulur ve higher order fonksiyonun parametre parantezleri açılır varsa parametresi yazılır. Sonra -> işareti koyulur ve fonksiyonun geri dönüş tipi belirtilir. Aşağıdaki örnekte daha net görebiliriz.

Nasıl normal bir fonksiyon tanımlıyor ve çağrım esnasında bir parametre gönderiyorsak yukarıda da aynı işlemleri gerçekleştirdik. Tek fark fonksiyonumuz parametre olarak başka bir fonksiyon aldı ve main bloğu içerisinde bu fonksiyonu çağırırken de değer olarak süslü parantezler içerisinde fonksiyonun yapacağı işi belirttik. Şöyle de diyebiliriz, fonksiyon tanımını diğer fonksiyonun parametre parantezleri arasında yaptık, süslü parantezler arasında yazdığımız kısmı ise çağrım işleminin gerçekleştiği yerde yazdık. Bir nevi fonksiyonu ikiye bölmüş olduk. Şimdi hem normal fonksiyon ve higher order fonksiyonun bulunduğu hem de parametre olarak normal değişkenle birlikte bir fonksiyon alan fonksiyonun bulunduğu bir örnekle pekiştirelim.

Normal bir fonksiyon ve Higher Order Fonksiyon
1 Değişken ve 1 Fonksiyon olarak iki parametre olan Fonksiyon

Yukarıdaki örneklerde de görüldüğü gibi aslında normal bir fonksiyon yazıyoruz. Parametre olarak verdiğimizde aynı şekilde fonksiyon tanımlar gibi fonksiyon ismini, parametre ismini ve tipini, geri dönüş tipini yazıyoruz, süslü parantezli kısmını, yapacağı işi ise parametre olarak alındığı fonksiyonun çağrımı esnasında yazmış oluyoruz.

Bir değişkene atayarak Higher Order Fonksiyon tanımlayabiliriz. Eğer Higher Order fonksiyon tek parametre alıyorsa parametreleri yazmak zorunda değiliz(Çağrım esnasında). Bu durumda higher order fonksiyon bize “it” kelimesi ile higher order fonksiyon parametresi tipinde bir değişken verecektir. Eğer higher order fonksiyonun birden fazla parametresi varsa süslü parantezler içerisine bu fonksiyonun aldığı parametreler lambda(->) okundan önce aralarına virgül koyarak yazılır.

İsmi olmayan fonksiyonlara “anonymous fonksiyon” adı verilir.Bu anonymous fonksiyon tanımlamaları da higher order fonksiyon olarak normal bir fonksiyona parametre olarak verilebilir. Anonymous fonksiyonun expression kullanımı da yine higher order fonksiyon olarak normal bir fonksiyona parametre olarak verilebilir.

Higher order fonksiyonlar default değerler alabilirler(infix methodlar alamıyordu). Dikkat edilmesi gereken konu bu değer süslü parantezler içerisine yazılmalıdır. Higher order fonksiyona parametre tanımlarken değişken adı olmadan sadece değişken tipini tanımlayarak da kullanabiliriz.

Fonksiyonlar-1 yazısında infix methodu anlatmıştık. Bu yazımızda ise infix methodun extension fonksiyonla birlikte kullanımını gördük. Şimdi ise ilk olarak infix, extension ve higher order fonksiyonun birlikte kullanımına bir örnek verelim, son olarak da higher order fonksiyonun parametresinin de yine higher order fonksiyon olabileceğine bir örnek vererek konumuzu sonlandıralım. :)

Infix method sadece bir parametre alıyordu. Aşağıdaki örnekte infix methodumuz higher order fonksiyon olarak tek bir parametre aldı ama higher order fonksiyonumuz birden fazla parametre aldı. Bu şekilde kullanım infix method kullanımına engel değildir çünkü bakıldığında infix method tek bir parametre almıştır. Parametre olarak aldığı higher order fonksiyon birden fazla parametre alabilir.

Bir sonraki konumuz olan Classlarda görüşmek üzere, iyi çalışmalar..:)

--

--