Sınıf Modifikatörleri (Class Modifiers)

Sınıf modifikatörleri, bir sınıf veya karışımın hem kendi kitaplığı içinde hem de tanımlandığı kitaplığın dışında nasıl kullanılabileceğini kontrol eder.

Modifikatör anahtar kelimeleri, sınıf veya karışım bildirisinden önce gelir. Örneğin, abstract class yazarak soyut bir sınıf tanımlarsınız. Bir sınıf bildirisinden önce görünebilecek tam modifikatör kümesi şunları içerir:

  • abstract

  • base

  • final

  • interface

  • sealed

  • mixin

Sadece base modifikatörü, bir mixin bildirisinden önce görünebilir. Modifikatörler, enum, typedef, extension veya extension type gibi diğer bildirimlere uygulanmaz.

Sınıf modifikatörlerini kullanıp kullanmamaya karar verirken, sınıfın amaçlanan kullanımlarını ve sınıfın hangi davranışlara güvenebilmesi gerektiğini düşünmelisiniz.

Not

Eğer bir kütüphaneyi yönetiyorsanız, kütüphaneleriniz için bu değişiklikleri nasıl yönlendireceğiniz konusunda rehberlik için "API sağlayıcıları için Sınıf Modifikatörleri" sayfasını okuyun.

Modifikatör Olmadan (No Modifier)

Sınıfa veya karışıma modifikatör eklenmemiş bir bildiri, herhangi bir kitaplıktan inşa etme veya alt tür oluşturma izni verir. Varsayılan olarak şunları yapabilirsiniz:

  • Bir sınıfın yeni örneklerini oluşturun.

  • Bir sınıfı genişleterek yeni bir alt tür oluşturun.

  • Bir sınıfın veya karışımın arayüzünü uygulayın.

  • Bir karışımı veya karışım sınıfını içe alın.

Soyut (Abstract)

Tam bir arayüzün somut bir uygulamasını zorunlu kılmayan bir sınıf tanımlamak için soyut modifikatörü kullanın.

Soyut sınıflar herhangi bir kitaplık tarafından inşa edilemez, kendi kitaplığında olsun veya dış kitaplıklardan olsun. Soyut sınıflar genellikle soyut metodlara sahiptir.

a.dart

abstract class Arac {
  void ileriGit(int metre);
}

b.dart

import 'a.dart';

// Hata: Oluşturulamaz.
Arac aracim = Arac();

// Genişletilebilir.
class Araba extends Arac {
  int yolcuSayisi = 4;
  // ···
}

// Uygulanabilir.
class SahteArac implements Arac {
  @override
  void ileriGit(int metre) {
    // ...
  }
}

Eğer soyut sınıfınızın görünürde bir şekilde örneklenmesini istiyorsanız, bir fabrika kurucusu tanımlayın.

Base

Bir sınıfın veya karışımın uygulamasının kalıtımını zorlamak için base modifikatörünü kullanın. Base sınıf, kendi kitaplığı dışında bir uygulamayı engeller. Bu şu garantileri sağlar:

  • Base sınıfın kurucusu, sınıfın alt türünden bir örnek oluşturulduğunda her zaman çağrılır.

  • Tüm uygulanan özel üyeler, alt türlerde mevcuttur.

  • Bir base sınıfındaki yeni uygulanan bir üye, alt türleri bozmaz, çünkü tüm alt türler yeni üyeyi miras alır.

  • Bu, alt tür zaten aynı ada sahip ve uyumsuz bir imza ile bir üye bildirirse geçerli değildir.

  • Bir sınıf veya karışımı uygulayan veya genişleten herhangi bir sınıfın base, final veya sealed olarak işaretlenmesi gerekir. Bu, dış kitaplıkların base sınıfları bozmasını engeller.

a.dart

base class Arac {
  void ileriGit(int metre) {
    // ...
  }
}

b.dart

import 'a.dart';

// Oluşturulabilir.
Arac aracim = Arac();

// Genişletilebilir.
base class Araba extends Arac {
  int yolcuSayisi = 4;
  // ...
}

// HATA: Uygulanamaz.
base class SahteArac implements Arac {
  @override
  void ileriGit() {
    // ...
  }
}

Arayüz (Interface)

Bir arayüz tanımlamak için interface modifikatörünü kullanın. Arayüzün kendi tanımlayan kitaplığının dışındaki kitaplıklar arayüzü uygulayabilir, ancak genişletemez. Bu şu garantileri sağlar:

  • Bir sınıfın örnek metotlarından biri diğer bir metodu çağırdığında, bu her zaman aynı kitaplıktan bilinen bir metodun uygulanmasını çağırır.

  • Diğer kitaplıklar, arayüz sınıfının kendi metotlarını beklenmedik şekillerde geçersiz kılabilecek metodları geçersiz kılamaz. Bu, kırılgan base sınıf sorununu azaltır.

a.dart

interface class Arac {
  void ileriGit(int metre) {
    // ...
  }
}

