Mengimplementasikan Interface
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan C di Coddy. Pelajaran 41 dari 61.
Setelah memahami apa itu interface, yaitu struct yang hanya berisi pointer fungsi, sekarang saatnya membuat implementasi konkret yang memenuhi kontrak tersebut.
Ingat kembali antarmuka ILogger kita dari pelajaran sebelumnya:
typedef void (*LogFunc)(const char* message);
typedef struct {
LogFunc log;
} ILogger;Untuk mengimplementasikan interface ini, kita menulis fungsi sebenarnya yang sesuai dengan signature LogFunc, lalu membuat instance ILogger dengan menetapkan fungsi-fungsi tersebut:
void console_log(const char* message) {
printf("[CONSOLE] %s\n", message);
}
void file_log(const char* message) {
printf("[FILE] %s\n", message); // Mensimulasikan output file
}
ILogger create_console_logger() {
ILogger logger = { console_log };
return logger;
}
ILogger create_file_logger() {
ILogger logger = { file_log };
return logger;
}Setiap fungsi "constructor" mengembalikan ILogger dengan fungsi berbeda yang terhubung. Kode yang menggunakan logger ini tidak perlu mengetahui implementasi mana yang diterimanya:
void do_work(ILogger* logger) {
logger->log("Starting work...");
logger->log("Work complete!");
}
int main() {
ILogger console = create_console_logger();
ILogger file = create_file_logger();
do_work(&console); // Menggunakan console_log
do_work(&file); // Menggunakan file_log
return 0;
}Fungsi do_work sepenuhnya tidak terikat pada implementasi logging. Kamu bisa mengganti logger dengan bebas tanpa mengubah logika inti apa pun: itulah keunggulan pemrograman terhadap antarmuka.
Tantangan
MudahMari buat sistem INotifier yang menunjukkan bagaimana implementasi yang berbeda dapat memenuhi kontrak interface yang sama. Kamu akan membuat notifier konkret, yaitu EmailNotifier dan SMSNotifier, yang sama-sama mengikuti interface umum tetapi menghasilkan output yang berbeda.
Kamu akan mengatur kodemu dalam tiga file:
notifier.h: Definisikan interface di sini. Buat tipe pointer fungsi bernamaNotifyFuncyang menerima pesanconst char*dan tidak mengembalikan apa pun. Lalu, definisikan structINotifieryang hanya berisi pointer fungsinotifybertipe ini. Deklarasikan juga dua fungsi konstruktor:create_email_notifierdancreate_sms_notifier, yang masing-masing mengembalikanINotifierberdasarkan nilai.notifier.c: Implementasikan fungsi notifikasi konkret dan konstruktor di sini. Buat:email_notify: mencetak pesan dengan format:[EMAIL] messagesms_notify: mencetak pesan dengan format:[SMS] messagecreate_email_notifier: mengembalikanINotifieryang terhubung keemail_notifycreate_sms_notifier: mengembalikanINotifieryang terhubung kesms_notify
main.c: Satukan semuanya di sini. Baca tipe notifikasi dan pesan, buat notifier yang sesuai menggunakan fungsi konstruktor, lalu kirim notifikasi melalui interface.
Programmu akan menerima dua input: tipe notifikasi (1 untuk email, 2 untuk SMS) dan pesan yang akan dikirim.
Gunakan fungsi konstruktor untuk membuat notifier yang sesuai, lalu panggil notify melalui interface untuk menampilkan pesan.
Contoh output saat tipenya 1 dan pesannya Meeting at 3pm:
[EMAIL] Meeting at 3pmContoh output saat tipenya 2 dan pesannya Your code shipped:
[SMS] Your code shippedKeunggulan pola ini adalah main.c tidak perlu mengetahui cara kerja internal setiap notifier. Program cukup memanggil fungsi notify dari interface, lalu implementasi yang tepat akan dijalankan. Ingat untuk menggunakan include guard di file header-mu.
Coba sendiri
#include <stdio.h>
#include "notifier.h"
int main() {
int type;
char message[256];
// Baca jenis notifikasi (1 untuk email, 2 untuk SMS)
scanf("%d", &type);
getchar(); // buang karakter baris baru
// Baca pesan
fgets(message, sizeof(message), stdin);
// Hapus karakter baris baru di akhir jika ada
int len = 0;
while (message[len] != '\0') len++;
if (len > 0 && message[len-1] == '\n') message[len-1] = '\0';
// TODO: Buat notifier yang sesuai berdasarkan type
// Gunakan create_email_notifier() untuk type 1
// Gunakan create_sms_notifier() untuk type 2
// TODO: Panggil fungsi notify melalui antarmuka
// notifier.notify(message);
return 0;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar Pemrograman Modular
file headerProteksi includefile sumberFungsi StatisRingkasan: Kalkulator Modular4Enkapsulasi
Konsep Opaque PointerMendefinisikan Opaque StructGetter dan SetterValidasi pada SetterUlasan: Kotak Rahasia2Object dan method
Struct sebagai objectPointer 'self'Konsistensi constPointer vs nilaiMethod pembantuRangkuman: Pengelola Point5Proyek: Akun Bank Sederhana
Penyiapan ProyekImplementasi Akun8Polimorfisme
Pointer Fungsi dalam StructMensimulasikan methodKonsep InterfaceMengimplementasikan InterfaceIterasi PolimorfikUlasan: Greeter3Siklus Hidup object
Pola KonstruktorPola DestruktorInisialisasi StackSalinan MendalamRangkuman: Pembungkus string6Pewarisan melalui Komposisi
Penyematan StructAturan Anggota PertamaMengakses Anggota ParentUpcastingRekap: Hierarki Bentuk9Proyek: Penggambar Bentuk
Ringkasan ProyekImplementasi LingkaranImplementasi Persegi PanjangPenggunaan PolimorfismeWadah BentukLatihan sendiri: Compiler C online