Menu
Coddy logo textTech

Extension Metotlar

Coddy'nin Dart Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 83 / 110.

Bazen, Dart'ın yerleşik String veya int türleri gibi, size ait olmayan bir sınıfa işlevsellik eklemek istersiniz. Kaynak kodlarını değiştiremezsiniz ve kalıtım, final sınıflarda yardımcı olmaz. İşte extension methods (genişletme metotları) burada devreye girer.

Uzantılar (Extensions), mevcut türleri değiştirmeden veya alt sınıflar oluşturmadan onlara yeni yöntemler eklemenize olanak tanır:

extension StringExtras on String {
  String reverse() {
    return split('').reversed.join('');
  }
  
  bool get isPalindrome {
    var cleaned = toLowerCase().replaceAll(' ', '');
    return cleaned == cleaned.split('').reversed.join('');
  }
}

void main() {
  print('hello'.reverse());        // olleh
  print('radar'.isPalindrome);     // true
}

Söz dizimi extension ExtensionName on Type şeklindedir. İçerisinde, tıpkı normal bir sınıfta olduğu gibi metotlar ve getter'lar tanımlarsınız. Tanımlandıktan sonra, bu metotlar sanki yerleşikmiş gibi o türün tüm örneklerinde görünür.

Uzantılar (Extensions), kendi sınıflarınız ve genel (generic) türler de dahil olmak üzere her tür üzerinde çalışır:

extension IntExtras on int {
  int squared() => this * this;
}

extension ListExtras<T> on List<T> {
  T? get secondOrNull => length >= 2 ? this[1] : null;
}

void main() {
  print(5.squared());                    // 25
  print([1, 2, 3].secondOrNull);         // 2
}

Bir extension içinde, this ifadesinin metodun çağrıldığı örneği referans aldığına dikkat edin. Extension'lar, kodunuzu düzenli ve okunabilir tutarken mevcut türleri geliştirmenin temiz bir yoludur.

challenge icon

Görev

Kolay

Dart'ın yerleşik türlerini uzantı metotları (extension methods) kullanarak kullanışlı işlevlerle geliştirelim! String ve List türlerine yardımcı metotlar ekleyen uzantılar oluşturacak ve ardından bunları ana dosyanızda kullanacaksınız.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • extensions.dart: Mevcut türlere yeni yetenekler ekleyen iki uzantı oluşturun:
    • String üzerinde şu özelliklere sahip StringUtils adlı bir uzantı:
      • Dizedeki sesli harflerin (a, e, i, o, u - büyük/küçük harf duyarsız) sayısını döndüren bir countVowels() metodu
      • Her kelimenin (boşluklarla ayrılmış) ilk harfini birleştirilmiş ve büyük harfe dönüştürülmüş olarak döndüren bir initials getter'ı. Örneğin, "hello world" dizesi "HW" olur
    • List<T> üzerinde şu özelliklere sahip ListUtils<T> adlı bir uzantı:
      • Belirtilen indeksteki öğe mevcutsa onu, indeks sınırların dışındaysa null döndüren bir safeGet(int index) metodu
      • Liste birden fazla öğeye sahipse true döndüren bir hasMultiple getter'ı
  • main.dart: Uzantılarınızı içe aktarın ve onları iş başında gösterin:
    • "Object Oriented Programming" dizesini oluşturun ve sesli harf sayısını şu formatta yazdırın: Vowels: [count]
    • Aynı dizenin baş harflerini şu formatta yazdırın: Initials: [initials]
    • [10, 20, 30] tam sayılarından oluşan bir liste oluşturun
    • safeGet(1) sonucunu şu formatta yazdırın: Element at 1: [value]
    • safeGet(5) sonucunu şu formatta yazdırın: Element at 5: [value]
    • Listenin birden fazla öğeye sahip olup olmadığını şu formatta yazdırın: Has multiple: [true/false]

Bir uzantı içinde this ifadesinin, metodun çağrıldığı örneği (instance) temsil ettiğini unutmayın. Uzantılarınız, bu türlerin sanki bu metotlara doğuştan sahipmiş gibi hissettirmesini sağlayacaktır!

Beklenen çıktı:

Vowels: 9
Initials: OOP
Element at 1: 20
Element at 5: null
Has multiple: true

Kopya kağıdı

Genişletme metotları (extension methods), mevcut türlerin kaynak kodunu değiştirmeden veya kalıtım kullanmadan onlara yeni işlevsellikler eklemenize olanak tanır.

Bir genişletme oluşturmak için kullanılan söz dizimi extension ExtensionName on Type şeklindedir:

extension StringExtras on String {
  String reverse() {
    return split('').reversed.join('');
  }
  
  bool get isPalindrome {
    var cleaned = toLowerCase().replaceAll(' ', '');
    return cleaned == cleaned.split('').reversed.join('');
  }
}

Tanımlandıktan sonra, genişletme metotları o türün örnekleri üzerinde sanki yerleşik metotlarmış gibi çağrılabilir:

print('hello'.reverse());        // olleh
print('radar'.isPalindrome);     // true

Genişletmeler; yerleşik türler, kendi sınıflarınız ve genel (generic) türler dahil olmak üzere her tür üzerinde çalışır:

extension IntExtras on int {
  int squared() => this * this;
}

extension ListExtras<T> on List<T> {
  T? get secondOrNull => length >= 2 ? this[1] : null;
}

print(5.squared());                    // 25
print([1, 2, 3].secondOrNull);         // 2

Bir genişletme içerisinde this, metodun üzerinde çağrıldığı örneği ifade eder.

Kendin dene

import 'extensions.dart';

void main() {
  // String'i oluşturun
  String text = "Object Oriented Programming";

  // TODO: countVowels() kullanarak sesli harf sayısını yazdırın
  // Format: Vowels: [count]

  // TODO: initials getter'ını kullanarak baş harfleri yazdırın
  // Format: Initials: [initials]

  // Tam sayı listesini oluşturun
  List<int> numbers = [10, 20, 30];

  // TODO: safeGet(1) sonucunu yazdırın
  // Format: Element at 1: [value]

  // TODO: safeGet(5) sonucunu yazdırın
  // Format: Element at 5: [value]

  // TODO: Listenin birden fazla öğeye sahip olup olmadığını yazdırın
  // Format: Has multiple: [true/false]
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler