E-Wallet pada aplikasi kasir menanggung dua tanggung jawab: memproses pembayaran dan mengirim struk lewat email. Dua tanggung jawab itu dijanjikan oleh dua kontrak berbeda, yaitu IPembayaran dan IKirimEmail. C# memperbolehkan satu class menepati banyak kontrak sekaligus, dan bab ini menunjukkan caranya beserta akibatnya bagi pemanggil.

Mendeklarasikan Banyak Interface Sekaligus #

Daftar interface ditulis setelah tanda titik dua dan dipisahkan koma:

csharp
public class Ewallet : IPembayaran, IKirimEmail
{
    public int BiayaAdmin => 1000;

    public void ProsesPembayaran(int jumlah)
    {
        Console.WriteLine($"E-Wallet: pembayaran Rp{jumlah} didebit.");
    }

    public void Kirim(string tujuan, string isi)
    {
        Console.WriteLine($"Email ke {tujuan}: {isi}");
    }
}

Class Ewallet wajib mengisi gabungan member kedua kontrak: property BiayaAdmin dan method ProsesPembayaran dari IPembayaran, ditambah method Kirim dari IKirimEmail. Bila class juga mewarisi sebuah base class, nama base class ditulis paling awal sebelum daftar interface.

Pemisahan tanggung jawab ke dalam dua interface memberi manfaat nyata: class tetap satu unit yang koheren, sementara pemanggil yang hanya butuh satu kemampuan dapat menangani object lewat kontrak tersebut saja.

Satu Object, Dua Sudut Pandang Kontrak #

Object Ewallet yang sama dapat dilihat sebagai pembayaran atau sebagai pengirim email:

csharp
Ewallet dompet = new Ewallet();

IPembayaran pembayaran = dompet;
IKirimEmail notifikasi = dompet;

pembayaran.ProsesPembayaran(120000);
notifikasi.Kirim("[email protected]", "Struk pembayaran E-Wallet Rp120000.");

Console.WriteLine($"pembayaran dan notifikasi menunjuk object yang sama: {ReferenceEquals(pembayaran, notifikasi)}");

Output yang Dihasilkan:

text
E-Wallet: pembayaran Rp120000 didebit.
Email ke [email protected]: Struk pembayaran E-Wallet Rp120000.
pembayaran dan notifikasi menunjuk object yang sama: True

Mari kita bedah baris demi baris:

  1. IPembayaran pembayaran = dompet; — assignment berjalan tanpa cast karena Ewallet menepati kontrak IPembayaran.
  2. IKirimEmail notifikasi = dompet; — object yang sama dilihat melalui kontrak kedua; variabel baru tidak menyalin object, hanya menunjuk yang sama.
  3. pembayaran.ProsesPembayaran(120000) — melalui variabel ini, hanya member IPembayaran yang dapat dipanggil.
  4. ReferenceEquals(pembayaran, notifikasi) — hasil True membuktikan kedua variabel menunjuk satu object yang sama.
  5. notifikasi.Kirim(...) — member dari kontrak kedua dipanggil pada object yang sama tanpa cast maupun object tambahan.

Satu class dengan dua kemampuan; pemanggil bebas memakai sudut pandang kontrak yang dibutuhkan. Urutan penulisan interface pada deklarasi tidak memengaruhi perilaku program; compiler hanya menuntut seluruh member dari daftar tersebut terisi, dan pesan CS0535 dari bab sebelumnya akan muncul bila ada yang tertinggal.