Programcılar için Kotlin Temel Eğitim Programı 4: Nesne yönelimli programlama

Bu codelab, Kotlin Bootcamp for Programmers kursunun bir parçasıdır. Bu kurstan en iyi şekilde yararlanmak için codelab'leri sırayla tamamlamanızı öneririz. Bilgi düzeyinize bağlı olarak bazı bölümleri gözden geçirebilirsiniz. Bu kurs, nesne yönelimli bir dil bilen ve Kotlin'i öğrenmek isteyen programcılara yöneliktir.

Giriş

Bu codelab'de bir Kotlin programı oluşturacak ve Kotlin'deki sınıflar ve nesneler hakkında bilgi edineceksiniz. Başka bir nesne yönelimli dil biliyorsanız bu içeriğin çoğu size tanıdık gelecektir. Ancak Kotlin, yazmanız gereken kod miktarını azaltmak için bazı önemli farklılıklar içerir. Ayrıca soyut sınıflar ve arayüz temsilcisi hakkında bilgi edineceksiniz.

Bu kurstaki dersler, tek bir örnek uygulama oluşturmak yerine bilginizi artırmak için tasarlanmıştır ancak birbirlerinden yarı bağımsız oldukları için aşina olduğunuz bölümleri gözden geçirebilirsiniz. Örneklerin çoğu, bunları bir araya getirmek için akvaryum temasını kullanır. Akvaryumun hikayesinin tamamını görmek isterseniz Kotlin Bootcamp for Programmers (Programcılar için Kotlin Temel Eğitim Programı) adlı Udacity kursuna göz atın.

Bilmeniz gerekenler

  • Türler, operatörler ve döngü gibi Kotlin'in temelleri
  • Kotlin'in işlev söz dizimi
  • Nesne yönelimli programlamanın temelleri
  • IntelliJ IDEA veya Android Studio gibi bir IDE'nin temelleri

Neler öğreneceksiniz?

  • Kotlin'de sınıf oluşturma ve özelliklere erişme
  • Kotlin'de sınıf oluşturucuları oluşturma ve kullanma
  • Alt sınıf oluşturma ve devralmanın işleyiş şekli
  • Soyut sınıflar, arayüzler ve arayüz yetkilendirmesi hakkında
  • Veri sınıfları oluşturma ve kullanma
  • Singleton'lar, enum'lar ve sealed sınıflar nasıl kullanılır?

Yapacaklarınız

  • Özelliklere sahip bir sınıf oluşturma
  • Bir sınıf için oluşturucu oluşturma
  • Alt sınıf oluşturma
  • Soyut sınıflar ve arayüzlerle ilgili örnekleri inceleyin
  • Basit bir veri sınıfı oluşturma
  • Singleton'lar, enum'lar ve sealed sınıflar hakkında bilgi

Aşağıdaki programlama terimlerini zaten biliyor olmanız gerekir:

  • Sınıflar, nesnelerin planlarıdır. Örneğin, Aquarium sınıfı, akvaryum nesnesi oluşturmanın planıdır.
  • Nesneler, sınıfların örnekleridir. Bir akvaryum nesnesi, gerçek bir Aquarium'dir.
  • Özellikler, sınıfların özellikleridir. Örneğin, Aquarium uzunluğu, genişliği ve yüksekliği.
  • Yöntemler (üye işlevleri olarak da bilinir), sınıfın işlevselliğidir. Yöntemler, nesneyle "yapabileceğiniz" işlemlerdir. Örneğin, fillWithWater() bir Aquarium nesnesi oluşturabilirsiniz.
  • Arayüz, bir sınıfın uygulayabileceği bir spesifikasyondur. Örneğin, temizlik akvaryum dışındaki nesneler için de yaygın bir işlemdir ve farklı nesneler için genellikle benzer şekilde yapılır. Bu nedenle, clean() yöntemini tanımlayan Clean adlı bir arayüzünüz olabilir. Aquarium sınıfı, akvaryumu yumuşak bir süngerle temizlemek için Clean arayüzünü uygulayabilir.
  • Paketler, ilgili kodları düzenli tutmak veya kod kitaplığı oluşturmak için gruplandırmanın bir yoludur. Bir paket oluşturulduktan sonra, paketin içeriğini başka bir dosyaya aktarabilir ve içindeki kodu ve sınıfları yeniden kullanabilirsiniz.

Bu görevde, bazı özelliklere ve bir yönteme sahip yeni bir paket ve sınıf oluşturacaksınız.

1. adım: Paket oluşturun

Paketler, kodunuzu düzenli tutmanıza yardımcı olabilir.

  1. Proje bölmesinde, Hello Kotlin projesi altında src klasörünü sağ tıklayın.
  2. Yeni > Paket'i seçip paketi example.myapp olarak adlandırın.

2. adım: Özelliklere sahip bir sınıf oluşturun

Sınıflar class anahtar kelimesiyle tanımlanır ve sınıf adları geleneksel olarak büyük harfle başlar.

  1. example.myapp paketini sağ tıklayın.
  2. New > Kotlin File / Class (Yeni > Kotlin Dosyası/Sınıfı) seçeneğini belirleyin.
  3. Tür bölümünde Sınıf'ı seçin ve sınıfa ad verin Aquarium. IntelliJ IDEA, paket adını dosyaya ekler ve sizin için boş bir Aquarium sınıfı oluşturur.
  4. Aquarium sınıfında genişlik, yükseklik ve uzunluk (santimetre cinsinden) için var özelliklerini tanımlayın ve başlatın. Özellikleri varsayılan değerlerle başlatın.
package example.myapp

class Aquarium {
    var width: Int = 20
    var height: Int = 40
    var length: Int = 100
}

Kotlin, arka planda Aquarium sınıfında tanımladığınız özellikler için otomatik olarak alıcılar ve ayarlayıcılar oluşturur. Böylece özelliklere doğrudan erişebilirsiniz (ör. myAquarium.length).

3. adım: main() işlevi oluşturun

main() işlevini barındıracak main.kt adlı yeni bir dosya oluşturun.

  1. Soldaki Project (Proje) bölmesinde example.myapp paketini sağ tıklayın.
  2. New > Kotlin File / Class (Yeni > Kotlin Dosyası/Sınıfı) seçeneğini belirleyin.
  3. Tür açılır listesinde seçimi Dosya olarak bırakın ve dosyayı main.kt olarak adlandırın. IntelliJ IDEA, paket adını içerir ancak dosya için sınıf tanımı içermez.
  4. buildAquarium() işlevini tanımlayın ve içinde Aquarium örneği oluşturun. Bir örnek oluşturmak için sınıfa işlevmiş gibi referans verin: Aquarium(). Bu, sınıfın oluşturucusunu çağırır ve diğer dillerde new kullanmaya benzer şekilde Aquarium sınıfının bir örneğini oluşturur.
  5. main() işlevi tanımlayın ve buildAquarium() işlevini çağırın.
package example.myapp

fun buildAquarium() {
    val myAquarium = Aquarium()
}

fun main() {
    buildAquarium()
}

4. adım: Yöntem ekleme

  1. Aquarium sınıfında, akvaryumun boyut özelliklerini yazdırmak için bir yöntem ekleyin.
    fun printSize() {
        println("Width: $width cm " +
                "Length: $length cm " +
                "Height: $height cm ")
    }
  1. main.kt içinde, buildAquarium() içinde myAquarium üzerinde printSize() yöntemini çağırın.
fun buildAquarium() {
    val myAquarium = Aquarium()
    myAquarium.printSize()
}
  1. main() işlevinin yanındaki yeşil üçgeni tıklayarak programınızı çalıştırın. Sonucu inceleyin.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm 
  1. buildAquarium() içinde, yüksekliği 60 olarak ayarlamak ve değiştirilen boyut özelliklerini yazdırmak için kod ekleyin.
fun buildAquarium() {
    val myAquarium = Aquarium()
    myAquarium.printSize()
    myAquarium.height = 60
    myAquarium.printSize()
}
  1. Programınızı çalıştırın ve çıktıyı inceleyin.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm 
Width: 20 cm Length: 100 cm Height: 60 cm 

Bu görevde sınıf için bir oluşturucu oluşturacak ve özelliklerle çalışmaya devam edeceksiniz.

1. adım: Oluşturucu oluşturun

Bu adımda, ilk görevde oluşturduğunuz Aquarium sınıfına bir oluşturucu ekleyeceksiniz. Önceki örnekte, Aquarium öğesinin her örneği aynı boyutlarda oluşturulur. Özellikleri ayarlayarak oluşturulduktan sonra boyutları değiştirebilirsiniz ancak en başından doğru boyutta oluşturmak daha kolay olacaktır.

Bazı programlama dillerinde oluşturucu, sınıf içinde sınıfın adıyla aynı ada sahip bir yöntem oluşturularak tanımlanır. Kotlin'de oluşturucuyu doğrudan sınıf bildiriminde tanımlarsınız. Parametreleri, sınıf bir yöntemmiş gibi parantez içinde belirtirsiniz. Kotlin'deki işlevlerde olduğu gibi, bu parametreler varsayılan değerler içerebilir.

  1. Daha önce oluşturduğunuz Aquarium sınıfında, sınıf tanımını length, width ve height için varsayılan değerlere sahip üç oluşturucu parametresini içerecek şekilde değiştirin ve bunları ilgili özelliklere atayın.
class Aquarium(length: Int = 100, width: Int = 20, height: Int = 40) {
   // Dimensions in cm
   var length: Int = length
   var width: Int = width
   var height: Int = height
...
}
  1. Daha kompakt olan Kotlin yöntemi, var veya val kullanarak özellikleri doğrudan oluşturucuyla tanımlamaktır. Kotlin, alıcıları ve ayarlayıcıları da otomatik olarak oluşturur. Ardından, sınıfın gövdesindeki özellik tanımlarını kaldırabilirsiniz.
class Aquarium(var length: Int = 100, var width: Int = 20, var height: Int = 40) {
...
}
  1. Bu oluşturucuyla bir Aquarium nesnesi oluşturduğunuzda, herhangi bir bağımsız değişken belirtmeyip varsayılan değerleri alabilir, yalnızca bazılarını belirtebilir veya hepsini belirterek tamamen özel boyutlu bir Aquarium oluşturabilirsiniz. buildAquarium() işlevinde, adlandırılmış parametreleri kullanarak Aquarium nesnesi oluşturmanın farklı yollarını deneyin.
fun buildAquarium() {
    val aquarium1 = Aquarium()
    aquarium1.printSize()
    // default height and length
    val aquarium2 = Aquarium(width = 25)
    aquarium2.printSize()
    // default width
    val aquarium3 = Aquarium(height = 35, length = 110)
    aquarium3.printSize()
    // everything custom
    val aquarium4 = Aquarium(width = 25, height = 35, length = 110)
    aquarium4.printSize()
}
  1. Programı çalıştırın ve çıktıyı inceleyin.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm 
Width: 25 cm Length: 100 cm Height: 40 cm 
Width: 20 cm Length: 110 cm Height: 35 cm 
Width: 25 cm Length: 110 cm Height: 35 cm 

Yapıcıyı aşırı yüklemeniz ve bu durumların her biri için farklı bir sürüm (diğer kombinasyonlar için de birkaç tane daha) yazmanız gerekmediğini fark edin. Kotlin, varsayılan değerlerden ve adlandırılmış parametrelerden gerekenleri oluşturur.

2. adım: Başlatma blokları ekleyin

Yukarıdaki örnek oluşturucular yalnızca özellikleri bildirir ve bir ifadenin değerini bunlara atar. Oluşturucunuzun daha fazla başlatma koduna ihtiyacı varsa bu kod, bir veya daha fazla init bloğuna yerleştirilebilir. Bu adımda, Aquarium sınıfına bazı init blokları ekleyeceksiniz.

  1. Aquarium sınıfına, nesnenin başlatıldığını yazdırmak için bir init bloğu ve hacmi litre cinsinden yazdırmak için ikinci bir blok ekleyin.
class Aquarium (var length: Int = 100, var width: Int = 20, var height: Int = 40) {
    init {
        println("aquarium initializing")
    }
    init {
        // 1 liter = 1000 cm^3
        println("Volume: ${width * length * height / 1000} l")
    }
}
  1. Programı çalıştırın ve çıktıyı inceleyin.
aquarium initializing
Volume: 80 l
Width: 20 cm Length: 100 cm Height: 40 cm 
aquarium initializing
Volume: 100 l
Width: 25 cm Length: 100 cm Height: 40 cm 
aquarium initializing
Volume: 77 l
Width: 20 cm Length: 110 cm Height: 35 cm 
aquarium initializing
Volume: 96 l
Width: 25 cm Length: 110 cm Height: 35 cm 

init bloklarının, sınıf tanımında göründükleri sırayla yürütüldüğünü ve oluşturucu çağrıldığında hepsinin yürütüldüğünü unutmayın.

3. adım: İkincil oluşturucular hakkında bilgi edinin

Bu adımda, ikincil oluşturucular hakkında bilgi edinecek ve sınıfınıza bir tane ekleyeceksiniz. Bir veya daha fazla init bloğu içerebilen birincil oluşturucunun yanı sıra, Kotlin sınıfı, oluşturucu aşırı yüklemesine (yani farklı bağımsız değişkenlere sahip oluşturucular) izin vermek için bir veya daha fazla ikincil oluşturucuya da sahip olabilir.

  1. Aquarium sınıfında, constructor anahtar kelimesini kullanarak argüman olarak balık sayısı alan ikincil bir oluşturucu ekleyin. Balık sayısına göre akvaryumun litre cinsinden hesaplanan hacmi için val tank mülkü oluşturun. Balık başına 2 litre (2.000 cm^3) su ve suyun dökülmemesi için biraz daha yer ayırın.
constructor(numberOfFish: Int) : this() {
    // 2,000 cm^3 per fish + extra room so water doesn't spill
    val tank = numberOfFish * 2000 * 1.1
}
  1. İkincil oluşturucu içinde, birincil oluşturucuda ayarlanan uzunluk ve genişliği aynı tutun ve tankın belirtilen hacme ulaşması için gereken yüksekliği hesaplayın.
    // calculate the height needed
    height = (tank / (length * width)).toInt()
  1. buildAquarium() işlevinde, yeni ikincil oluşturucunuzu kullanarak Aquarium oluşturma çağrısı ekleyin. Boyutu ve hacmi yazdırın.
fun buildAquarium() {
    val aquarium6 = Aquarium(numberOfFish = 29)
    aquarium6.printSize()
    println("Volume: ${aquarium6.width * aquarium6.length * aquarium6.height / 1000} l")
}
  1. Programınızı çalıştırın ve çıktıyı inceleyin.
⇒ aquarium initializing
Volume: 80 l
Width: 20 cm Length: 100 cm Height: 31 cm 
Volume: 62 l

Hacmin iki kez yazdırıldığına dikkat edin: Bir kez ikincil oluşturucu yürütülmeden önce birincil oluşturucudaki init bloğu tarafından, bir kez de buildAquarium() içindeki kod tarafından.

constructor anahtar kelimesini birincil oluşturucuya da ekleyebilirsiniz ancak çoğu durumda bu gerekli değildir.

4. adım: Yeni bir mülk alıcı ekleyin

Bu adımda, açık bir özellik alıcı ekliyorsunuz. Kotlin, özellikleri tanımladığınızda getter ve setter'ları otomatik olarak tanımlar ancak bazen bir özelliğin değerinin ayarlanması veya hesaplanması gerekir. Örneğin, yukarıda Aquarium hacmini yazdırdınız. Bir değişken ve getter tanımlayarak birimi özellik olarak kullanılabilir hale getirebilirsiniz. volume hesaplanması gerektiğinden alıcı, hesaplanan değeri döndürmelidir. Bunu tek satırlık bir işlevle yapabilirsiniz.

  1. Aquarium sınıfında, volume adlı bir Int özelliği tanımlayın ve bir sonraki satırda hacmi hesaplayan bir get() yöntemi tanımlayın.
val volume: Int
    get() = width * height * length / 1000  // 1000 cm^3 = 1 l
  1. Sesi yazdıran init bloğunu kaldırın.
  2. Sesi yazdıran buildAquarium() içindeki kodu kaldırın.
  3. printSize() yönteminde, hacmi yazdırmak için bir satır ekleyin.
fun printSize() {
    println("Width: $width cm " +
            "Length: $length cm " +
            "Height: $height cm "
    )
    // 1 l = 1000 cm^3
    println("Volume: $volume l")
}
  1. Programınızı çalıştırın ve çıktıyı inceleyin.
⇒ aquarium initializing
Width: 20 cm Length: 100 cm Height: 31 cm 
Volume: 62 l

Boyutlar ve hacim aynıdır ancak hacim yalnızca nesne hem birincil oluşturucu hem de ikincil oluşturucu tarafından tamamen başlatıldıktan sonra bir kez yazdırılır.

5. adım: Özellik ayarlayıcı ekleyin

Bu adımda, ses düzeyi için yeni bir özellik ayarlayıcı oluşturursunuz.

  1. Aquarium sınıfında, volume öğesini var olarak değiştirin. Böylece, bu öğe birden fazla kez ayarlanabilir.
  2. volume özelliği için bir ayarlayıcı ekleyin. Bunun için, getter'ın altına set() yöntemi ekleyin. Bu yöntem, sağlanan su miktarına göre yüksekliği yeniden hesaplar. Setter parametresinin adı geleneksel olarak value'dır ancak isterseniz bunu değiştirebilirsiniz.
var volume: Int
    get() = width * height * length / 1000
    set(value) {
        height = (value * 1000) / (width * length)
    }
  1. buildAquarium() bölümünde, akvaryumun hacmini 70 litreye ayarlamak için kod ekleyin. Yeni boyutu yazdırın.
fun buildAquarium() {
    val aquarium6 = Aquarium(numberOfFish = 29)
    aquarium6.printSize()
    aquarium6.volume = 70
    aquarium6.printSize()
}
  1. Programınızı tekrar çalıştırın ve değişen yüksekliği ve hacmi gözlemleyin.
⇒ aquarium initialized
Width: 20 cm Length: 100 cm Height: 31 cm 
Volume: 62 l
Width: 20 cm Length: 100 cm Height: 35 cm 
Volume: 70 l

Kodda şu ana kadar public veya private gibi görünürlük değiştiriciler kullanılmadı. Bunun nedeni, Kotlin'de varsayılan olarak her şeyin herkese açık olmasıdır. Bu da sınıflar, yöntemler, özellikler ve üye değişkenleri dahil olmak üzere her şeye her yerden erişilebileceği anlamına gelir.

Kotlin'de sınıflar, nesneler, arayüzler, oluşturucular, işlevler, özellikler ve bunların ayarlayıcıları görünürlük değiştiricilere sahip olabilir:

  • public, sınıf dışında görünür olduğu anlamına gelir. Sınıfın değişkenleri ve yöntemleri de dahil olmak üzere her şey varsayılan olarak herkese açıktır.
  • internal, yalnızca ilgili modülde görünür olacağı anlamına gelir. Modül, birlikte derlenen bir grup Kotlin dosyasıdır (ör. kitaplık veya uygulama).
  • private, yalnızca söz konusu sınıfta (veya işlevlerle çalışıyorsanız kaynak dosyada) görünür olacağı anlamına gelir.
  • protected, private ile aynıdır ancak alt sınıflar tarafından da görülebilir.

Daha fazla bilgi için Kotlin belgelerindeki Görünürlük Değiştiricileri bölümüne bakın.

Üye değişkenleri

Bir sınıf içindeki özellikler veya üye değişkenleri varsayılan olarak public'dır. var ile tanımlarsanız bunlar değiştirilebilir (yani okunabilir ve yazılabilir) olur. val ile tanımlarsanız başlatma işleminden sonra salt okunur hale gelirler.

