Menu
Coddy logo textTech

noSuchMethod Override

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

Bir nesne üzerinde mevcut olmayan bir metodu çağırdığınızda, Dart normalde bir NoSuchMethodError fırlatır. Ancak, bu çağrıları yakalamak ve onları düzgün bir şekilde ele almak için özel noSuchMethod() metodunu geçersiz kılabilirsiniz.

noSuchMethod() kullanmak için, sınıfınızın ayrıca bir arayüz uygulaması veya dynamic yazımını kullanması gerekir.

Metot, yapılan çağrıyla ilgili ayrıntıları içeren bir Invocation nesnesi alır:

class Flexible {
  @override
  dynamic noSuchMethod(Invocation invocation) {
    var methodName = invocation.memberName.toString();
    print('Called: $methodName');
    return null;
  }
}

void main() {
  dynamic obj = Flexible();
  obj.anyMethod();      // Çağrıldı: Symbol("anyMethod")
  obj.anotherOne(42);   // Çağrıldı: Symbol("anotherOne")
}

Invocation nesnesi çağrı hakkında yararlı bilgiler sağlar - memberName size yöntem adını bir Symbol olarak verir, positionalArguments geçirilen argümanları içerir ve isMethod bunun bir getter veya setter yerine bir yöntem çağrısı olup olmadığını söyler.

class Logger {
  @override
  dynamic noSuchMethod(Invocation invocation) {
    print('Method: ${invocation.memberName}');
    print('Args: ${invocation.positionalArguments}');
    return 'handled';
  }
}

void main() {
  dynamic log = Logger();
  var result = log.save('data', 123);
  print(result);  // handled
}

Bu teknik; proxy nesneleri, test için mock sınıfları oluşturmak veya rastgele metot çağrılarına yanıt veren esnek API'ler inşa etmek için yararlıdır. Ancak, derleme zamanı tür denetimini (compile-time type checking) atladığı için bunu idareli kullanın.

challenge icon

Görev

Kolay

Bir nesne üzerinde yapılan tüm metot çağrılarını yakalayan ve kaydeden bir metot günlüğü (logger) oluşturalım! Tanımlanmamış metot çağrıları hakkında bilgi toplamak ve metot adına göre akıllıca yanıt vermek için noSuchMethod() kullanan bir sınıf oluşturacaksınız.

Kodunuzu iki dosyada organize edeceksiniz:

  • method_logger.dart: Tanımlanmamış metotlara yapılan çağrıları yakalayan bir MethodLogger sınıfı oluşturun. Günlüğünüz (logger), şunları yapmak için noSuchMethod() metodunu geçersiz kılmalıdır (override):
    • Çağrıdan (invocation) metot adını çıkarın (bu, Symbol("methodName") gibi bir Symbol olacaktır - bunu bir dizeye dönüştürmeniz ve sadece adı çıkarmanız gerekecektir)
    • Metot adını ve varsa konumsal argümanları şu formatta yazdırın: Called: [methodName] with args: [arguments]
    • Metot adına göre özel bir yanıt döndürün:
      • Eğer metot adı get içeriyorsa, 'data retrieved' dizesini döndürün
      • Eğer metot adı save içeriyorsa, 'data saved' dizesini döndürün
      • Aksi takdirde, 'unknown action' dizesini döndürün
  • main.dart: Günlüğünüzü içe aktarın ve çeşitli tanımlanmamış metot çağrılarını nasıl işlediğini gösterin. Dart'ın var olmayan metotları çağırmaya izin vermesi için dynamic tipleme kullanmayı unutmayın:
    • Dinamik bir değişken kullanarak bir MethodLogger örneği oluşturun
    • Üzerinde getUserData('Alice', 42) metodunu çağırın ve dönen sonucu yazdırın
    • Üzerinde saveRecord('important') metodunu çağırın ve dönen sonucu yazdırın
    • Üzerinde processItem() metodunu çağırın (argüman olmadan) ve dönen sonucu yazdırın

Bir Symbol'den metot adını çıkarmak için, onu bir dizeye dönüştürebilir ve ardından tırnak işaretleri arasındaki adı ayıklayabilirsiniz. Örneğin, Symbol("myMethod").toString() size 'Symbol("myMethod")' sonucunu verir.

Beklenen çıktı:

Called: getUserData with args: [Alice, 42]
data retrieved
Called: saveRecord with args: [important]
data saved
Called: processItem with args: []
unknown action

Kendin dene

import 'method_logger.dart';

void main() {
  // TODO: Dinamik tipleme kullanarak bir MethodLogger örneği oluşturun
  // dynamic kullanmak, derleme zamanında mevcut olmayan metotların çağrılmasına olanak tanır
  dynamic logger;
  
  // TODO: getUserData('Alice', 42) metodunu çağırın ve sonucu yazdırın
  
  // TODO: saveRecord('important') metodunu çağırın ve sonucu yazdırın
  
  // TODO: processItem() metodunu argüman olmadan çağırın ve sonucu yazdırın
  
}
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