Platform jasa pengiriman memproses paket melalui beberapa layanan: kurir reguler, kurir express, dan layanan baru yang hadir setiap tahun. Semua layanan wajib bisa mengantar paket, tetapi hanya sebagian yang menyediakan asuransi. Inheritance tunggal tidak muat untuk situasi ini, karena satu class tidak boleh mewarisi dua base class. Interface implementation menjawab kebutuhan tersebut: satu class dapat menepati banyak kontrak sekaligus, dan kode pemanggil memeriksa kontrak yang tersedia saat runtime.
Member Interface Lebih dari Method #
Selain method, interface boleh mendeklarasikan property. Property pada interface hanya menyatakan nama dan accessor-nya, misalnya { get; } untuk property baca-saja. Seluruh member interface secara implisit bersifat publik, sehingga implementasinya di class selalu ditulis public dan accessornya harus cocok dengan deklarasi kontrak.
Satu Class, Banyak Interface #
Class menyatakan kontrak yang ditepati dengan tanda titik dua, dan beberapa interface cukup dipisahkan koma. Deklarasi class KurirExpress : IPengiriman, IAsuransi berarti compiler memeriksa bahwa KurirExpress mengisi seluruh member milik kedua interface; satu member pun yang tertinggal menggagalkan kompilasi. Class juga boleh sekaligus mewarisi satu base class dan mengimplementasikan beberapa interface dalam deklarasi yang sama.
Contoh: Layanan Pengiriman #
public interface IPengiriman
{
string NomorResi { get; }
void Antar(string tujuan);
}
public interface IAsuransi
{
void TampilkanPremi();
}
public class KurirReguler : IPengiriman
{
public string NomorResi { get; }
public KurirReguler(string nomorResi)
{
NomorResi = nomorResi;
}
public void Antar(string tujuan)
{
Console.WriteLine($"Kurir reguler {NomorResi} mengantar paket ke {tujuan} dalam dua hari.");
}
}
public class KurirExpress : IPengiriman, IAsuransi
{
public string NomorResi { get; }
public KurirExpress(string nomorResi)
{
NomorResi = nomorResi;
}
public void Antar(string tujuan)
{
Console.WriteLine($"Kurir express {NomorResi} mengantar paket ke {tujuan} hari ini.");
}
public void TampilkanPremi()
{
Console.WriteLine("Premi asuransi Rp5000 per paket.");
}
}
IPengiriman pesananExpress = new KurirExpress("JNE123");
pesananExpress.Antar("Bandung");
if (pesananExpress is IAsuransi asuransi)
{
asuransi.TampilkanPremi();
}
IPengiriman pesananReguler = new KurirReguler("JNE456");
pesananReguler.Antar("Surabaya");
if (pesananReguler is IAsuransi asuransiReguler)
{
asuransiReguler.TampilkanPremi();
}
else
{
Console.WriteLine("Paket ini tidak dilindungi asuransi.");
}Output yang Dihasilkan:
Kurir express JNE123 mengantar paket ke Bandung hari ini.
Premi asuransi Rp5000 per paket.
Kurir reguler JNE456 mengantar paket ke Surabaya dalam dua hari.
Paket ini tidak dilindungi asuransi.Mari kita bedah baris demi baris:
string NomorResi { get; }: Interface mendeklarasikan property baca-saja, dan kedua class mengisinya lewat constructor tanpa membuka celah perubahan dari luar.class KurirExpress : IPengiriman, IAsuransi: Satu class menepati dua kontrak;KurirRegulerhanya menepatiIPengiriman, sehingga kemampuan keduanya memang berbeda.IPengiriman pesananExpress = new KurirExpress("JNE123"): Variable bertipe interface menampung object implementasi; kode di bawahnya tidak mengetahui class konkret sama sekali.pesananExpress is IAsuransi asuransi: Polaismemeriksa kemampuan saat runtime, lalu langsung meng-cast; pemeriksaan bernilaitrueuntukKurirExpressdanfalseuntukKurirReguler.- Blok
else: Jalur untuk object tanpa asuransi menunjukkan bahwa pemeriksaan kontrak membuat kode tetap aman untuk layanan yang kemampuannya berbeda-beda.