Aplikasi kasir dapat menerima pembayaran lewat transfer bank, e-wallet, dan metode lain yang baru hadir bertahun-tahun kemudian. Setiap metode punya cara kerja berbeda, tetapi semuanya harus menjamin satu kemampuan yang sama: memproses pembayaran dengan jumlah tertentu. Interface menyatakan jaminan itu sebagai kontrak perilaku, tanpa mengatur bagaimana kontrak tersebut diisi.

Mendefinisikan Interface #

Deklarasi interface memakai kata kunci interface, dan secara konvensi namanya diawali huruf I:

csharp
public interface IPembayaran
{
    void ProsesPembayaran(int jumlah);
}

Isi interface pada tingkat dasar hanya berupa daftar member tanpa badan. Member interface secara implisit bersifat publik, sehingga kita tidak menulis access modifier di dalamnya. Interface juga tidak boleh memiliki field.

Implementasi pada Class #

Class menyatakan implementasi dengan tanda titik dua, sama seperti pewarisan, lalu mengisi seluruh member kontrak:

csharp
public class TransferBank : IPembayaran
{
    public void ProsesPembayaran(int jumlah)
    {
        Console.WriteLine($"Transfer bank sebesar Rp{jumlah} berhasil diproses.");
    }
}

public class EWallet : IPembayaran
{
    public void ProsesPembayaran(int jumlah)
    {
        Console.WriteLine($"E-Wallet sebesar Rp{jumlah} berhasil didebit.");
    }
}

List<IPembayaran> metodePembayaran = new List<IPembayaran>
{
    new TransferBank(),
    new EWallet()
};

foreach (IPembayaran metode in metodePembayaran)
{
    metode.ProsesPembayaran(150000);
}

Output yang Dihasilkan:

text
Transfer bank sebesar Rp150000 berhasil diproses.
E-Wallet sebesar Rp150000 berhasil didebit.

Mari kita bedah baris demi baris:

  1. public interface IPembayaran: Kontrak ini menjanjikan satu kemampuan, yaitu ProsesPembayaran(int jumlah), tanpa menyebut cara kerjanya.
  2. class TransferBank : IPembayaran: Compiler memeriksa bahwa TransferBank mengisi seluruh member kontrak; bila ada yang kurang, program gagal dikompilasi.
  3. class EWallet : IPembayaran: Kontrak yang sama diisi dengan implementasi yang berbeda.
  4. List<IPembayaran>: Daftar bertipe interface menampung object dari class mana pun yang mengimplementasikan kontrak tersebut.
  5. metode.ProsesPembayaran(150000): Pemanggilan lewat tipe interface berjalan seperti polymorphism: setiap object menjalankan versinya sendiri.

Berikut perbedaan pokok abstract class dan interface pada tingkat dasar:

AspekAbstract ClassInterface
Isi memberBoleh member konkret dan fieldHanya deklarasi tanpa badan
Batasan pewarisanSatu base class sajaSatu class boleh mengimplementasikan banyak interface
Relasi yang dinyatakan“adalah” (is-a)“mampu” (can-do)

Tiga hal berikut menegaskan cara kerja implementasi di atas:

  • Satu class boleh mengimplementasikan lebih dari satu interface sekaligus, cukup dipisahkan koma setelah tanda titik dua.
  • Implementasi boleh berasal dari class yang tidak saling berhubungan; TransferBank dan EWallet tidak mewarisi class yang sama, tetapi keduanya menepati kontrak yang sama.
  • Object hasil implementasi dapat disimpan dalam variable bertipe interface-nya, seperti elemen List<IPembayaran> pada contoh.

Dengan interface, kode kasir hanya bergantung pada kontrak IPembayaran, sehingga metode pembayaran baru dapat ditambahkan tanpa mengubah kode pemanggil.