b.dart

import 'a.dart';

// Oluşturulabilir.
Arac aracim = Arac();

// HATA: Genişletilemez.
class Araba extends Arac {
  int yolcuSayisi = 4;
  // ...
}

// Uygulanabilir.
class SahteArac implements Arac {
  @override
  void ileriGit(int metre) {
    // ...
  }
}

Soyut Arayüz (Abstract Interface)

interface modifikatörünü genellikle saf bir arayüzü tanımlamak için kullanın. Bir soyut sınıfa, başka kitaplıklar tarafından uygulanabilir ancak miras alınamayan bir arayüz için interface ve abstract modifikatörlerini birleştirin. Bu, başka kitaplıkların bir arayüzü uygulayabilmesine, ancak miras alamamasına olanak tanır.

Final

Tip hiyerarşisini kapatmak için final modifikatörünü kullanın. Bu, mevcut kitaplığın dışındaki bir sınıftan alt türleme izin vermez. Hem kalıtım hem de uygulamayı engelleyerek tamamen alt türlemeyi engeller. Bu şu garantileri sağlar:

  • API'ye aşamalı değişiklikler ekleyebilirsiniz.

  • Birinci sınıf alt sınıflarının örnek metotlarını güvenle çağırabilirsiniz, çünkü bunların üçüncü taraf alt sınıfları tarafından üzerine yazılmamış olması garantilidir.

  • Final sınıfları aynı kitaplık içinde genişletilebilir veya uygulanabilir. Final modifikatörü, base'nin etkilerini içerir ve bu nedenle alt sınıflar da base, final veya sealed olarak işaretlenmelidir.

a.dart

final class Arac {
  void ileriGit(int metre) {
    // ...
  }
}

b.dart

import 'a.dart';

// Oluşturulabilir.
Arac aracim = Arac();

// HATA: Genişletilemez.
class Araba extends Arac {
  int yolcuSayisi = 4;
  // ...
}

class SahteArac implements Arac {
  // HATA: Uygulanamaz.
  @override
  void ileriGit(int metre) {
    // ...
  }
}

Mühürlü (Sealed)

Belli, sayılabilir bir alt tür kümesi oluşturmak için sealed modifikatörünü kullanın. Bu, bu alt türler üzerinde duraksızca geçiş yapılması için derleyici tarafından statik olarak sağlanan bir switch oluşturmanıza olanak tanır.

Sealed modifikatörü, bir sınıfın kendi kitaplığı dışında genişletilmesine veya uygulanmasına izin vermez. Mühürlü sınıflar, varsayılan olarak soyut olarak kabul edilir.

  • Kendi başlarına oluşturulamazlar.

  • Fabrika kurucularına sahip olabilirler.

  • Alt sınıflarının kullanması için kurucular tanımlayabilirler.

Derleyici, bu alt türlerin yalnızca aynı kitaplıkta var olabileceğini bildiği için herhangi bir olası doğrudan alt türün farkındadır. Bu, bir switch'in tüm olası alt türleri işlemediğinde sizi uyarabilir:

a.dart

sealed class Arac {}

class Araba extends Arac {}

class Kamyon implements Arac {}

class Bisiklet extends Arac {}

// HATA: Oluşturulamaz.
Arac aracim = Arac();

// Alt sınıflar oluşturulabilir.
Arac aracimAraba = Araba();

String getAracSesi(Arac arac) {
  // HATA: Switch, Bicycle alt türünü veya varsayılan durumu eksik bıraktı.
  return switch (arac) {
    case Araba() => 'vroom',
    case Kamyon() => 'VROOOOMM',
  };
}

Eğer kapsamlı bir geçiş istemiyorsanız veya daha sonra alt türler ekleyebilmek istiyorsanız, final modifikatörünü kullanın. Daha ayrıntılı bir karşılaştırma için "mühürlü versus final"i okuyun.

Modifikatörleri Birleştirme

Bazı modifikatörleri katmanlı kısıtlamalar için birleştirebilirsiniz. Bir sınıf bildirimi, sırasıyla:

  • (İsteğe Bağlı) Soyut olup olmadığını belirten abstract, sınıfın soyut üyeler içerebilme ve örneklenememe yeteneğini engeller.

  • (İsteğe Bağlı) base, interface, final veya sealed'dan biri, sınıfın başka kitaplıkların alt türlerine yönelik kısıtlamalarını belirler.

  • (İsteğe Bağlı) mixin, bildirimin karıştırılıp karıştırılamayacağını belirler.

  • Sınıf anahtar kelimesi kendisi.

Bazı modifikatörleri birleştiremezsiniz çünkü bunlar çelişkili, gereksiz veya başka türlü birbirleriyle çakışan modifikatörlerdir:

  • abstract ile sealed. Bir mühürlü sınıf zaten soyut olarak kabul edilir.

  • mixin ile interface, final veya sealed. Bu erişim modifikatörleri karışmayı engeller.

Last updated