Yazar adı: Damla Çim

Ben Damla Çim. Bolu Abant İzzet Baysal Üniversitesi'nde Bilgisayar Mühendisliği okuyorum. Hobi olarak sokak fotoğrafçılığı ile ilgileniyorum ve boş zamanlarımda yazılım sektöründe kendime seçtiğim alan doğrultusunda blog yazıları yazıyorum.

STEM

Android Programlamaya Giriş: Bir Uygulamanın Anatomisi

Herkese merhabalar, bildiğiniz üzere son yazımızla birlikte Kotlin serimizi noktalamıştık. Bugün ise yeni bir seriye başlıyoruz. Artık uzun bir süre Android programlama üzerine konuşuyor olacağız. Basit bir Android projesi üç kısımdan oluşur. Bunlar activity’ler, uygulama kaynakları ve gradle dosyalarıdır. Bunları kısaca şöyle tanımlayabiliriz: Activity Activity’ler kullanıcı girdisini işleyerek ekranda bir sayfa yapısı oluşturur. Bu sayfa yapısında kullanıcı arayüzü (user interface) görüntülenir. Her activity’nin kendine ait bir yaşam döngüsü vardır. Buna ileriki yazılarda değineceğiz. Resources Kaynak dosyalarının içinde resimler, sesler temalar, renkler ve benzeri dosyalar tutulur. Gradle Gradle bir build tool yani bir inşa aracıdır. Bu dosyalar uygulamanın geliştirme aşamalarını yapılandırmamızı sağlar. Diğer bir deyişle uygulamamızın bir cihaza yüklenebilmesi için gerekli kontrolleri sağlayan bir komut dosyasıdır. Proje Yapısı Bir Android projesi oluşturmak istediğimizi varsayalım. Bilgisayarınızda Android Studio’ya girdiniz ve yeni bir proje oluşturdunuz. Projeyi oluşturduğunuz anda Android Studio size şu şekilde bir proje yapısı oluşturur: MyApplication ├── app │   ├── libs │   └── src │       ├── androidTest │       ├── main │       │   ├── java │       │   ├── res │       │   └── AndroidManifest.xml │       └── test ├── build.gradle └── gradlew Şimdi kısaca dosya ve dizinleri tanıyalım. app Uygulama için kullanılacak kaynak kodları, testleri ve diğer kaynakları depolar. libs Uygulamanın bağlı olduğu local kütüphaneler burada depolanır. androidTest (Instrumentation) Android framework’ü ile gerçek anlamda etkileşime girmesi gereken sınıfların testi için Instrumentation Test yapılması gerekir. main Java ve Kotlin app dosyaları burada bulunur. test (Unit Test) Android framework’ünden bağımsız olan sınıfları/metodları test etmek için kullanılır. Robolectric ve JUnit popüler unit test araçlarıdır. AndroidManifest.xml Uygulamaya ait tüm temel bilgiler, işlevler ve gereksinimler bu dosyada tutulur. Proje oluşturulduğunda default olarak proje yapısına eklenir. Dosyanın xml formatında olması makine ve kullanıcı tarafından okunabilirlik sağlar. Dosyanın görünümü şu şekildedir: Bu dosya içinde yönetebileceğimiz bazı özelliklerden bahsedelim. Uygulamanın adını ve temasını değiştirebiliriz. Version numaraları, kütüphaneler ve SDK sürümlerinde değişiklik yapabiliriz. Uygulama izinlerini kontrol edebiliriz. Activity’leri yönetebiliriz. Açılışta ilk tetiklenen Activity’i ayarlayabiliriz. Uygulamanın iconlarını yönetebiliriz. 3. parti SDK’lerin ayarlarını yönetebiliriz. Build.gradle Gradle dosyaları project module ve app module olmak üzere iki tanedir. Build.gradle (project module) Modüllere yapılan tüm yapılandırmalar bu dosya içinde yönetilir ve gradle versiyon kontrolü bu dosyada yapılır. Build.gradle (app module) Proje için yapılandırma ayarları bu dosyada yapılır. Uygulama sürümü, kütüphaneler ve benzeri diğer özellikler bu dosyadan okunabilir. Gradle içeriğine göz atalım. CompileSdkVersion Uygulamanın derleneceği API düzeyini belirtir. Bu değerden daha yüksek değerli API özellikleri uygulama içinde desteklenmez. buildToolVersion Derleyicinin sürümü burada gösterilir. Gradle plugin 3.0.0’dan itibaren bu alan isteğe bağlıdır. Belirtilmediği takdirde Android SDK build tools’un en son indirilen sürümü kullanılır. defaultConfig Uygulamanın tüm derleme sürümlerine, örneğin debug ve release, uygulanacak seçenekleri içerir. applicationId Uygulamanın tanımlayıcısı niteliğindedir. Uygulamanın Play Store’da başarıyla yayınlanması ve güncellenmesi için eşsiz olması gerekmektedir. minSdkVersion Desteklenen en düşük API seviyesini gösterir. targetSdkVersion Uygulamanın test edileceği maksimum API düzeyini belirtir. versionCode Uygulamanın sürümünü belirten sayısal bir değerdir. versionName Kullanıcıya gösterilen string bir değerdir. dependencies Modül için gereken tüm bağımlılıkları içerir. Gradlew Gradle’ı çalıştırmak için yürütülen bir dosyadır.   Bu yazıda kısaca bir Android projesinin yapısını, dosyaları ve dizinleri görmüş olduk. Gelecek yazıda ise Layout’lardan bahsedeceğiz. Sonraki yazıda görüşmek üzere.  

