Soru tarihi:
Yöntemlerin yeniden tanımlanması OOP'nin temeli, ancak Java'da başlangıçta override zorunlu değildi. Kotlin, kodun belirginliğini artırmak ve miras alırken rastgele hatalardan kaçınmak için override kullanımını zorunlu kılan katı bir türdedir.
Sorun:
Açıkça override belirtmeden, bir arayüzü/kelas tanımlarken yanlış isim, tür veya gösterici ile hata yapmak kolaydır. Program çökmez, ama beklenen yeniden tanımlama gerçekleşmez. Kotlin bu konuyu köklü bir şekilde çözmektedir.
Çözüm:
Kotlin'de, bir yöntem yeniden tanımlanabilir olması için open (veya abstract/aralık) olarak ilan edilmelidir. Yeniden tanımlama için override yazmak zorunludur. Eğer imzalar uyuşmazsa — derleme hatasıdır. Bu, Java'nın çoğu klasik hatalarını önler.
Kod örneği:
open class Base { open fun greet() { println("Hello!") } } class Child : Base() { override fun greet() { println("Hi!") } }
Anahtar özellikler:
Override'ı unuttuğunuzda bir fonksiyonu yanlışlıkla yeniden tanımlayabilir misiniz?
Hayır. Eğer override atladıysanız, ilan edilen yöntem, sınıfın yeni bir yöntemi olarak kabul edilir ve hiçbir yeniden tanımlama gerçekleşmez — eğer open temel yöntemde mevcutsa, derleyici hata verir.
Kod örneği:
open class A { open fun test() {} } class B : A() { fun test() {} // yeniden tanımlama değil! test2() ile aynı }
Kendi yöntemleri ebeveynin görünürlüğünden daha katı bir görünürlükle sahip olabilir mi?
Hayır. Yeniden tanımlanan yöntemin görünürlük alanını daraltmak yasaktır. Örneğin, eğer temel yöntem public ise, override tanımı private/protected/internal olamaz. Derleyici hata verir.
Override bileşeni final olabilir mi?
Evet! Daha fazla yeniden tanımlama istemiyorsanız final ekleyin:
class D : Base() { final override fun greet() { //... } }
Java'da:
public class Parent {void foo(){} } public class Child extends Parent {void foo(int x){} }
Yeniden tanımlama bekleniyor, ancak gerçekte — aşırı yükleme. Çağrılar yanlış yönteme gidiyor.
Artılar:
Eksiler:
Kotlin'de:
open class Parent { open fun foo() {} } class Child : Parent() { override fun foo() { /*...*/ } }
Artılar:
Eksiler: