- Birincil yapıcısı, özellikleri ve metotları olan bir sınıf yazmak
- Veri sınıfının sağladığı
toString,==vecopyolanaklarını kullanmak objectve eşlik eden nesnenin ne işe yaradığını açıklamakopen/overrideile kalıtım kurmak ve bir arayüzü uygulamak
Bir e-okul defteri yazıyorsun: her öğrencinin adı, sınıfı ve notları var; yeni not eklemen ve ortalamayı hesaplaman gerekiyor. 30 öğrenci için ayrı ayrı değişkenler kısa sürede karmaşaya dönüşür. Nesne yönelimli programlama başka bir yol sunar: verileri ve onlarla çalışan fonksiyonları tek bir yerde, yani bir nesnede birleştirmek. Kotlin bunu çok kısa bir yazımla yapar.
Sınıf, yapıcı ve özellikler
Sınıf nesnelerin planıdır, nesne ise bu plana göre oluşturulmuş somut bir örnektir. Kotlin'de birincil yapıcı (primary constructor), sınıf adından hemen sonra parantez içinde yazılır: orada val ya da var ile tanımlanan parametreler doğrudan sınıfın özellikleri olur. Sınıfın içindeki fonksiyonlara metot denir. Nesne new sözcüğü olmadan, bir fonksiyon çağrısı gibi oluşturulur: Student("Aysel", 8).
class Student(val name: String, var grade: Int) {
val scores = mutableListOf<Int>()
fun addScore(score: Int) {
scores.add(score)
}
fun average() = scores.average()
fun introduce() = "I am $name, grade $grade"
}
fun main() {
val aysel = Student("Aysel", 8)
aysel.addScore(5)
aysel.addScore(4)
println(aysel.introduce())
println(aysel.scores)
println(aysel.average())
aysel.grade = 9
println(aysel.introduce())
}I am Aysel, grade 8 [5, 4] 4.5 I am Aysel, grade 9
grade bir var olduğu için değiştirilebilir; name ise val'dır ve değişmez.Veri sınıfları
Sıradan bir sınıfın nesnesini yazdırırsan Student@1b6d3586 gibi anlaşılmaz bir metin görürsün; aynı verilere sahip iki nesne de == ile eşit sayılmaz. Çoğu zaman bir sınıf yalnızca veri tutmak içindir: kullanıcı, ürün, sipariş. Böyle durumlarda sınıfın önüne data yazılır ve Kotlin otomatik olarak okunaklı bir toString, içeriği karşılaştıran bir ==, copy ve bileşenlere ayırma olanağı oluşturur.
data class User(val name: String, val age: Int)
fun main() {
val u1 = User("Aysel", 15)
val u2 = User("Aysel", 15)
println(u1)
println(u1 == u2)
val older = u1.copy(age = 16)
println(older)
val (name, age) = older
println("$name is $age")
}User(name=Aysel, age=15) true User(name=Aysel, age=16) Aysel is 16
object ve eşlik eden nesneler
Bazen programda bir şeyin yalnızca tek bir örneği olmalıdır: uygulama ayarları ya da veritabanı bağlantısı gibi. Bunun için class yerine object yazılır; bu hem sınıfı tanımlar hem de onun tek nesnesini oluşturur. Sınıfın içindeki companion object (eşlik eden nesne) ise nesne oluşturmadan doğrudan sınıf adıyla çağrılan fonksiyonlar ve sabitler içindir; örneğin nesne üreten “fabrika” fonksiyonları.
object Settings {
var language = "az"
fun describe() = "Language: $language"
}
class Temperature(val celsius: Double) {
companion object {
const val WATER_BOILS = 100.0
fun fromFahrenheit(f: Double) = Temperature((f - 32) * 5 / 9)
}
}
fun main() {
println(Settings.describe())
Settings.language = "en"
println(Settings.describe())
val t = Temperature.fromFahrenheit(212.0)
println(t.celsius)
println(t.celsius == Temperature.WATER_BOILS)
}Language: az Language: en 100.0 true
Kalıtım: open ve override
Kalıtım, var olan bir sınıfın üzerine yeni bir sınıf kurmayı sağlar: alt sınıf, üst sınıfın özelliklerini ve metotlarını alır. Kotlin'de sınıflar varsayılan olarak kapalıdır; bir sınıftan türetebilmek için üst sınıfın open ile işaretlenmesi gerekir. Alt sınıfın değiştirebileceği metot da open olmalıdır; alt sınıf onun yeni sürümünü override ile yazar. Üst sınıf iki noktadan sonra belirtilir: class Dog(name: String) : Animal(name).
open class Animal(val name: String) {
open fun sound() = "..."
fun introduce() = "$name says ${sound()}"
}
class Dog(name: String) : Animal(name) {
override fun sound() = "Woof!"
}
class Cat(name: String) : Animal(name) {
override fun sound() = "Meow!"
}
fun main() {
val pets = listOf(Dog("Rex"), Cat("Mestan"), Animal("Nemo"))
for (pet in pets) {
println(pet.introduce())
}
}Rex says Woof! Mestan says Meow! Nemo says ...
introduce(), her nesnede o nesnenin kendi sound() sürümünü çağırır; buna çok biçimlilik (polimorfizm) denir.Arayüzler
Arayüz (interface), sınıfların neler yapabilmesi gerektiğini tanımlayan bir sözleşmedir: özelliklerini ve metotlarını uygulayan her sınıf o arayüzün türüne ait olur. Arayüz bir metodun hazır bir sürümünü de içerebilir. Bir sınıf yalnızca bir sınıftan türeyebilir ama istediği sayıda arayüzü uygulayabilir.
interface Shape {
val name: String
fun area(): Double
fun describe() = "$name: area ${area()}"
}
class Rectangle(val width: Double, val height: Double) : Shape {
override val name = "Rectangle"
override fun area() = width * height
}
class Circle(val radius: Double) : Shape {
override val name = "Circle"
override fun area() = 3.14 * radius * radius
}
fun main() {
val shapes: List<Shape> = listOf(Rectangle(3.0, 4.0), Circle(2.0))
shapes.forEach { println(it.describe()) }
println(shapes.maxBy { it.area() }.name)
}Rectangle: area 12.0 Circle: area 12.56 Circle
kotlin.math.PI'dadır.| Tanım | Ne zaman kullanılır |
|---|---|
class | verisi ve davranışı olan sıradan nesneler |
data class | çoğunlukla veri tutan nesneler |
object | tek bir örneği olan şey |
open class | alt sınıflar için bir temel |
interface | birkaç sınıfın ortak yeteneği (sözleşme) |
Önemli noktalar
class Student(val name: String): birincil yapıcı özelliği doğrudan tanımlar; nesnenewolmadan oluşturulur.data classotomatik olaraktoString, içeriğe göre==,copyve bileşenlere ayırma kazanır.objecttek bir örnek oluşturur;companion objectise sınıf adıyla çağrılan üyeleri tutar.- Sınıflar ve metotlar varsayılan olarak kapalıdır: kalıtım için
open, geçersiz kılmak içinoverridegerekir. - Bir sınıf tek bir üst sınıftan türer ama birden çok arayüzü uygulayabilir.
Kendini test et
10 soru. Her doğru cevap XP kazandırır.
data class Point(val x: Int, val y: Int) için println(Point(1, 2)) ne yazdırır?