STEM

Kotlin’de Özel Sınıflar

Herkese merhabalar. Kotlin serisinin 7. ve son yazısını okumaya başlamak üzeresiniz. Benim için hem yazarken hem de doküman karıştırırken öğretici ve keyifli bir süreçti. Buraya kadar gelen, 7 aydır birlikte bir programlama dili üzerine konuştuğumuz bütün okurlara teşekkür ederim. Umarım sizlere bir şey katabilmişimdir. Bu yazıda son basamağımız olan özel sınıflara değineceğiz.

STEM

Kotlin’de Nesne Yönelimli Programlama (2)

Herkese merhabalar. Geçtiğimiz yazıda Kotlin’de nesne yönelimli programlamaya ufak bir giriş yapmıştık. Bu yazıda ise nesne yönelimli programlamada kullanılan diğer kavramlardan bahsedeceğiz. Kalıtım (Inheritance) Önceki yazımızda bahsettiğimiz gibi, her sınıf nesne üzerinde çalışmak için özellikler ve yöntemler içerir. Peki biz bu özellikleri nasıl kullanacağız? Burada devreye kalıtım (inheritance) giriyor. Nesnelerin özelliklerinin ve yeteneklerinin üst sınıftan alt sınıfa miras alınmasına kalıtım denir. Kalıtım kodun tekrar kullanılabilirliğini arttırır. Kotlin’de tek ebeveynli (single-parent) sınıf kalıtım yapısı vardır. Her sınıf bir parent sınıfına sahiptir ve buna superclass denir. Her alt sınıf (subclass), üst sınıfın miras aldığı olanlar da dahil olmak üzere üst sınıfın bütün üyelerini miras alabilir. Kotlin’de sınıflar default olarak final’dır. Yani miras alınamazlar. Bir sınıfı kalıtsal hale getirmek istiyorsak başına open anahtar sözcüğünü getiririz. Bir önceki yazımızda sınıf kavramından bahsederken bir Car sınıfı oluşturmuştuk. Aynı sınıfı ele aldığımızı varsayalım ve bunu kalıtıma uyarlayalım. Araba özelliklerini tuttuğumuz bir sınıf oluşturduk ve bunu open anahtar kelimesiyle tanımladık. Bu sınıfta sadece renk, model ve satılık olup olmadığının bilgisini tutuyoruz. Şimdi Car adında ikinci bir sınıf oluşturalım ve bunu oluşturduğumuz ilk sınıfa bağlayalım. Bu sınıfın başında da open anahtar sözcüğünü kullandık çünkü bu sınıf ara sınıf görevi görecek. Görüldüğü üzere Car sınıfına ait brand parametresi dışında CarProp sınıfındaki parametreler de parantez içinde mevcut. Yani artık Car sınıfından CarProp sınıfındaki bütün özelliklere erişilebilir. Buna kalıtım denir. Aracın kasa tipini tutacağımız başka bir sınıf daha oluşturalım. CarType’da tutacağımız type bilgisi dışında diğer bütün özelliklerin yine bu sınıfa da aktarıldığını görmüş olduk. Şimdi main fonksiyonu içinde bu özellikleri nasıl kullanabileceğimize bakalım. CarType sınıfından car adında bir nesne oluşturduk. Car nesnesi görüldüğü üzere mevcut bütün özelliklere erişebilmektedir. Kodumuzun çıktısı şu şekildedir: Car brand: Opel Car type: Sedan Car color: Black Car model: 2020 Is for sale? : true Interface (Arabirim) Nesne yönelimli programlamanın temel yapılarından biri olan interface, classlarda yapılacak ortak işlemleri deklare etmek için kullanılır ve ilgili classlara implement edilir. Yapı şu şekildedir: interface  InterfaceAdı {  //kod  } Bir örnekle açıklayalım. AverageGrade adında bir interface oluşturduk ve Grade adında bir sınıf tanımladık. Kod bloğunun içinde calculate metodu override edildi. Bu interface’i implement eden herhangi bir sınıf interface içindeki metodu override etmek zorundadır. Overriding Bir metodun tekrar yazılması işlemine override denir. Herhangi bir sınıfa kalıtım yoluyla ya da interface kullanarak dahil edilen metotlar bu yöntemle değiştirilerek tekrar yazılabilir. Interface yapısında override zorunlu bir işlemdir. Abstract Class Tekrar kullanılmak istenen bir görevi ya da özelliği başka sınıflara devretmek için kullanılır. Kalıtım uygulanan diğer sınıflardan farkı ise abstract classtan nesne üretilemez. Tanımlama yaparken abstract anahtar sözcüğünü kullanırız. Bir örnekle açıklayacak olursak: Abstract sınıflar doğrudan başlatılamaz ve subclasslarda (alt sınıflarda) override edilmesi gereken işlemler olabilir. Abstract classlar metotların ve özelliklerin subclasslara implement edilmesi bakımından farklıdır. Yukarıdaki örneği baz alacak olursak eat() metodunu direkt olarak devraldığımızı görürüz. Fakat bazı özellikleri override ederek kullanmak zorunda kaldık. Extension Function Kalıtım kullanmadan bir sınıfı yeni işlevlerle genişletmek (extend) istediğimizde extension fonksiyonlarını kullanırız. Bu yöntemle kod üzerinde değişiklik yapmamıza da gerek kalmaz. Kotlin’de kalıtım mantığından ve kalıtım için diğer gerekli özelliklerden bahsetmiş olduk. Kotlin serimizin sonuna yaklaşmaktayız ve eğer buraya kadar geldiyseniz umarım keyifli bir yolculuk olmuştur. Bir sonraki yazıda Kotlin’de kullanılan özel sınıflardan bahsedeceğiz. Bir sonraki yazıda görüşmek üzere, hoşça kalın.

STEM

Kotlin’de Nesne Yönelimli Programlama (1)

Herkese merhabalar. Bugün Kotlin serimizin son adımı olan nesne yönelimli programlama ve kavramlarına değineceğiz. Nesne yönelimli programlamada temel amaç kod karmaşıklığını azaltmak ve kodun yazımını kolaylaştırmaktır. Kavramlardan bahsetmeden önce kısaca nesne yönelimli programlamanın ne olduğunu anlamaya çalışalım. Nesne yönelimli programlama (Object Oriented Programming), nesnelere (object) ve nesneler üzerinden yapılacak işlemlere odaklanır. Örneğin bir arabanın renginin, fiyatının ya da modelinin bilgisayar ortamına aktarılması nesne yönelimli programlamaya örnektir. Diğer bir deyişle nesnenin kendisine ait özelliklerini kullanmamıza olanak sağlayan bir dil modelidir. Şimdi detaylıca nesne yönelimli programlamanın kavramlarına göz atalım. Class Sınıflar (class) nesne yönelimli programlamanın temelini oluştururlar. Nesnelerin özellikleri ve davranışları ile ilgili ayrıntılar bu yapıda tutulur. Her sınıf nesne üzerinde çalışmak için özellikler ve yöntemler içerir. Sınıf ve nesne birbirine bağlıdır ve her nesnenin bir sınıfı olmak zorundadır. Örnekle açıklayacak olursak, bir araba sınıfımız olduğunu varsayalım. Bu araba sınıfı bazı özellikler ve metotlar içeriyor. Bu sınıftan bir nesne türetebiliriz. Nesnemiz araba sınıfında tanımladığımız her özelliğe ve yönteme erişebilir durumdadır. Arabanın rengini, modelini ve arabanın satılık olup olmadığının bilgisini tutan bir sınıf tanımlayalım. Aynı zamanda bu sınıf bir metot da içersin. Sınıfı tanımlamak için class anahtar sözcüğünü kullandık ve ardından sınıfa bir isim verdik. Gövde kısmında ise bazı değişkenler tanımladık ve onlara değerler atadık. Bu sınıftan bir nesne oluşturmak istediğimizde artık bu değişkenlere erişebileceğiz. Constructors Yapıcı metotlar bir sınıftan nesne türetirken o nesneye başlangıç değeri verilmesine olanak tanır. Kotlin’de bir sınıf primary constructor ve bir ya da birden fazla secondary constructor‘a sahip olabilir. Yukarıda oluşturduğumuz Car sınıfını giriş parametresi alacak şekilde düzenleyelim. Car sınıfımızı düzenledik ve parametreler ekledik. Bu parametrelere ise main.kt dosyasında erişim sağladık. İkinci kodun çıktısı şu şekilde olur: Color: Black Model: 2016 Is for Sale: false Sınıflar default (varsayılan) parametrelere sahip olabilir. Fonksiyonlardan bahsettiğimiz yazıda default parametrelerin nasıl kullanıldığını görmüştük. Aynı şekilde bunu constructorlara da uyarlayabiliriz. Bu şu anlama gelmektedir; sınıftan bir nesne türetildiğinde varsayılan değerler belirtilmek zorunda değildir. Car sınıfımızda ufak bir değişiklik yaparak model parametresini default parametre yapalım. Primary Constructor Primary constructor direkt sınıf tanımlanırken sınıf adının yanında, sınıf içerisindeki değişkenlere başlangıç değeri atamak için kullanılır. Teknik olarak ilk kod bloğu ile ikinci kod bloğu aynıdır. Fakat biz Kotlin’de ilk kod bloğunu daha yaygın olarak kullanıyoruz. Initializer Block Kotlin’de primary constructor içine kod yazamayız. Bu yüzden kod yazmak için init bloklarını kullanırız. Sınıf içerisinde birden fazla init bloğu olabilir ve kodlar sırasıyla yürütülür. Aynı zamanda init bloğu, primary constructor’ın gövdesi konumundadır. Bir örnekle göz atalım. İlk kod bloğunda giriş parametresine sahip bir sınıfımız var. Constructor içinde çalışmak istediğimiz için bir init bloğu oluşturduk ve içine bir ifade yazdık. Bu sınıftan bir nesne türetildiğinde (ikinci kod bloğu) kod yürütüldüğü anda init bloğu çalışır ve println ifadesi çıktımız olur. Secondary Constructor Bir secondary constructorı tanımlarken constructor anahtar sözcüğünü kullanırız. Secondary constructor this anahtar kelimesini kullanan bir primary constructor çağırmalıdır. Bunun yerine primary constructorı çağıran başka bir secondary constructorı da çağırabilir. Calculate sınıfının içinde bir primary constructorımız var. Giriş olarak double tipinde bir radius değişkeni tutuyor. İki tane de secondary constructorımız var. Birden çok constructora sahip sınıflarda init bloğu, secondary constructorlardaki herhangi bir koddan önce çalışacaktır. Bu yüzden çıktı olarak ilk önce println ifadesini görürüz. Getters ve Setters Getter ve Setter her sınıf özelliği için varsayılan olarak oluşturulur ve özelliklere erişmemizi sağlar. Kotlin var anahtar kelimesiyle tanımlanmış değerler için otomatik olarak get ve set metotları oluşturur fakat val anahtar kelimesiyle tanımlanan değişkenler sadece okunur durumdadır. Bu yüzden bu değişkenler için set metodu oluşturulmaz. Kod formatı ise şu şekildedir: field anahtar kelimesi değişkeni (name) temsil etmektedir. Value ise değişkene atanacak değer için kullanılır. Value yerine başka bir kelime de kullanabiliriz. Bu metotlar Kotlin’de varsayılan olarak bulunduğu için özelleştirilmiş halleri dışında kullanımları gerekli değildir. Custom Getter ve Setter Bir sınıfın içinde özelleştirilmiş getter ve setter metotları kullanabiliriz. Parametre olarak belirttiğimiz ad ve soyad değişkenini birleştiren özel bir get metodu tanımladık. Burada fullName’e özellik gibi erişim sağlayabiliriz ve get() metodu yürütülür. Şimdi de özelleştirilmiş setter metoduna göz atalım. Bir Student sınıfının içinde özel get ve set metotları oluşturduk. Her metodun içine ise bu metodun çalıştığına dair ibareler ekledik. Main fonksiyonu çalıştırıldığında kodumuzun çıktısı şu şekilde olacaktır: set method first get method second get method Damla’s grade is 89 Sınıfın içerisinde ilk önce set metodu işleme alındı. Set metodunda koda, değişkene atanacak değerin uzunluğunun ikiden küçük olması halinde name’in (field) geçersiz olacağını söyledik. Sonrasında ise ilk get() metodumuz çalıştı ve ismi string tipinde döndürdü. Son olarak ise ikinci get() metodumuz çalıştı ve grade değişkenine özellik olarak erişebilmemiz sağlandı. Main fonksiyonunda Student sınıfından bir student nesnesi oluşturduk ve “.” operatörü kullanarak name değişkenine bir isim atadık. Sonrasında ise bunları ekrana yazdırdık. Bu yazıda sınıf, nesne, constructor ve getter/setter metotlarına değinmiş olduk. Sonraki yazımızda ise kalıtım (inheritance), extension function ve special classes konularına değineceğiz. Nesne yönelimli programlamanın ikinci yazısında görüşmek üzere, hoşça kalın.

STEM

Kotlin’de Fonksiyonlar

Herkese merhaba, bugünkü yazımızda Kotlin’de fonksiyon tiplerine değineceğiz. Fonksiyonlar; kodları bir arada tutan, bir işlemi gerçekleştiren ve bir değer döndürebilen kod bloklarıdır. Kotlin’de fonksiyonlar fun anahtar kelimesiyle deklare edilir ve adlandırılmış ya da varsayılan değerler ile bağımsız değişkenler alabilirler. Şimdi fonksiyon tiplerine göz atalım.

STEM

Kotlin’de List ve Array Mantığı

Merhabalar, Kotlin temelleri serimize kaldığımız yerden devam ediyoruz. Bugünkü yazımızda Kotlin’deki list ve array mantığına değineceğiz. Kotlin tarafında bir ya da birden fazla aynı tipte veriyi tutmak için Collections yapılarını kullanırız. Fakat biz bugün Android Development Resources for Educators dokümanında anlatıldığı gibi sadece list ve arraylerden bahsedeceğiz. List List’lerde elemanlara liste içerisindeki pozisyonları yani index değerleri aracılığıyla erişiriz. Değişkenler sıralı biçimdedir ve bir öğe liste içerisinde birden fazla kez bulunabilir. Google’ın bize sunduğu dokümanda da belirtildiği gibi kurallı bir cümle list’e örnek olarak gösterilebilir. Cümle kurallı olduğu için kelimelerin sırası önemlidir ve kelimeler sıralı bir şekildedir. Kotlin’de listeler mutable (değiştirebilir) ya da read-only (salt okunur) şeklinde olabilmektedir. Read-only listeler için listOf(), mutable listeler için ise mutableListOf() ifadelerini kullanacağız. Şimdi listOf() ile ilgili bir örnek yapalım. Şehir isimlerini sıralı bir şekilde cities adlı değişkenin içinde list yardımıyla tuttuk. Kodun çıktısı şu şekildedir: [İstanbul, Tekirdağ, Ankara, İzmir] Şimdi ise mutable bir liste örneği yapalım. Bu kod bloğunda ise iki farklı çıktı aldık. İlk çıktımız yukarıda yazmış olduğumuz kod bloğunun çıktısıyla aynıdır. Aradaki tek fark listemiz mutable yani değiştirilebilir bir liste olduğu için liste içinden eleman çıkarma işlemini gerçekleştirebildik. Bu yüzden kod hata vermedi ve ikinci çıktımız şu şekilde oldu: [İstanbul, Tekirdağ, İzmir] Daha önceki yazılarımızda val anahtar kelimesiyle tanımlanan bir değerin değiştirilemeyeceğinden bahsetmiştik. Fakat burada üzerinde değişiklik yaptığımız listeyi val anahtar kelimesiyle tanımladığımız bir değere atadık. Burada dikkat edilmesi gereken nokta şudur; listenin hangi değişkene atıfta bulunduğunu değiştiremeyiz ancak listenin içeriğinde değişiklikler yapabiliriz. Aynı liste üzerinde eleman ekleme ve index değerine göre silme işlemi de yapabiliriz. Onun da örneğini verelim. Arrays Diziler aynı tipte birden çok veriyi saklamamıza olanak sağlar. Verileri kolayca sıralamak ve içlerinde arama yapmak için diziler kullanılır. Dizilerin boyutları sabittir ve elementleri (eleman ya da verileri) mutable özellik gösterir. Ayrıca dizi içinde ekleme çıkarma işlemi yapılamaz fakat dizi elemanları üzerinde güncelleme yapılabilir. Bir dizi oluşturalım ve değer ataması yapalım. Colors adında boyutu 4 olan boş bir array tanımladık ve 0. index’ine blue kelimesini atadık. Dizi oluşturmak için bu yöntem kullanılacağı gibi diğer bir yöntem olan arrayOf() da kullanılabilir. Animals adında bir dizi oluşturduk ve içine bazı hayvan isimleri yazdık. Görüldüğü üzere index değerini kullanarak dizinin istediğimiz elemanına erişebiliriz. Aynı zamanda index değerini bildiğimiz bir elemanı başka bir elemanla da değiştirebiliriz. Bonus: Null Safety Yazımızı bitirmeden Kotlin’i oldukça ilgi çekici kılan bir özellikten bahsedelim: Null safety özelliği. Kotlin’de değişkenler default olarak boş tanımlanamaz (safe call operatörü kullanımı hariç). Null referans gösteren bir kod NullPointerException hatasına neden olacaktır. Bu hata önemli bir hatadır. Kotlin’de uygulamayı çökertmeden null olabilecek değişkenleri kolayca kontrol edip bu hatayı önleyebiliriz. Safe Call Operatörü Verinin tipinden sonra kullanılan (?) işareti değişkenin boş olabileceğini belirtmek için kullanılır.   Bugün genel hatlarıyla listelere, dizilere ve Kotlin’deki NullPointerException hatasına değindik. Bir sonraki yazıda ise fonksiyonlardan bahsedeceğiz. Sonraki yazıda görüşmek üzere.    

damla-cim-site
STEM

Kotlin’e Giriş – Basics

Herkese merhabalar. Bu yazımızda Android programlama ve diğer birçok uygulama için kullanılan Kotlin programlama dilini tanıyıp Kotlin’deki değişkenler ve veri tiplerine göz atacağız.

Scroll to Top