Sınıflar (Classes)

Dart, sınıflar ve mixin tabanlı kalıtım kullanılarak nesne tabanlı bir dil olarak tasarlanmıştır. Her nesne, bir sınıf örneğidir ve Null dışındaki tüm sınıflar Object sınıfından türemiştir. Mixin tabanlı kalıtım, her sınıfın (Object sınıfı hariç) tam olarak bir üst sınıfa sahip olduğu anlamına gelir; ancak sınıfın içeriği birden fazla sınıf hiyerarşisinde yeniden kullanılabilir. Extension metodları, bir sınıfa fonksiyonellik eklemenin bir yoludur ve sınıfı değiştirmeden veya alt sınıf oluşturmadan bu işlevselliği sağlar. Sınıf modifikatörleri, kütüphanelerin bir sınıfı alt tür olarak nasıl kullanabileceğini kontrol etmenizi sağlar.

Sınıf Üyelerini Kullanma

Nesneler, fonksiyonlar ve verilerden oluşan üyelere sahiptir (sırasıyla metotlar ve örnek değişkenler). Bir metodu çağırdığınızda, bunu bir nesne üzerinde çağırırsınız: metot, bu nesnenin fonksiyonlarına ve verilerine erişime sahiptir.

Bir örnek değişkeni veya metodu belirtmek için bir nokta (.) kullanılır:

var p = Nokta(2, 2);

// Y'nin değerini al.
assert(p.y == 2);

// p üzerinde mesafeHesapla() metodunu çağır.
double mesafe = p.mesafeHesapla(Nokta(4, 4));

Nesnenin en sol operandı null olduğunda bir istisna oluşmaması için . yerine ?. kullanılır:

// Eğer p null değilse, bir değişkeni onun y değerine eşitle.
var a = p?.y;

Yapıcıları (Constructors) Kullanma

Bir nesne oluşturmak için bir yapıcı kullanabilirsiniz. Yapıcı isimleri SinifAdi veya SinifAdi.tanimlayici olabilir. Örneğin, aşağıdaki kod, Nokta() ve Nokta.fromJson() yapıcılarını kullanarak Nokta nesneleri oluşturur:

var p1 = Nokta(2, 2);
var p2 = Nokta.fromJson({'x': 1, 'y': 2});

Aynı etkiye sahip olan aşağıdaki kod, yapıcı adından önce opsiyonel new anahtar kelimesini kullanır:

var p1 = new Nokta(2, 2);
var p2 = new Nokta.fromJson({'x': 1, 'y': 2});

Bazı sınıflar, sabit yapıcılar sağlar. Sabit bir yapıcı kullanarak derleme zamanında bir sabit oluşturmak için, const anahtar kelimesini yapıcı adından önce ekleyin:

var p = const SabitNokta(2, 2);

İki adet aynı sabit yapıcı oluşturmak, tek bir, standart örneği sonuçlandırır:

var a = const SabitNokta(1, 1);
var b = const SabitNokta(1, 1);

assert(identical(a, b)); // Aynı örnektir!

Bir sabit bağlam içinde, bir yapıcı veya literalin const önündeki tüm kullanımları atlayabilirsiniz. Örneğin, bu kodu inceleyin, bir const haritası oluşturan:

// Burada çok sayıda const anahtarı var.
const noktaVeCizgi = const {
  'nokta': const [const SabitNokta(0, 0)],
  'cizgi': const [const SabitNokta(1, 10), const SabitNokta(-2, 11)],
};

Tüm const anahtarını ilk kullanım haricinde atlayabilirsiniz:

// Sadece bir const var, bu sabit bağı oluşturur.
const noktaVeCizgi = {
  'nokta': [SabitNokta(0, 0)],
  'cizgi': [SabitNokta(1, 10), SabitNokta(-2, 11)],
};

Bir sabit yapıcı, sabit bir bağlam dışında ve const olmadan çağrıldığında, sabit olmayan bir nesne oluşturur:

var a = const SabitNokta(1, 1); // Sabit oluşturur
var b = SabitNokta(1, 1); // Sabit bir nesne OLUŞTURMAZ

assert(!identical(a, b)); // Aynı örnek değil!