Kodunuzun okuyabileceği veya yazabileceği ancak dış kodun yalnızca okuyabileceği bir özellik istiyorsanız özelliği ve getter'ını herkese açık bırakabilir, setter'ı ise aşağıda gösterildiği gibi özel olarak bildirebilirsiniz.

var volume: Int
    get() = width * height * length / 1000
    private set(value) {
        height = (value * 1000) / (width * length)
    }

Bu görevde, Kotlin'de alt sınıfların ve kalıtımın nasıl çalıştığını öğreneceksiniz. Bu türler, diğer dillerde gördüklerinize benzer ancak bazı farklılıklar vardır.

Kotlin'de sınıflar varsayılan olarak alt sınıflara ayrılamaz. Benzer şekilde, özellikler ve üye değişkenleri alt sınıflar tarafından geçersiz kılınamaz (ancak erişilebilir).

Bir sınıfın alt sınıflara ayrılmasına izin vermek için bu sınıfı open olarak işaretlemeniz gerekir. Benzer şekilde, alt sınıfta geçersiz kılmak için özellikleri ve üye değişkenlerini open olarak işaretlemeniz gerekir. Sınıfın arayüzünün bir parçası olarak uygulama ayrıntılarının yanlışlıkla sızdırılmasını önlemek için open anahtar kelimesi gereklidir.

1. adım: Akvaryum sınıfını açık hale getirin

Bu adımda, bir sonraki adımda geçersiz kılabilmek için Aquarium sınıfını open yaparsınız.

  1. Aquarium sınıfını ve tüm özelliklerini open anahtar kelimesiyle işaretleyin.
open class Aquarium (open var length: Int = 100, open var width: Int = 20, open var height: Int = 40) {
    open var volume: Int
        get() = width * height * length / 1000
        set(value) {
            height = (value * 1000) / (width * length)
        }
  1. "rectangle" değeriyle açık bir shape özelliği ekleyin.
   open val shape = "rectangle"
  1. Aquarium hacminin% 90'ını döndüren bir alıcıya sahip açık bir water özelliği ekleyin.
    open var water: Double = 0.0
        get() = volume * 0.9
  1. Şekli ve su miktarını hacmin yüzdesi olarak yazdırmak için printSize() yöntemine kod ekleyin.
fun printSize() {
    println(shape)
    println("Width: $width cm " +
            "Length: $length cm " +
            "Height: $height cm ")
    // 1 l = 1000 cm^3
    println("Volume: $volume l Water: $water l (${water/volume*100.0}% full)")
}
  1. buildAquarium() içinde kodu değiştirerek width = 25, length = 25 ve height = 40 ile Aquarium oluşturun.
fun buildAquarium() {
    val aquarium6 = Aquarium(length = 25, width = 25, height = 40)
    aquarium6.printSize()
}
  1. Programınızı çalıştırın ve yeni çıktıyı inceleyin.
⇒ aquarium initializing
rectangle
Width: 25 cm Length: 25 cm Height: 40 cm 
Volume: 25 l Water: 22.5 l (90.0% full)

2. adım: Alt sınıf oluşturun

  1. Aquarium sınıfının TowerTank adlı bir alt sınıfını oluşturun. Bu sınıf, dikdörtgen tank yerine yuvarlak silindir tankı uygular. TowerTank sınıfıyla aynı dosyaya başka bir sınıf ekleyebileceğiniz için Aquarium sınıfının altına TowerTank sınıfını ekleyebilirsiniz.Aquarium
  2. TowerTank içinde, oluşturucuda tanımlanan height özelliğini geçersiz kılın. Bir özelliği geçersiz kılmak için alt sınıfta override anahtar kelimesini kullanın.
  1. TowerTank için oluşturucuyu diameter olarak ayarlayın. Aquarium üst sınıfında oluşturucuyu çağırırken hem length hem de width için diameter öğesini kullanın.
class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
  1. Silindir hesaplamak için hacim özelliğini geçersiz kılın. Silindir formülü, pi sayısı çarpı yarıçapın karesi çarpı yükseklik şeklindedir. Sabit PI değerini java.lang.Math hizmetinden içe aktarmanız gerekir.
    override var volume: Int
    // ellipse area = π * r1 * r2
    get() = (width/2 * length/2 * height / 1000 * PI).toInt()
    set(value) {
        height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
    }
  1. TowerTank içinde, water özelliğini sesin% 80'i olacak şekilde geçersiz kılın.
override var water = volume * 0.8
  1. shape değerini "cylinder" olarak geçersiz kılın.
override val shape = "cylinder"
  1. Son TowerTank sınıfınız aşağıdaki koda benzer şekilde görünmelidir.

Aquarium.kt:

package example.myapp

import java.lang.Math.PI

... // existing Aquarium class

class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
    override var volume: Int
    // ellipse area = π * r1 * r2
    get() = (width/2 * length/2 * height / 1000 * PI).toInt()
    set(value) {
        height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
    }

    override var water = volume * 0.8
    override val shape = "cylinder"
}
  1. buildAquarium() içinde, çapı 25 cm ve yüksekliği 45 cm olan bir TowerTank oluştur. Boyutu yazdırın.

main.kt:

package example.myapp

fun buildAquarium() {
    val myAquarium = Aquarium(width = 25, length = 25, height = 40)
    myAquarium.printSize()
    val myTower = TowerTank(diameter = 25, height = 40)
    myTower.printSize()
}
  1. Programınızı çalıştırın ve çıktıyı inceleyin.
⇒ aquarium initializing
rectangle
Width: 25 cm Length: 25 cm Height: 40 cm 
Volume: 25 l Water: 22.5 l (90.0% full)
aquarium initializing
cylinder
Width: 25 cm Length: 25 cm Height: 40 cm 
Volume: 18 l Water: 14.4 l (80.0% full)

Bazen, bazı ilgili sınıflar arasında paylaşılacak ortak davranış veya özellikler tanımlamak isteyebilirsiniz. Kotlin, bunu yapmanın iki yolunu sunar: arayüzler ve soyut sınıflar. Bu görevde, tüm balıklar için ortak olan özellikler için soyut bir AquariumFish sınıfı oluşturacaksınız. Tüm balıklar için ortak olan davranışı tanımlamak üzere FishAction adlı bir arayüz oluşturursunuz.

  • Ne soyut bir sınıf ne de bir arayüz kendi başına örneklendirilebilir. Bu nedenle, bu türlerin nesnelerini doğrudan oluşturamazsınız.
  • Soyut sınıfların oluşturucuları vardır.
  • Arayüzler, oluşturucu mantığına sahip olamaz veya herhangi bir durumu depolayamaz.

1. Adım: Soyut sınıf oluşturma

  1. example.myapp altında yeni bir dosya (AquariumFish.kt) oluşturun.
  2. AquariumFish olarak da adlandırılan bir sınıf oluşturun ve abstract ile işaretleyin.
  3. Bir String özelliği, color ekleyin ve abstract ile işaretleyin.
