Menu
CoddyTech

Override noSuchMethod

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Dart di Coddy. Pelajaran 74 dari 110.

Saat kamu memanggil method yang tidak ada pada object, Dart biasanya memunculkan NoSuchMethodError. Namun, kamu dapat meng-override method khusus noSuchMethod() untuk mencegat pemanggilan ini dan menanganinya dengan baik.

Untuk menggunakan noSuchMethod(), class-mu juga harus mengimplementasikan interface atau menggunakan pengetikan dynamic.

method menerima object Invocation yang berisi detail tentang pemanggilan yang dicoba:

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

void main() {
  dynamic obj = Flexible();
  obj.anyMethod();      // Dipanggil: Symbol("anyMethod")
  obj.anotherOne(42);   // Dipanggil: Symbol("anotherOne")
}

Object Invocation memberikan informasi berguna tentang pemanggilan, memberName memberikan nama method dalam bentuk Symbol, positionalArguments berisi argumen yang diberikan, dan isMethod memberitahumu apakah pemanggilan tersebut adalah pemanggilan method, bukan getter atau setter.

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
}

Teknik ini berguna untuk membuat object proxy, class tiruan untuk pengujian, atau membangun API fleksibel yang merespons pemanggilan method sembarang. Namun, gunakan teknik ini seperlunya karena teknik ini melewati pemeriksaan tipe saat kompilasi.

challenge icon

Tantangan

Mudah

Mari buat pencatat method yang mencegat dan mencatat setiap pemanggilan method pada sebuah object! Kamu akan membuat class yang menggunakan noSuchMethod() untuk menangkap informasi tentang pemanggilan method yang tidak didefinisikan dan merespons dengan tepat berdasarkan nama method.

Kamu akan mengatur kodemu ke dalam dua file:

  • method_logger.dart: Buat class MethodLogger yang mencegat pemanggilan method yang tidak didefinisikan. Logger-mu harus meng-override noSuchMethod() untuk:
    • Mengambil nama method dari pemanggilan (namanya berupa Symbol seperti Symbol("methodName"), kamu perlu mengubahnya menjadi string dan mengambil namanya saja)
    • Mencetak nama method dan argumen posisi apa pun dalam format ini: Called: [methodName] with args: [arguments]
    • Mengembalikan respons khusus berdasarkan nama method:
      • Jika nama method berisi get, kembalikan string 'data retrieved'
      • Jika nama method berisi save, kembalikan string 'data saved'
      • Jika tidak, kembalikan string 'unknown action'
  • main.dart: Impor logger-mu dan tunjukkan cara logger menangani berbagai pemanggilan method yang tidak didefinisikan. Ingat, gunakan tipe dynamic agar Dart mengizinkan pemanggilan method yang tidak ada:
    • Buat instance MethodLogger menggunakan variabel dynamic
    • Panggil getUserData('Alice', 42) pada instance itu dan cetak hasil yang dikembalikan
    • Panggil saveRecord('important') pada instance itu dan cetak hasil yang dikembalikan
    • Panggil processItem() pada instance itu tanpa argumen, lalu cetak hasil yang dikembalikan

Untuk mengambil nama method dari Symbol, kamu bisa mengubahnya menjadi string, lalu mengambil nama di antara tanda kutip. Misalnya, Symbol("myMethod").toString() menghasilkan 'Symbol("myMethod")'.

Output yang diharapkan:

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

Coba sendiri

import 'method_logger.dart';

void main() {
  // TODO: Buat instance MethodLogger menggunakan tipe dynamic
  // Penggunaan dynamic memungkinkanmu memanggil method yang belum ada saat compile
  dynamic logger;
  
  // TODO: Panggil getUserData('Alice', 42) dan cetak hasilnya
  
  // TODO: Panggil saveRecord('important') dan cetak hasilnya
  
  // TODO: Panggil processItem() tanpa argumen dan cetak hasilnya
  
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Dart online