Bir Nesnenin Türünü Almak (Object's Type)

Bir nesnenin çalışma zamanındaki türünü almak için, Object özelliği olan runtimeType kullanabilirsiniz, bu da bir Type nesnesi döndürür.

print('a nesnesinin türü ${a.runtimeType}');

Uyarı

Bir nesnenin türünü test etmek için runtimeType yerine bir tür test operatörü kullanın. Üretim ortamlarında, test nesnesi Type, test nesne.runtimeType == Type'den daha kararlıdır.

Buraya kadar, sınıfları nasıl kullanacağınızı gördünüz. Bu bölümün geri kalanı, sınıfları nasıl uygulayacağınızı gösterir.

Örnek Değişkenler (Instance Variables)

İşte örnek değişkenlerin nasıl bildirileceği:

class Nokta {
  double? x; // İlk başta null olan x adlı örnek değişkenini bildir.
  double? y; // İlk başta null olan y adlı örnek değişkenini bildir.
  double z = 0; // İlk başta 0 olan z adlı örnek değişkenini bildir.
}

Nullable bir türle bildirilen başlatılmamış bir örnek değişkeninin değeri null'dır. Başlatılmamış, nullable olmayan örnek değişkenleri, örneğin oluşturulduğunda, yapıcı ve onun başlatıcı listesi çalışmadan önce değerini almalıdır.

Tüm örnek değişkenleri, gizli bir get metodu oluşturur. Nullable olmayan örnek değişkenleri ve başlatıcı listesi olmayan late final örnek değişkenleri, aynı zamanda gizli bir set metodu oluşturur. Ayrıntılar için getters ve setters'a bakın.

class Nokta {
  double? x; // İlk başta null olan x adlı örnek değişkenini bildir.
  double? y; // İlk başta null olan y adlı örnek değişkenini bildir.
}

void main() {
  var nokta = Nokta();
  nokta.x = 4; // x için setter metodunu kullan.
  assert(nokta.x == 4); // x için getter metodunu kullan.
  assert(nokta.y == null); // Değerler varsayılan olarak null'dur.
}

Bir non-late (late olmayan) örnek değişkenini bildirirken, değeri oluşturulan örnek oluşturulduğu anda, yani kurucu ve başlatıcı listesi çalışmadan önce belirlenir. Bu nedenle, bir non-late örnek değişkeninin başlatma ifadesi (='den sonraki) this'e erişemez.

double baslangicX = 1.5;

class Nokta {
  // Tamam, `this`'e bağlı olmayan deklarasyonlara erişebilir:
  double? x = baslangicX;

  // HATA, non-`late` başlatıcıda `this`'e erişemez:
  double? y = this.x;

  // Tamam, `this`'e `late` başlatıcıda erişebilir:
  late double? z = this.x;

  // Tamam, `this.fieldName` bir parametre deklarasyonudur, bir ifade değil:
  Nokta(this.x, this.y);
}

Örnek değişkenleri final olabilir, bu durumda bir kereye mahsus olarak ayarlanmalıdır. Final, non-late örnek değişkenlerini tanımlama sırasında, bir yapılandırıcı (constructor) parametresiyle veya bir yapılandırıcının başlatıcı (constructor initializer) listesi kullanarak başlatın:

class Profil {
  final String isim;
  final DateTime baslangic = DateTime.now();

  Profil(this.isim);
  Profil.isimsiz() : isim = '';
}

Bir yapılandırıcı gövdesi başladıktan sonra bir final örnek değişkeninin değerini atamak gerekiyorsa, aşağıdaki yöntemlerden birini kullanabilirsiniz:

  • Fabrika yapıcı kullanın.

  • Late final kullanın, ancak dikkatli olun: başlatıcı eklemeyen late final, API'ye bir setter ekler.

Örtük Arabirimler (Implicit Interfaces)

Her sınıf, sınıfın tüm örnek üyelerini ve uyguladığı arabirimlerin tüm örnek üyelerini içeren örtük bir arabirim tanımlar. Eğer A sınıfının B sınıfının uygulamasını devralmadan sadece B'nin API'sini destekleyen bir A sınıfı oluşturmak istiyorsanız, A sınıfının B arabirimini uygulaması gerekir.

Bir sınıf, bu arabirimleri bir implements ifadesinde belirterek bir veya daha fazla arabirimi uygular ve ardından arabirimlerin gerektirdiği API'leri sağlar. Örneğin:

// Bir kişi. Implicit (örtük) arayüz, selamVer() metodunu içerir.
class Kisi {
  // Arayüzde bulunan ancak sadece bu kütüphanede görünür.
  final String _isim;

  // Arayüzde bulunmayan, çünkü bu bir kurucu metod.
  Kisi(this._isim);

  // Arayüzde bulunan bir metod.
  String selamVer(String kime) => 'Merhaba, $kime. Ben $_isim.';
}

// Kisi arayüzünü uygulayan bir sınıf.
class Sahtekar implements Kisi {
  String get _isim => '';

  String selamVer(String kime) => 'Selam $kime. Beni tanıyor musun?';
}

String selamVerBob(Kisi kisi) => kisi.selamVer('Mehmet');

void main() {
  print(selamVerBob(Kisi('Bayram')));
  print(selamVerBob(Sahtekar()));
}

Birden fazla arabirimi uyguladığınızı belirtmenin bir örneği:

class Nokta implements Karsilastirilabilir, Konum {...}

Sınıf Değişkenleri ve Metotları (Class Variables and Methods)

Sınıf çapında değişkenler ve metodlar uygulamak için static anahtar kelimesini kullanın.

Statik Değişkenler (Static Variables)

Statik değişkenler (sınıf değişkenleri), sınıf genelinde durumu ve sabitleri depolamak için kullanışlıdır:

class Kuyruk {
  static const baslangicKapasitesi = 16;
  // ···
}

void main() {
  assert(Kuyruk.baslangicKapasitesi == 16);
}

Statik değişkenler, kullanıldıkları zaman başlatılır.

Statik Metotlar (Static Methods)

Statik metotlar (sınıf metotları), bir instance üzerinde çalışmaz ve bu nedenle this'e erişemez. Ancak, statik değişkenlere erişebilirler. Aşağıdaki örnek gösterildiği gibi, statik metotları bir sınıf üzerinde doğrudan çağırabilirsiniz:

import 'dart:math';

class Nokta {
  double x, y;
  Nokta(this.x, this.y);

  static double mesafe(Nokta a, Nokta b) {
    var dx = a.x - b.x;
    var dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
  }
}

void main() {
  var a = Nokta(2, 2);
  var b = Nokta(4, 4);
  var mesafe = Nokta.mesafe(a, b);
  assert(2.8 < mesafe && mesafe < 2.9);
  print(mesafe);
}

Not

Ortak veya geniş bir kullanımı olan yardımcı program ve işlevsellik için statik metotlar yerine, statik metotlar yerine üst düzey fonksiyonları kullanmayı düşünün.

Statik metotları derleme zamanı sabitleri olarak kullanabilirsiniz. Örneğin, bir statik metodu bir sabit yapıcıya bir parametre olarak geçirebilirsiniz.

Last updated