package example.myapp

abstract class AquariumFish {
    abstract val color: String
}
  1. AquariumFish, Shark ve Plecostomus sınıflarının iki alt sınıfını oluşturun.
  2. color soyut olduğundan alt sınıfların bunu uygulaması gerekir. Shark simgesini gri, Plecostomus simgesini altın rengi yapın.
class Shark: AquariumFish() {
    override val color = "gray"
}

class Plecostomus: AquariumFish() {
    override val color = "gold"
}
  1. main.kt dosyasında, sınıflarınızı test etmek için bir makeFish() işlevi oluşturun. Shark ve Plecostomus öğelerini oluşturun, ardından her birinin rengini yazdırın.
  2. main() bölümündeki önceki test kodunuzu silin ve makeFish() için bir çağrı ekleyin. Kodunuz aşağıdaki koda benzer olmalıdır.

main.kt:

package example.myapp

fun makeFish() {
    val shark = Shark()
    val pleco = Plecostomus()

    println("Shark: ${shark.color}")
    println("Plecostomus: ${pleco.color}")
}

fun main () {
    makeFish()
}
  1. Programınızı çalıştırın ve çıktıyı inceleyin.
⇒ Shark: gray 
Plecostomus: gold

Aşağıdaki şema, soyut sınıf AquariumFish'ın alt sınıfları olan Shark sınıfını ve Plecostomus sınıfını temsil etmektedir.

AkvaryumBalığı adlı soyut sınıfı ve Köpek Balığı ile Plekostomus adlı iki alt sınıfı gösteren bir diyagram.

2. adım: Arayüz oluşturma

  1. AquariumFish.kt dosyasında eat() adlı bir yöntemi olan FishAction adlı bir arayüz oluşturun.
interface FishAction  {
    fun eat()
}
  1. Alt sınıfların her birine FishAction ekleyin ve balığın ne yaptığını yazdırarak eat()'ı uygulayın.
class Shark: AquariumFish(), FishAction {
    override val color = "gray"
    override fun eat() {
        println("hunt and eat fish")
    }
}

class Plecostomus: AquariumFish(), FishAction {
    override val color = "gold"
    override fun eat() {
        println("eat algae")
    }
}
  1. makeFish() işlevinde, eat() işlevini çağırarak oluşturduğunuz her balığın bir şeyler yemesini sağlayın.
fun makeFish() {
    val shark = Shark()
    val pleco = Plecostomus()
    println("Shark: ${shark.color}")
    shark.eat()
    println("Plecostomus: ${pleco.color}")
    pleco.eat()
}
  1. Programınızı çalıştırın ve çıktıyı inceleyin.
⇒ Shark: gray
hunt and eat fish
Plecostomus: gold
eat algae

Aşağıdaki şemada, her ikisi de FishAction arayüzünü içeren ve uygulayan Shark sınıfı ile Plecostomus sınıfı gösterilmektedir.

Soyut sınıflar ve arayüzler ne zaman kullanılır?

Yukarıdaki örnekler basittir ancak çok sayıda ilişkili sınıfınız olduğunda soyut sınıflar ve arayüzler, tasarımınızı daha temiz, daha düzenli ve bakımı daha kolay hale getirmenize yardımcı olabilir.

Yukarıda belirtildiği gibi, soyut sınıfların oluşturucuları olabilir ancak arayüzlerin oluşturucuları olamaz. Bunun dışında, soyut sınıflar ve arayüzler birbirine çok benzer. Peki, her birini ne zaman kullanmalısınız?

Bir sınıfı oluşturmak için arayüzleri kullandığınızda, sınıfın işlevselliği içerdiği sınıf örnekleri aracılığıyla genişletilir. Kompozisyon, soyut bir sınıftan devralmaya kıyasla kodun yeniden kullanılmasını ve hakkında akıl yürütülmesini kolaylaştırır. Ayrıca, bir sınıfta birden fazla arayüz kullanabilirsiniz ancak yalnızca bir soyut sınıftan alt sınıf oluşturabilirsiniz.

Kompozisyon genellikle daha iyi kapsülleme, daha düşük bağlantı (karşılıklı bağımlılık), daha temiz arayüzler ve daha kullanılabilir kod sağlar. Bu nedenlerden dolayı, arayüzlerle birlikte kompozisyon kullanmak tercih edilen tasarımdır. Öte yandan, soyut bir sınıftan devralma bazı sorunlar için doğal bir çözüm olabilir. Bu nedenle, kompozisyonu tercih etmeniz gerekir. Ancak kalıtımın mantıklı olduğu durumlarda Kotlin bunu yapmanıza da olanak tanır.

  • Çok sayıda yönteminiz ve bir veya iki varsayılan uygulamanız varsa (örneğin, aşağıdaki AquariumAction örneğinde olduğu gibi) arayüz kullanın.
interface AquariumAction {
    fun eat()
    fun jump()
    fun clean()
    fun catchFish()
    fun swim()  {
        println("swim")
    }
}
  • Bir sınıfı tamamlayamadığınız her durumda soyut sınıf kullanın. Örneğin, AquariumFish sınıfına geri dönersek AquariumFish sınıfının FishAction sınıfını uygulamasını sağlayabilir ve eat için varsayılan bir uygulama sağlayabilirsiniz. color sınıfı ise soyut olarak kalır. Bunun nedeni, balıklar için varsayılan bir renk olmamasıdır.
interface FishAction  {
    fun eat()
}

abstract class AquariumFish: FishAction {
   abstract val color: String
   override fun eat() = println("yum")
}

Önceki görevde soyut sınıflar, arayüzler ve kompozisyon kavramı tanıtılmıştı. Arayüz temsilciliği, bir arayüzün yöntemlerinin yardımcı (veya temsilci) bir nesne tarafından uygulandığı ve ardından bir sınıf tarafından kullanıldığı gelişmiş bir tekniktir. Bu teknik, bir arayüzü birbiriyle ilişkisiz bir dizi sınıfta kullandığınızda yararlı olabilir: Gerekli arayüz işlevini ayrı bir yardımcı sınıfa eklersiniz ve sınıfların her biri, işlevi uygulamak için yardımcı sınıfın bir örneğini kullanır.

Bu görevde, bir sınıfa işlevsellik eklemek için arayüz temsilini kullanırsınız.

1. adım: Yeni bir arayüz oluşturun

  1. AquariumFish.kt dosyasında AquariumFish sınıfını kaldırın. AquariumFish sınıfından devralmak yerine Plecostomus ve Shark, hem balık işlemi hem de renkleri için arayüzleri uygulayacak.
  2. Rengi dize olarak tanımlayan yeni bir arayüz (FishColor) oluşturun.
