Aplikasi kasir POS menerima permintaan cetak struk dari dua sumber: modul kasir yang menginginkan struk ringkas dan modul pajak yang mewajibkan struk memuat rincian pajak. Kedua modul dinyatakan sebagai interface, dan kebetulan keduanya mendeklarasikan method bernama CetakStruk(). Implementasi biasa hanya bisa menyediakan satu versi method dengan nama tersebut, padahal isi keduanya harus berbeda. Explicit interface implementation menyelesaikan konflik ini: class menyediakan satu implementasi terpisah untuk setiap interface, dan pemanggil memilih versi melalui tipe interface yang diinginkan.
Sintaks Implementasi Eksplisit #
Bentuk eksplisit menuliskan nama interface lengkap di depan nama member, misalnya void IKasir.CetakStruk(). Implementasi eksplisit tidak boleh diberi access modifier, karena member tersebut secara efektif hanya tersedia melalui reference bertipe interface-nya. Dua interface yang bertengkar nama pun menjadi berdamai tanpa perlu mengubah salah satu kontrak.
Contoh: Dua Struk dalam Satu Class #
public interface IKasir
{
void CetakStruk();
}
public interface IPenangananPajak
{
void CetakStruk();
}
public class AplikasiPos : IKasir, IPenangananPajak
{
void IKasir.CetakStruk()
{
Console.WriteLine("Struk kasir: ringkas, tanpa rincian pajak.");
}
void IPenangananPajak.CetakStruk()
{
Console.WriteLine("Struk pajak: memuat NPWP dan rincian pajak.");
}
}
AplikasiPos pos = new AplikasiPos();
IKasir kasir = pos;
kasir.CetakStruk();
IPenangananPajak penangananPajak = pos;
penangananPajak.CetakStruk();Output yang Dihasilkan:
Struk kasir: ringkas, tanpa rincian pajak.
Struk pajak: memuat NPWP dan rincian pajak.Mari kita bedah baris demi baris:
- Dua deklarasi
CetakStruk(): Kedua interface menyatakan member dengan nama dan signature sama; situasi ini sah selama implementasinya dipisahkan. void IKasir.CetakStruk(): Nama interface di depan nama method mengikat versi ini khusus untuk kontrakIKasir.void IPenangananPajak.CetakStruk(): Versi kedua terikat pada kontrakIPenangananPajak; kedua versi berdampingan di satu class tanpa bertabrakan.IKasir kasir = pos;lalukasir.CetakStruk(): Pemanggilan melalui tipeIKasirmenjalankan versi kasir, menghasilkan baris pertama output.IPenangananPajak penangananPajak = pos;lalupenangananPajak.CetakStruk(): Pemanggilan melalui tipeIPenangananPajakmenjalankan versi pajak; satu object, dua perilaku yang dipilih lewat tipe reference.
error CS1061: 'AplikasiPos' does not contain a definition for 'CetakStruk' and no accessible extension method 'CetakStruk' accepting a first argument of type 'AplikasiPos' could be found (are you missing a using directive or an assembly reference?)Pesan tersebut wajar: member eksplisit memang bukan bagian dari permukaan publik class, melainkan milik tiap kontrak interface. Batasan ini menjaga pemanggil selalu menyatakan niatnya, yakni struk mana yang ingin dicetak.
Explicit implementation juga menjadi tempat menaruh member kontrak yang jarang dipakai agar tidak mengotori permukaan class. Bab berikutnya menambahkan kemampuan lain pada interface: member yang sudah membawa implementasi bawaan.