Ahmet Balaman LogoAhmet Balaman

Dart'ta Interface ve Implements - Sınıflara Ekstra Özellik Eklemek

personAhmet Balaman
calendar_today
DartInterfaceAbstractOOPFlutter

Interface'ler ve Implements - Soyut Kavramlar

Bugün Dart'ın biraz daha ileri seviye konularına girdim: Abstract class'lar ve implements. Bu konu başta oldukça soyut geldi (zaten abstract soyut demek), ama örnekler üzerinde çalışınca netleşmeye başladı.

Canlı Demo: Abstract Class ve Implements

Abstract class ve implements kullanımlarını interaktif olarak öğrenin:

Abstract Class Nedir?

Abstract class, kendi başına bir nesne oluşturamadığınız ama başka sınıflara şablon sağlayan sınıflardır. Şöyle düşünün: Bir tarif defteri var, ama tarif defterinden yemek yiyemezsiniz. Önce o tarifteki yemeği yapmanız gerekir.

abstract class Squeezable {
  void howToSqueeze() {}
}

abstract class Eatable {
  void howToEat() {}
}

Burada iki abstract class tanımladım. Biri "sıkılabilir şeyler", diğeri "yenilebilir şeyler" için.

Implements ile Sınıflara Özellik Eklemek

Extends'den farklı olarak, implements kullandığınızda birden fazla sınıftan özellik alabilirsiniz. Ben buna "sözleşme imzalamak" diyorum. "Ben bu özellikleri uygulayacağım" diye söz veriyorsunuz.

Elma Örneği

abstract class Squeezable {
  void howToSqueeze() {}
}

abstract class Eatable {
  void howToEat() {}
}

class Elma implements Eatable, Squeezable {
  @override
  void howToEat() {
    print("Ağzınla ısır ve çiğne");
  }
  
  @override
  void howToSqueeze() {
    print("Meyve sıkacağına koy ve sık");
  }
}

void main() {
  var elma1 = Elma();
  
  print("Elma nasıl yenir?");
  elma1.howToEat();
  
  print("\nElma nasıl sıkılır?");
  elma1.howToSqueeze();
}

Çıktı:

Elma nasıl yenir?
Ağzınla ısır ve çiğne

Elma nasıl sıkılır?
Meyve sıkacağına koy ve sık

Neden İki Interface Kullandık?

Çünkü elmayı hem yiyebiliyorsunuz hem sıkıp suyu içebiliyorsunuz. Ama mesela bir taşı düşünün: Taş yenilmez ama belki kırılabilir. O zaman Taş sınıfı sadece Breakable interface'ini implement eder.

Extends vs Implements Farkı

Bu ikisini karıştırıyordum başta, şimdi netleştirdim:

Extends Implements
Tek sınıftan kalıtım alır Birden fazla interface'den alabilir
Babadan özellik miras alır Sözleşmeyi yerine getirmelidir
İsteğe bağlı override Mutlaka override gerekir

Örnek ile Açıklama

// EXTENDS örneği
class Hayvan {
  void nefesAl() {
    print("Nefes alıyor");
  }
}

class Kopek extends Hayvan {
  // nefesAl metodunu otomatik aldık
  // İstersek override ederiz, istersek etmeyiz
}

// IMPLEMENTS örneği
abstract class Yuruyebilir {
  void yuru();
}

class Insan implements Yuruyebilir {
  @override
  void yuru() {
    // Bunu MUTLAKA yazmak zorundayız
    print("İnsan yürüyor");
  }
}

Gerçek Hayattan Flutter Örneği

Flutter'da widget'lar yazarken sürekli bu yapıyı kullanıyoruz aslında:

abstract class Tiklanabilir {
  void tiklandiginda();
}

abstract class Kaydirilebilir {
  void kaydirildiginda();
}

class OzelButton implements Tiklanabilir {
  @override
  void tiklandiginda() {
    print("Butona tıklandı!");
    // Analytics'e gönder
    // Animasyon başlat
    // Veri kaydet vs.
  }
}

class OzelListView implements Tiklanabilir, Kaydirilebilir {
  @override
  void tiklandiginda() {
    print("Liste elemanına tıklandı");
  }
  
  @override
  void kaydirildiginda() {
    print("Liste kaydırıldı");
  }
}

Gördüğünüz gibi OzelListView hem tıklanabiliyor hem kaydırılabiliyor. Eğer extends kullansaydık sadece bir sınıftan özellik alabilirdik.

IDE'nin Yardımı

VS Code veya Android Studio kullandığınızda, bir interface implement ettiğinizde IDE size otomatik olarak metodları ekler. Bu çok işime yarıyor:

  1. implements Eatable yazıyorsunuz
  2. Kırmızı çizgi çıkıyor (hata var)
  3. Ampul ikonuna tıklıyorsunuz
  4. "Implement members" diyorsunuz
  5. Tüm metodlar otomatik ekleniyor!

Kullanmadığım Metodları Silebilir miyim?

Teknik olarak silemezsiniz, çünkü implements bir sözleşmedir. Ama boş bırakabilirsiniz:

class Portakal implements Eatable, Squeezable {
  @override
  void howToEat() {
    print("Soy ve ye");
  }
  
  @override
  void howToSqueeze() {
    // Boş bıraktık, ama yazmak zorundaydık
  }
}

Veya daha iyisi, gerçekten gerekmiyorsa o interface'i implement etmeyin.

Bugün Ne Öğrendim?

  • Abstract class'lar şablon görevi görür
  • Implements ile birden fazla interface kullanabiliriz
  • Extends ile implements'in farkını anladım
  • IDE'nin otomatik tamamlama özelliği çok işe yarıyor

Yarın Collections konusuna (List, Set, Map) bakacağım. Onlar da çok önemliymiş Flutter'da.

Kafa Karıştıran Nokta

Bir abstract class'ı extends de edebiliyorsunuz, implements de. Farkı şu:

  • Extends ederseniz: İçindeki metodları kullanabilirsiniz (override opsiyonel)
  • Implements ederseniz: Her şeyi override etmek zorundasınız
abstract class Sekil {
  void ciz() {
    print("Şekil çiziliyor");
  }
}

// Extends ile
class Kare extends Sekil {
  // ciz() metodunu kullanabiliriz, override opsiyonel
}

// Implements ile
class Daire implements Sekil {
  @override
  void ciz() {
    // Bunu MUTLAKA yazmalıyız
    print("Daire çiziliyor");
  }
}

Bu detayı anlamam biraz zaman aldı ama artık netleşti.


Benimle çalışmak isterseniz:

Bir sonraki yazıda görüşürüz!