interface FishColor {
    val color: String
}
  1. İki arayüz (FishAction) ve bir FishColor uygulamak için Plecostomus öğesini değiştirin. color değerini FishColor, eat() değerini ise FishAction ile geçersiz kılmanız gerekir.
class Plecostomus: FishAction, FishColor {
    override val color = "gold"
    override fun eat() {
        println("eat algae")
    }
}
  1. Shark sınıfınızı, AquariumFish sınıfından devralmak yerine FishAction ve FishColor olmak üzere iki arayüzü de uygulayacak şekilde değiştirin.
class Shark: FishAction, FishColor {
    override val color = "gray"
    override fun eat() {
        println("hunt and eat fish")
    }
}
  1. Tamamlanmış kodunuz aşağıdaki gibi görünmelidir:
package example.myapp

interface FishAction {
    fun eat()
}

interface FishColor {
    val color: String
}

class Plecostomus: FishAction, FishColor {
    override val color = "gold"
    override fun eat() {
        println("eat algae")
    }
}

class Shark: FishAction, FishColor {
    override val color = "gray"
    override fun eat() {
        println("hunt and eat fish")
    }
}

2. adım: Tekil sınıf oluşturun

Ardından, FishColor uygulayan bir yardımcı sınıf oluşturarak temsilci atama bölümünün kurulumunu gerçekleştirirsiniz. GoldColor adlı temel bir sınıf oluşturursunuz. Bu sınıf, FishColor'ı uygular ve tek yaptığı şey renginin altın olduğunu söylemektir.

GoldColor öğesinin birden fazla örneğini oluşturmak mantıklı değildir. Çünkü hepsi tam olarak aynı şeyi yapar. Bu nedenle Kotlin, class yerine object anahtar kelimesini kullanarak yalnızca bir örneğini oluşturabileceğiniz bir sınıf tanımlamanıza olanak tanır. Kotlin bu tek örneği oluşturur ve bu örneğe sınıf adı ile referans verilir. Daha sonra diğer tüm nesneler bu tek örneği kullanabilir. Bu sınıfın başka örneklerini oluşturmanın bir yolu yoktur. Singleton kalıbını biliyorsanız Kotlin'de singleton'ları bu şekilde uygulayabilirsiniz.

  1. AquariumFish.kt dosyasında GoldColor için bir nesne oluşturun. Rengi geçersiz kılın.
object GoldColor : FishColor {
   override val color = "gold"
}

3. adım: FishColor için arayüz temsilcisi ekleyin

Artık arayüz yetkisini kullanmaya hazırsınız.

  1. AquariumFish.kt dosyasında, color öğesinin Plecostomus öğesinden geçersiz kılınmasını kaldırın.
  2. Plecostomus sınıfını, rengini GoldColor sınıfından alacak şekilde değiştirin. Bunun için sınıf bildirimine by GoldColor ekleyerek yetki devrini oluşturursunuz. Bu, FishColor yerine GoldColor tarafından sağlanan uygulamanın kullanılmasını önerir. Bu nedenle, color öğesine her erişildiğinde GoldColor öğesine temsilci olarak erişilir.
class Plecostomus:  FishAction, FishColor by GoldColor {
   override fun eat() {
       println("eat algae")
   }
}

Bu sınıfta tüm Pleco'lar altın renginde gösteriliyor ancak bu balıklar aslında birçok renkte olabilir. Bunu, GoldColor için varsayılan renk olarak Plecostomus ile rengin oluşturucu parametresini ekleyerek çözebilirsiniz.

  1. Plecostomus sınıfını, oluşturucusuyla birlikte fishColor olarak geçirilen bir sınıfı alacak şekilde değiştirin ve varsayılan değerini GoldColor olarak ayarlayın. Temsilciyi by GoldColor yerine by fishColor olarak değiştirin.
class Plecostomus(fishColor: FishColor = GoldColor):  FishAction,
       FishColor by fishColor {
   override fun eat() {
       println("eat algae")
   }
}

4. adım: FishAction için arayüz temsilcisi ekleyin

Aynı şekilde, FishAction için arayüz yetkilendirmesini kullanabilirsiniz.

  1. AquariumFish.kt dosyasında FishAction'ü uygulayan bir PrintingFishAction sınıfı oluşturun. Bu sınıf, String ve food parametrelerini alır ve balığın ne yediğini yazdırır.
class PrintingFishAction(val food: String) : FishAction {
    override fun eat() {
        println(food)
    }
}
  1. Plecostomus sınıfında, yetkilendirme ile değiştireceğiniz için geçersiz kılma işlevini eat() kaldırın.
  2. Plecostomus beyanında, FishAction öğesini PrintingFishAction öğesine "eat algae" ileterek temsilci olarak atayın.
  3. Tüm bu temsil işlemleri nedeniyle Plecostomus sınıfının gövdesinde kod yok. Bu nedenle, tüm geçersiz kılmalar arayüz temsilcisi tarafından işlendiğinden {} öğesini kaldırın.
class Plecostomus (fishColor: FishColor = GoldColor):
        FishAction by PrintingFishAction("eat algae"),
        FishColor by fishColor

Aşağıdaki şema, Shark ve Plecostomus sınıflarını temsil etmektedir. Her ikisi de PrintingFishAction ve FishColor arayüzlerinden oluşur ancak uygulamayı onlara devreder.

Arayüz temsilciliği güçlü bir özelliktir ve genellikle başka bir dilde soyut sınıf kullanabileceğiniz her durumda nasıl kullanacağınızı düşünmelisiniz. Bu sayede, her biri farklı bir şekilde uzmanlaşmış çok sayıda alt sınıf oluşturmak yerine davranışları eklemek için kompozisyonu kullanabilirsiniz.

Veri sınıfı, diğer bazı dillerdeki struct yapısına benzer. Temel olarak bazı verileri tutmak için kullanılır ancak veri sınıfı nesnesi yine de bir nesnedir. Kotlin veri sınıfı nesneleri, yazdırma ve kopyalama gibi yardımcı programlar gibi bazı ek avantajlara sahiptir. Bu görevde basit bir veri sınıfı oluşturacak ve Kotlin'in veri sınıfları için sağladığı destek hakkında bilgi edineceksiniz.

1. adım: Veri sınıfı oluşturun

  1. Yeni kodu tutmak için example.myapp paketi altına yeni bir paket decor ekleyin. Proje bölmesinde example.myapp'i sağ tıklayın ve Dosya > Yeni > Paket'i seçin.
  2. Pakette Decoration adlı yeni bir sınıf oluşturun.
package example.myapp.decor

class Decoration {
}
  1. Decoration öğesini bir veri sınıfı yapmak için sınıf bildiriminin başına data anahtar kelimesini ekleyin.
  2. Sınıfa veri vermek için rocks adlı bir String özelliği ekleyin.
data class Decoration(val rocks: String) {
}
  1. Dosyada, sınıfın dışında, makeDecorations() işlevini kullanarak "granite" ile Decoration örneği oluşturup yazdırın.
fun makeDecorations() {
    val decoration1 = Decoration("granite")
    println(decoration1)
}
  1. main() işlevini ekleyerek makeDecorations()'u çağırın ve programınızı çalıştırın. Bunun bir veri sınıfı olması nedeniyle oluşturulan anlamlı çıkışa dikkat edin.
⇒ Decoration(rocks=granite)
  1. makeDecorations() içinde, her ikisi de "slate" olan iki Decoration nesnesi daha oluşturun ve bunları yazdırın.
fun makeDecorations() {
    val decoration1 = Decoration("granite")
    println(decoration1)

    val decoration2 = Decoration("slate")
    println(decoration2)

    val decoration3 = Decoration("slate")
    println(decoration3)
}
  1. makeDecorations() içinde, decoration1 ile decoration2 karşılaştırmasının sonucunu yazdıran bir yazdırma ifadesi ve decoration3 ile decoration2 karşılaştırmasını yapan ikinci bir ifade ekleyin. Veri sınıfları tarafından sağlanan equals() yöntemini kullanın.
    println (decoration1.equals(decoration2))
    println (decoration3.equals(decoration2))
  1. Kodunuzu çalıştırın.
⇒ Decoration(rocks=granite)
Decoration(rocks=slate)
Decoration(rocks=slate)
false
true

2. adım: Destructuring kullanma

Bir veri nesnesinin özelliklerine erişmek ve bunları değişkenlere atamak için özellikleri tek tek atayabilirsiniz.

val rock = decoration.rock
val wood = decoration.wood
val diver = decoration.diver

Bunun yerine, her mülk için bir değişken oluşturabilir ve veri nesnesini değişken grubuna atayabilirsiniz. Kotlin, özellik değerini her değişkene yerleştirir.

val (rock, wood, diver) = decoration

Bu işleme destructuring adı verilir ve kullanışlı bir kısaltmadır. Değişken sayısı, özellik sayısıyla eşleşmelidir ve değişkenler sınıfta bildirildikleri sırayla atanır. Decoration.kt içinde deneyebileceğiniz eksiksiz bir örneği burada bulabilirsiniz.

// Here is a data class with 3 properties.
data class Decoration2(val rocks: String, val wood: String, val diver: String){
}

fun makeDecorations() {
    val d5 = Decoration2("crystal", "wood", "diver")
    println(d5)

// Assign all properties to variables.
    val (rock, wood, diver) = d5
    println(rock)
    println(wood)
    println(diver)
}
⇒ Decoration2(rocks=crystal, wood=wood, diver=diver)
crystal
wood
diver

Özelliklerden bir veya daha fazlasına ihtiyacınız yoksa aşağıdaki kodda gösterildiği gibi değişken adı yerine _ kullanarak bunları atlayabilirsiniz.

    val (rock, _, diver) = d5

Bu görevde, Kotlin'deki bazı özel amaçlı sınıflar hakkında bilgi edineceksiniz. Bu sınıflar arasında şunlar yer alır:

  • Singleton sınıfları
  • Sıralamalar
  • Sealed sınıflar

1. adım: Tekil sınıfları geri çağırın

GoldColor sınıfıyla ilgili önceki örneği hatırlayın.

object GoldColor : FishColor {
   override val color = "gold"
}

GoldColor öğesinin her örneği aynı şeyi yaptığından, tekil olmasını sağlamak için class yerine object olarak tanımlanır. Yalnızca bir örneği olabilir.

2. adım: Enum oluşturun

Kotlin, diğer dillerde olduğu gibi bir şeyi numaralandırmanıza ve adına göre referans vermenize olanak tanıyan numaralandırılmış türleri de destekler. Bildirimi enum anahtar kelimesiyle önekleyerek bir enum bildirin. Temel bir enum bildirimi için yalnızca bir ad listesi gerekir ancak her adla ilişkili bir veya daha fazla alan da tanımlayabilirsiniz.

  1. Decoration.kt dosyasında bir enum örneğini deneyin.
enum class Color(val rgb: Int) {
   RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF);
}

Numaralandırmalar, tekil nesnelere benzer. Yalnızca bir tane olabilir ve numaralandırmadaki her değerden yalnızca bir tane olabilir. Örneğin, yalnızca bir Color.RED, bir Color.GREEN ve bir Color.BLUE olabilir. Bu örnekte, renk bileşenlerini temsil etmek için RGB değerleri rgb özelliğine atanır. Ayrıca, ordinal özelliğini kullanarak bir enum'ın sıra değerini, name özelliğini kullanarak da adını alabilirsiniz.

  1. Başka bir enum örneğini deneyin.
enum class Direction(val degrees: Int) {
    NORTH(0), SOUTH(180), EAST(90), WEST(270)
}

fun main() {
    println(Direction.EAST.name)
    println(Direction.EAST.ordinal)
    println(Direction.EAST.degrees)
}
⇒ EAST
2
90

3. adım: Sealed sınıf oluşturun

Sealed class, alt sınıf oluşturulabilen ancak yalnızca bildirildiği dosyanın içinde alt sınıf oluşturulabilen bir sınıftır. Sınıfı farklı bir dosyada alt sınıfa ayırmaya çalışırsanız hata alırsınız.

Sınıflar ve alt sınıflar aynı dosyada olduğundan Kotlin, tüm alt sınıfları statik olarak bilir. Yani derleme sırasında derleyici tüm sınıfları ve alt sınıfları görür ve bunların tamamı olduğunu bilir. Bu nedenle, derleyici sizin için ek kontroller yapabilir.

  1. AquariumFish.kt dosyasında, su temasına uygun olarak sealed class örneğini deneyin.
sealed class Seal
class SeaLion : Seal()
class Walrus : Seal()

fun matchSeal(seal: Seal): String {
   return when(seal) {
       is Walrus -> "walrus"
       is SeaLion -> "sea lion"
   }
}

Seal sınıfı başka bir dosyada alt sınıfa ayrılamaz. Daha fazla Seal türü eklemek istiyorsanız bunları aynı dosyaya eklemeniz gerekir. Bu nedenle, kapalı sınıflar sabit sayıda türü temsil etmenin güvenli bir yoludur. Örneğin, kapalı sınıflar bir ağ API'sinden başarı veya hata döndürmek için idealdir.

Bu derste pek çok konuyu ele aldık. Kotlin, nesne yönelimli diğer programlama dillerine benzer olsa da kodu kısa ve okunabilir tutmak için bazı özellikler ekler.

