Polimorfik İterasyon
Coddy'nin C Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 42 / 61.
Arayüzler oluşturmayı ve bunları farklı somut işlevlerle uygulamayı öğrendiniz. Asıl kazanım, farklı nesnelerden oluşan bir koleksiyonu tekdüze bir şekilde ele alabildiğinizde ortaya çıkar: Belirli olarak hangi davranışın bağlandığından bağımsız olarak, bunlar arasında yineleme yapabilir ve her biri üzerinde aynı işlev işaretçisini çağırabilirsiniz.
Her birine kendi execute işlevi atanmış Action yapılarından oluşan bir diziniz olduğunu düşünün:
typedef void (*ExecuteFunc)(void);
typedef struct {
const char* name;
ExecuteFunc execute;
} Action;
void jump(void) { printf("Jumping!\n"); }
void run(void) { printf("Running!\n"); }
void rest(void) { printf("Resting...\n"); }Bu eylemlerden bir dizi oluşturabilir, her birini farklı bir işleve bağlayabilir ve ardından basit bir for döngüsüyle bunların arasında dönebilirsin:
int main() {
Action actions[3] = {
{ "Jump", jump },
{ "Run", run },
{ "Rest", rest }
};
for (int i = 0; i < 3; i++) {
printf("%s: ", actions[i].name);
actions[i].execute();
}
return 0;
}Döngü, her bir eylemin dahili olarak ne yaptığını bilmez veya önemsemez. Yalnızca her öğe üzerinde execute() çağrısı yapar.
Bu, polimorfizmin iş başındaki hâlidir: aynı kod, tamamen farklı davranışlara sahip nesneleri işler. Yeni bir eylem türü eklemek, yineleme mantığında hiçbir değişiklik gerektirmez; diziye yalnızca bir öğe daha eklersiniz.
Görev
KolayFarklı davranışlar gerçekleştiren ancak ortak bir arayüzü paylaşan nesnelerden oluşan bir koleksiyonun işlenmesini gösteren polimorfik bir yineleme sistemi olan bir Task yönetim sistemi oluşturalım.
Kodunu üç dosyaya ayıracaksın:
task.h: Görev arayüzünü burada tanımla. Parametre almayan ve hiçbir şey döndürmeyenTaskFuncadlı bir işaretçi türü oluştur. Ardından birTask(name) veconst char*türünde birrunişlev işaretçisi içeren birTaskFuncyapısı tanımla.task.c: Farklı iş türlerini temsil eden üç farklı görev işlevi uygula:backup_task:Backing up data...yazdırırcleanup_task:Cleaning up files...yazdırırreport_task:Generating report...yazdırır
main.c: Her şeyi burada bir araya getir. Her biri farklı bir görev işlevine bağlanmışTaskyapılarından oluşan bir dizi oluştur. Ardından dizi üzerinde yineleme yap ve her görev için adını yazdırıprunişlevini çağırarak her görevi polimorfik biçimde çalıştır.
Programın tek bir girdi alacak: çalıştırılacak görev sayısı (1, 2 veya 3).
Şu sırada tam olarak üç görev içeren bir dizi oluştur: Backup adlı bir yedekleme görevi, Cleanup adlı bir temizleme görevi ve Report adlı bir rapor görevi. Girdi sayısına bağlı olarak dizinin başından başlayarak yalnızca bu kadar görev üzerinde yineleme yap.
Yinelemedeki her görev için görev adını, ardından iki nokta ve bir boşluk yazdır; sonra run işlevini çağır.
Girdi 2 olduğunda örnek çıktı:
Backup: Backing up data...
Cleanup: Cleaning up files...Girdi 3 olduğunda örnek çıktı:
Backup: Backing up data...
Cleanup: Cleaning up files...
Report: Generating report...Temel fikir, döngünün her görevin ne yaptığını bilmesine gerek olmamasıdır. Döngü yalnızca adı yazdırır ve her öğe üzerinde run() çağrısı yapar. Aynı yineleme kodu tüm görev türlerini aynı şekilde işler. Başlık dosyanda include korumaları kullanmayı unutma.
Kendin dene
#include <stdio.h>
#include "task.h"
// task.c'de uygulanan görev fonksiyonlarını bildir
void backup_task(void);
void cleanup_task(void);
void report_task(void);
int main() {
int count;
scanf("%d", &count);
// TODO: Bu sırada 3 Task yapısından oluşan bir dizi oluştur:
// 1. backup_task kullanarak "Backup" adlı Yedekleme görevi
// 2. cleanup_task kullanarak "Cleanup" adlı Temizleme görevi
// 3. report_task kullanarak "Report" adlı Rapor görevi
// TODO: Diziden 'count' görevi üzerinde yinele
// Her görev için yazdır: "<name>: " sonra run fonksiyonunu çağır
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Modüler Programlama Temelleri
Başlık DosyalarıInclude Guard'larKaynak DosyalarıStatik FonksiyonlarÖzet: Modüler Hesap Makinesi4Kapsülleme
Opaque Pointer KavramıOpaque Struct TanımlamaGetter ve Setter MetotlarıSetter Metotlarında DoğrulamaÖzet: Gizli Kutu2Nesneler ve Metotlar
Nesne Olarak Struct'lar'Self' İşaretçisiConst Doğruluğuİşaretçi vs DeğerYardımcı MetotlarÖzet: Point Manager5Proje: Basit Banka Hesabı
Proje KurulumuHesabın Oluşturulması8Polimorfizm
Struct'larda Fonksiyon İşaretçileriMetotları Simüle EtmeArayüz KavramıArayüzleri UygulamaPolimorfik İterasyonÖzet: Greeter3Nesne Yaşam Döngüsü
Constructor DeseniDestructor DeseniStack İlklendirmeDerin KopyalamaÖzet: String Wrapper6Kompozisyon Yoluyla Kalıtım
Struct Gömmeİlk Üye KuralıÜst Üyelere ErişimUpcastingÖzet: Şekil HiyerarşisiKendi başına pratik yap: Online C derleyicisi