Dart’ta Interface ve Abstract Class Uygulamaları

Dart, nesne yönelimli programlama yaklaşımını benimseyen bir dil olarak soyutlama, genişletilebilirlik ve çok biçimlilik gibi kavramları güçlü biçimde destekler. Bu yazıda, Dart’ta arayüz (interface) benzeri yapıların nasıl oluşturulduğunu, nasıl uygulandığını ve mimaride ne tür avantajlar sağladığını örnek üzerinden inceleyeceğiz.


Abstract Class ile Interface Tanımlama

Dart dilinde doğrudan bir interface anahtar kelimesi bulunmaz; bunun yerine soyut sınıflar (abstract classes) arayüz işlevi görecek şekilde kullanılabilir. Soyut sınıflar, onları uygulayan sınıflara belirli bir davranış kümesi dayatan bir kurallar bütünü (sözleşme / contract) tanımlar.

Örnek tanım:

abstract class MyInterface {
  late int degisken;   // Uygulayıcı sınıfın sağlaması gereken özellik
  void metod1();       // Gövdesiz, uygulanması zorunlu metod
  String metod2();     // Uygulanması zorunlu, String döndüren metod
}

Temel Özellikler

  • Soyut sınıf (abstract class): Doğrudan örneği oluşturulamaz; yalnızca alt sınıflara davranış bildirir.
  • Soyut üyeler (abstract members): Gövdesi olmayan metod ve özellik bildirimleridir.
  • Sözleşme (contract): Uygulayıcı her sınıfın bu üyeleri eksiksiz şekilde tanımlamak zorunda olduğu kurallar bütünüdür.

Bir Arayüzün Uygulanması (implements)

Bir sınıf, implements anahtar kelimesini kullandığında soyut sınıftaki tüm öğeleri tamamen yeniden tanımlamak (override) zorundadır. Bu yaklaşım, soyut sınıfın arayüz (interface) gibi davranmasını sağlar.

Örnek uygulama:

class ClassA implements MyInterface {
  @override
  late int degisken = 10;

  @override
  void metod1() {
    print("Metod 1 Çalıştı");
  }

  @override
  String metod2() {
    return "Metod 2 Çalıştı";
  }
}

Temel Özellikler

  • implements: Bir sınıfın, bildirilen sözleşmeyi (contract) eksiksiz uyguladığını belirtir.
  • override: Üst sınıf veya arayüzde bildirilen öğelerin yeniden tanımlandığını gösterir.
  • Tam uygulama zorunluluğu: Arayüzdeki tüm üyeler uygulayıcı sınıf tarafından sağlanmalıdır.

Kullanım Örneği (main Fonksiyonu)

void main() {
  var a = ClassA();
  print(a.degisken);
  a.metod1();
  print(a.metod2());
}

Konsol Çıktısı

10
Metod 1 Çalıştı
Metod 2 Çalıştı

Arayüz (Interface) ve Sözleşme (Contract) Yapılarının Önemi

Bu yapılar, nesne yönelimli tasarımın temel bileşenlerindendir ve aşağıdaki gerekçelerle büyük kod tabanlarında kritik önem taşır:

Tutarlılık

Tüm uygulayıcı sınıfların aynı metod imzasına sahip olmasını sağlar.

Çok Biçimlilik (Polymorphism)

Farklı sınıflar, dış dünyaya aynı tür (ör. MyInterface) olarak görünebilir; bu da esnek kod tasarımı sağlar.

Bağımlılık Tersine Çevirme (Dependency Inversion)

Üst seviye bileşenler, somut sınıflara değil, soyut sözleşmelere (contracts) bağımlı olur.

Test Edilebilirlik (Testability)

Mock veya sahte sınıfların kolayca üretilmesini sağlar.


Sonuç

Dart’ta soyut sınıflar (abstract classes) ve implements kullanımı, arayüz (interface) benzeri sözleşmelerin (contracts) oluşturulmasını mümkün kılar. Bu yaklaşım, genişletilebilir, tutarlı ve çok biçimli yapıların geliştirilmesinde önemli bir rol oynar.

Bu örnek, sözleşme temelli mimariyi anlamak için temel bir çerçeve sunar. Sonraki aşamada, extends (miras), implements (arayüz uygulama) ve with (mixins) yapılarının tüm farklarını kapsayan daha kapsamlı bir derlemeye geçmek faydalı olacaktır.