Sınıflar ve oluşturucular

  • class kullanarak Kotlin'de bir sınıf tanımlayın.
  • Kotlin, özellikler için otomatik olarak ayarlayıcılar ve alıcılar oluşturur.
  • Birincil oluşturucuyu doğrudan sınıf tanımında tanımlayın. Örneğin:
    class Aquarium(var length: Int = 100, var width: Int = 20, var height: Int = 40)
  • Birincil oluşturucunun ek koda ihtiyacı varsa bu kodu bir veya daha fazla init bloğuna yazın.
  • Bir sınıf, constructor kullanarak bir veya daha fazla ikincil oluşturucu tanımlayabilir ancak Kotlin stilinde bunun yerine bir fabrika işlevi kullanılır.

Görünürlük değiştiricileri ve alt sınıflar

  • Kotlin'deki tüm sınıflar ve işlevler varsayılan olarak public'dır ancak değiştiricileri kullanarak görünürlüğü internal, private veya protected olarak değiştirebilirsiniz.
  • Alt sınıf oluşturmak için üst sınıf open olarak işaretlenmelidir.
  • Bir alt sınıftaki yöntemleri ve özellikleri geçersiz kılmak için yöntemlerin ve özelliklerin üst sınıfta open olarak işaretlenmesi gerekir.
  • Sealed sınıflar yalnızca tanımlandıkları dosyada alt sınıflara ayrılabilir. Bildirimin önüne sealed ekleyerek kapalı bir sınıf oluşturun.

Veri sınıfları, tekil nesneler ve numaralandırmalar

  • Bildirimin önüne data ekleyerek bir veri sınıfı oluşturun.
  • Destructuring, bir data nesnesinin özelliklerini ayrı değişkenlere atamak için kullanılan bir kısaltmadır.
  • class yerine object kullanarak tekil bir sınıf oluşturun.
  • enum class kullanarak bir enum tanımlayın.

Soyut sınıflar, arayüzler ve temsil

  • Soyut sınıflar ve arayüzler, sınıflar arasında ortak davranışları paylaşmanın iki yoludur.
  • Soyut sınıf, özellikleri ve davranışı tanımlar ancak uygulamayı alt sınıflara bırakır.
  • Arayüz, davranışı tanımlar ve davranışın bir kısmı veya tamamı için varsayılan uygulamalar sağlayabilir.
  • Bir sınıfı oluşturmak için arayüzleri kullandığınızda, sınıfın işlevselliği içerdiği sınıf örnekleri aracılığıyla genişletilir.
  • Arayüz yetkilendirmesi, kompozisyonu kullanır ancak uygulamayı arayüz sınıflarına da yetkilendirir.
  • Kompozisyon, arayüz delegasyonu kullanarak bir sınıfa işlevsellik eklemenin etkili bir yoludur. Genel olarak kompozisyon tercih edilir ancak bazı sorunlar için soyut sınıftan devralma daha uygundur.

Kotlin belgeleri

Bu kurstaki herhangi bir konu hakkında daha fazla bilgi edinmek veya takıldığınız noktaları aşmak için https://kotlinlang.org adresini ziyaret edebilirsiniz.

Kotlin eğitimleri

https://try.kotlinlang.org web sitesinde Kotlin Koans adlı zengin eğitimler, web tabanlı bir yorumlayıcı ve örneklerle birlikte eksiksiz bir referans dokümanı seti yer alır.

Udacity kursu

Bu konuyla ilgili Udacity kursunu görüntülemek için Kotlin Bootcamp for Programmers'a (Programcılar için Kotlin Temel Eğitimi) göz atın.

IntelliJ IDEA

IntelliJ IDEA ile ilgili dokümanları JetBrains web sitesinde bulabilirsiniz.

Bu bölümde, bir eğitmenin yönettiği kurs kapsamında bu codelab'i tamamlayan öğrenciler için olası ödevler listelenmektedir. Eğitmen, aşağıdakileri yapmalıdır:

  • Gerekirse ödev atayın.
  • Öğrencilere ev ödevi ödevlerini nasıl göndereceklerini bildirin.
  • Ödevlere not verin.

Eğitmenler bu önerileri istedikleri kadar kullanabilir ve uygun olduğunu düşündükleri diğer ödevleri verebilirler.

Bu codelab'i kendi başınıza tamamlıyorsanız bilginizi test etmek için bu ödevleri kullanabilirsiniz.

Bu soruları yanıtlayın

1. Soru

Sınıflar, o sınıfın nesnelerini oluşturmak için plan görevi gören özel bir yönteme sahiptir. Bu yöntemin adı nedir?

▢ İnşaatçı

▢ Bir örnekleyici

▢ Oluşturucu

▢ Bir plan

2. Soru

Arayüzler ve soyut sınıflarla ilgili aşağıdaki ifadelerden hangisi doğru DEĞİLDİR?

▢ Soyut sınıflar oluşturuculara sahip olabilir.

▢ Arayüzler oluşturucuya sahip olamaz.

▢ Arayüzler ve soyut sınıflar doğrudan örneklenebilir.

▢ Soyut özellikler, soyut sınıfın alt sınıfları tarafından uygulanmalıdır.

3. Soru

Aşağıdakilerden hangisi özellikler, yöntemler vb. için Kotlin görünürlük değiştiricisi DEĞİLDİR?

internal

nosubclass

protected

private

4. Soru

Şu veri sınıfını göz önünde bulundurun:
data class Fish(val name: String, val species:String, val colors:String)
Aşağıdakilerden hangisi, Fish nesnesi oluşturmak ve yapılandırmasını bozmak için geçerli bir kod DEĞİLDİR?

val (name1, species1, colors1) = Fish("Pat", "Plecostomus", "gold")

val (name2, _, colors2) = Fish("Bitey", "shark", "gray")

val (name3, species3, _) = Fish("Amy", "angelfish", "blue and black stripes")

val (name4, species4, colors4) = Fish("Harry", "halibut")

5. Soru

Bakılması gereken birçok hayvanın bulunduğu bir hayvanat bahçeniz olduğunu varsayalım. Aşağıdakilerden hangisi bakıcılık hizmetinin uygulanması kapsamında DEĞİLDİR?

▢ Hayvanların yediği farklı türde yiyecekler için interface.

▢ Farklı bakıcı türleri oluşturabileceğiniz bir abstract Caretaker sınıfı.

▢ Hayvana temiz su verme interface

▢ Beslenme programındaki bir giriş için data sınıfı.

Sonraki derse geçin: 5.1 Uzantılar

Diğer codelab'lerin bağlantıları da dahil olmak üzere kursa genel bir bakış için "Kotlin Bootcamp for Programmers: Welcome to the course." başlıklı makaleyi inceleyin.