Abstrakcja i polimorfizm
Troszkę się przeciągnęło, ale juz nadrabiam. Czwarty odcinek cyklu dotyczyć będzie dwóch cech programowania obiektowego: abstrakcji i polimorfizmu. Obie te cechy używane były już w przykładach do poprzednich odcinków, jednak tu je troszkę bardziej uwypuklę.Uważni czytelnicy zapewne pamietają konstruktor kopiujący, czy destruktor, których używamy od pierwszego odcinka. Są to właśnie przykłady polimorfizmu i abstrakcyjnego projektowania. Mamy obiekty oraz operujące na nich funkcje, które wywołują metody tych obiektów nie zwracając uwagi na to, co to jest za obiekt i jak zaimplementowana jest metoda. Istotne jest jedynie to, aby interfejs był taki sam. Aby jeszcze bardziej pokazać te cechy, lekko zmodyfikujmy przykład z poprzedniego odcinka.
do pliku mydefaultobj.h dodajmy funkcję:
void ShowObjectInfo(struct TDefaultObj *);która będzie miała za zadanie wyświetlenie informacji o obiekcie. Samą strukturę również proponuję zmodyfikować dodając dodatkową metodę:
ObjectDefaultShowInfo fooShowObjInfo;jak widzimy dodany został typ:
typedef void (*ObjectDefaultShowInfo)(struct TDefaultObj *);Samą funkcję zdefiniujemy w prosty sposób:
void ShowObjectInfo(struct TDefaultObj *aobj) { if (aobj) { if (aobj->fooShowObjInfo) { aobj->fooShowObjInfo(aobj); } else myprintdbg("ShowObjectInfo: brak zdefiniowanej metody fooShowObjInfo!"); } else myprintdbg("ShowObjectInfo: brak obiektu!!!!!"); }
Kolejne zmiany to usunięcie deklaracji funkcji wypisujących informacje o obiektach z plików: myintegerobj.h i mytextobj.h.
W plikach z definicjami adekwatnymi do wyżej wymienionych plików nagłówkowych dodajemy pole z metodą:
ObjectDefaultShowInfo fooShowObjInfo;oraz przypisujemy w konstruktorach metody wypisujące informacje o obiektach. Jak widać zostały one zmienione na funkcje typu static.
Na sam koniec zmieniamy funkcję main:
int main() { struct TDefaultObj *objarr[4]; int i; objarr[0] = (struct TDefaultObj *)CreateTextObj("Mój Text 1"); objarr[2] = (struct TDefaultObj *)CreateIntegerObj(7); objarr[1] = CloneDefaultObject(objarr[0]); objarr[3] = CloneDefaultObject(objarr[2]); SetTextObjValue((struct myTextObj *)objarr[1], "Mój Text 2"); SetIntegerObjValue((struct myIntegerObj *)objarr[3], 14); for (i = 0; i < 4; i++) ShowObjectInfo(objarr[i]); for (i = 0; i < 4; i++) FreeDefaultObject(objarr[i]); return 0; }Jak widać działa prawie tak samo jak poprzedni, a pewne rzeczy (wypisywanie informacji o obiektach, oraz wywołanie destruktorów) zostały zautomatyzowane. Zamiast zmiennych róznych typów mamy kolekcję typu wektor ze wskaźnikami na obiekt domyślny.
Wynik działania to:

Pełen kod przykładu jest jak zwykle do pobrania i do własnych testów.
Wnioski
Tak więc udało mi się wykazać, że w języku C możemy programować obiektowo. Pokazałem proste przykłady jak to robić. Na tym mógłbym zakończyć cykl, ale postanowiłem zrobić wiernym czytelnikom małą niespodziankę i za jakiś czas pojawi się jeszcze jeden odcinek tego cyklu.Pozdrawiam
Tomasz Kaczanowski
polimorfizm abstrakcja C programowanie obiektowe język C