Yapıcılar (Constructors)

Bir constructor'ı, sınıfının adını (isteğe bağlı olarak Named constructor bölümünde açıklandığı gibi, ek bir tanımlayıcı) kullanarak bir fonksiyon oluşturarak tanımlayın.

Yeni bir sınıf örneği oluşturmak için en yaygın constructor olan "generative constructor"ı kullanın ve gerekirse herhangi bir örnek değişkenini başlatmak için initializing formal parameters'ları kullanın:

class Nokta {
  double x = 0;
  double y = 0;

  // İlk değer ataması yapılan kurucu method (generative constructor):
  Nokta(this.x, this.y);
}

this kelimesi mevcut örneğe referans yapar.

Not

this'i, bir isim çakışması olduğunda kullanın. Aksi takdirde, Dart stili this'i atlar.

Formal Parametreleri Başlatma (Initializing Formal Parameters)

Dart, bir constructor argümanını bir örnek değişkenine atamak için yaygın bir deseni basitleştirmek için initializing formal parameters'ları kullanır. Constructor tanımında doğrudan this.ozellikAdi'ni kullanın ve gövdeyi atlayın.

Initializing parametreleri, non-nullable veya final örnek değişkenlerini başlatmanıza olanak tanır, çünkü her ikisi de başlatılmalı veya varsayılan bir değer verilmelidir:

class Nokta {
  final double x;
  final double y;

  Nokta(this.x, this.y);
  // Kurucu method gövdesi çalışmadan önce
  // x ve y örnek değişkenlerini ayarlar.
}

Başlatma formaliteleri tarafından tanıtılan değişkenler, içsel olarak finaldir ve yalnızca başlatıcı listesinin kapsamında geçerlidir.

Başlatıcı listesinde ifade edilemeyen bazı mantık gerçekleştirmeniz gerekiyorsa, o mantığı içeren bir fabrika kurucusu (veya statik metod) oluşturun ve ardından hesaplanan değerleri normal bir kurucuya geçirin.

Varsayılan Yapıcılar (Default Constructors)

Eğer bir constructor tanımlamazsanız, size bir varsayılan constructor sağlanır. Varsayılan constructor'ın argümanı yoktur ve üst sınıftaki argümansız constructor'ı çağırır.

Yapıcılar Miras Edilmez (Constructors Aren't Inherited)

Alt sınıflar, üst sınıflarından constructorları miras almazlar. Constructor tanımlamayan bir alt sınıf, yalnızca varsayılan (argüman olmayan, isimsiz) constructor'a sahiptir.

İsimlendirilmiş Yapıcılar (Named Constructors)

Bir sınıf için birden çok constructor uygulamak veya ek açıklama sağlamak için isimlendirilmiş constructor'ları kullanın:

const double xOrigin = 0;
const double yOrigin = 0;

class Nokta {
  final double x;
  final double y;

  Nokta(this.x, this.y);

  // İsimlendirilmiş constructor
  Nokta.origin()
      : x = xOrigin,
        y = yOrigin;
}

Constructor'lar miras alınmadığı için, bir üst sınıftaki isimlendirilmiş constructor'ı bir alt sınıfta kullanmak istiyorsanız, o constructor'ı alt sınıfta implemente etmelisiniz.

Argümansız Üst Sınıf Constructor'ını Çağırmak

Varsayılan olarak, bir alt sınıftaki bir constructor, üst sınıfın isimsiz, argümansız constructor'ını çağırır. Üst sınıfın constructor'ı, constructor gövdesinin başında çağrılır. Eğer bir initializer list de kullanılıyorsa, bu, üst sınıf çağrılmadan önce gerçekleştirilir. Özetle, yürütme sırası şu şekildedir:

  • initializer list

  • üst sınıfın argümansız constructor'u

  • ana sınıfın argümansız constructor'u

Eğer üst sınıfın isimsiz, argümansız constructor'u yoksa, o zaman üst sınıfın bir constructor'ını manuel olarak çağırmanız gerekir. Bu, iki nokta üst üste (:) ve ardından constructor gövdesi (varsa) ile belirtilir.

Aşağıdaki örnekte, Calisan sınıfının constructor'ı, üst sınıfı olan Kisi sınıfının isimli constructor'ını çağırır:

class Kisi {
  String? ad;

  Kisi.fromJson(Map data) {
    print('Kisi sınıfında');
  }
}

class Calisan extends Kisi {
  // Kisi sınıfının varsayılan bir kurucusu yok;
  // bu nedenle super.fromJson() çağırmalısınız.
  Calisan.fromJson(Map data) : super.fromJson(data) {
    print('Calisan sınıfında');
  }
}

void main() {
  var calisan = Calisan.fromJson({});
  print(calisan);
  // Çıktı:
  // Kisi sınıfında
  // Calisan sınıfında
  // Instance of 'Calisan'
}

Uyarı

Üst sınıf constructor'ına argümanlar, this'e erişim sağlamaz. Örneğin, argümanlar static metodları çağırabilir, ancak örnek metodları çağıramaz.

Super Parametreleri (Super Prameters)

Her bir parametreyi tek tek üst sınıf constructor'ına geçirmekten kaçınmak için, belirli veya varsayılan üst sınıf constructor'ına parametreleri iletmeniz için super-initializer parametrelerini kullanabilirsiniz. Bu özellik, initializing formal parameters ile benzer sözdizimi ve anlamı taşır:

class Vektor2D {
  final double x;
  final double y;

  Vektor2D(this.x, this.y);
}

class Vektor3D extends Vektor2D {
  final double z;

  // x ve y parametrelerini varsayılan süper kurucuya yönlendirin:
  // Vektor3D(final double x, final double y, this.z) : super(x, y);
  Vektor3D(double x, double y, this.z) : super(x, y);
}

Super-initializer parametreleri, super-constructor çağrısında zaten pozisyonel argümanlar varsa pozisyonel olamaz, ancak her zaman isimli olabilir:

class Vektor2D {
  // ...

  Vektor2D.named({required this.x, required this.y});
}

class Vektor3D extends Vektor2D {
  // ...

  // y parametresini isimli süper kurucuya yönlendirin:
  // Vektor3D.yzDuzlemi({required double y, required this.z})
  //       : super.named(x: 0, y: y);
  Vektor3D.yzDuzlemi({required super.y, required this.z}) : super.named(x: 0);
}

Initializer List

Super sınıf constructor'ını çağırmak dışında, constructor gövdesi çalışmadan önce örnek değişkenlerini başlatmak için initializer list'ini kullanabilirsiniz. Virgül ile ayrılmış başlatıcıları kullanın.

// Başlatıcı liste, kurucu gövdesi çalışmadan önce
// örnek değişkenlerini ayarlar.
class Nokta {
  final double x;
  final double y;

  Nokta.fromJson(Map<String, double> json)
      : x = json['x']!,
        y = json['y']! {
    print('Nokta.fromJson() içinde: ($x, $y)');
  }
}

Uyarı

Initializer'ın sağ tarafı this'e erişim sağlamaz.

Geliştirme sırasında, initializer list içinde assert kullanarak girişleri doğrulayabilirsiniz.

Nokta.withAssert(this.x, this.y) : assert(x >= 0) {
    print('Nokta.withAssert() içinde: ($x, $y)');
}

Initializer list'leri, final alanları ayarlamak için kullanışlıdır. Aşağıdaki örnek, üç final alanı initializer list içinde başlatır:

import 'dart:math';

class Nokta {
  final double x;
  final double y;
  final double originUzaklik;

  Nokta(double x, double y)
      : x = x,
        y = y,
        originUzaklik = sqrt(x * x + y * y);
}

void main() {
  var nokta = Nokta(2, 3);
  print(nokta.originUzaklik);
}

Yönlendiren Yapıcılar (Redirect Constructors)

Bazen bir constructor'ın tek amacı, aynı sınıftaki başka bir constructor'a yönlendirmektir. Yönlendiren constructor'ın gövdesi boştur ve constructor çağrısı (this yerine sınıf adını kullanarak) iki nokta üst üste ile gösterildikten sonra gelir.

class Nokta {
  double x, y;

  // Bu sınıfın ana kurucusu.
  Nokta(this.x, this.y);

  // Ana yapıcıya yönlendirir.
  Nokta.xEksenineUzanan(double x) : this(x, 0);
}

Sabit Yapıcılar (Constant Constructors)

Eğer sınıfınız, asla değişmeyen nesneleri üretiyorsa, bu nesneleri derleme zamanı sabitleri yapabilirsiniz. Bunun için bir const constructor tanımlayın ve tüm örnek değişkenlerinin final olduğundan emin olun.

class SabitNokta {
  static const SabitNokta orijin = SabitNokta(0, 0);

  final double x, y;

  const SabitNokta(this.x, this.y);
}

Sabit constructor'lar her zaman sabitler oluşturmaz. Detaylar için constructor'ları kullanma bölümüne bakın.

Factory Yapıcılar (Factory ConstructorS)

Constructor'ın her zaman sınıfının yeni bir örneğini oluşturmadığını uyguladığınızda, bir constructor'ı implement etmek için factory anahtar kelimesini kullanabilirsiniz. Örneğin, bir factory constructor, bir örneği önbellekten döndürebilir veya bir alt türün bir örneğini döndürebilir. Factory constructor'lar için bir başka kullanım da bir final değişkenini initializer list içinde ele alamayacak mantığı kullanarak başlatmaktır.

İpucu

Bir final değişkenini dikkatlice kullanmak için, bir final değişkenini geç başlatma yoluna başvurabilirsiniz!

Aşağıdaki örnekte, Gunluk factory constructor'ı, nesneleri bir önbellekten döndürür ve Gunluk.fromJson factory constructor'ı, bir JSON nesnesinden bir final değişkeni başlatır.

class Gunluk {
  final String ad;
  bool sessiz = false;

  // _cache, isminin önündeki _ sayesinde
  // kütüphane içinde özel (private) bir değişkendir.
  static final Map<String, Gunluk> _onbellek = <String, Gunluk>{};

  factory Gunluk(String ad) {
    return _onbellek.putIfAbsent(ad, () => Gunluk._icSel(ad));
  }

  factory Gunluk.fromJson(Map<String, Object> json) {
    return Gunluk(json['ad'].toString());
  }

  Gunluk._icSel(this.ad);

  void kayit(String mesaj) {
    if (!sessiz) print(mesaj);
  }
}

Not

Factory constructor'ları, this'e erişime sahip değildir.

Bir factory constructor'ını, diğer herhangi bir constructor gibi çağırın:

var gunluk = Gunluk('UI');
gunluk.kayit('Butona tıklandı');

var kayitHaritasi = {'isim': 'UI'};
var gunlukJson = Gunluk.fromJson(kayitHaritasi);

Last updated