Zastosowanie polimorfizmu
Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 47 z 61.
Wyzwanie
ŁatwyUdowodnijmy, że polimorfizm naprawdę działa, pisząc funkcję, która może przetwarzać dowolny kształt za pomocą wskaźnika bazowego Shape*, niezależnie od tego, czy jest to Circle, czy Rectangle.
Rozbudowując istniejące implementacje Circle i Rectangle, dodasz potężną abstrakcję: pojedynczą funkcję, która działa jednolicie z dowolnym typem kształtu.
Twój projekt będzie zawierał następujące pliki:
shape.h: bazowy interfejsShapez typamiDrawFunciAreaFunc.circle.hicircle.c: implementacja Circle z poprzedniej lekcji.rectangle.hirectangle.c: implementacja Rectangle z poprzedniej lekcji.shape.c: Zaimplementuj nową funkcję o nazwieprocess_shape, która przyjmuje wskaźnikShape*. Funkcja powinna wywołać funkcjędrawkształtu, a następnie jego funkcjęareai wypisać wynik z dokładnością do 2 miejsc po przecinku w formacieArea: X.XX.main.c: Zademonstruj działanie polimorfizmu. Wczytaj oznaczenie typu kształtu (cdla koła,rdla prostokąta), a następnie wymagane wymiary. Utwórz odpowiedni kształt, a następnie przekaż wskaźnik do osadzonego w nim elementuShapedo funkcjiprocess_shape. Ta sama funkcja obsługuje oba typy!
Twój program otrzyma jedno z następujących wejść:
c, a po nim wartość promienia, lubr, a po nim wartości szerokości i wysokości
Przykładowe wyjście, gdy dane wejściowe to c i 5.0:
Drawing Circle with radius: 5.00
Area: 78.54Przykładowe wyjście, gdy dane wejściowe to r, 4.0 i 3.0:
Drawing Rectangle with width: 4.00 and height: 3.00
Area: 12.00Cała sztuczka polega na tym, że process_shape nie wie, czy działa z Circle, czy z Rectangle. Zna tylko interfejs Shape. Rzutując osadzony element Shape konkretnego kształtu na Shape*, możesz przekazać dowolny typ kształtu do tej jednej funkcji. To właśnie polimorfizm: jedna funkcja, wiele zachowań zależnych od rzeczywistego typu obiektu.
Pamiętaj, aby zadeklarować process_shape w shape.h, tak aby można było wywołać ją z main.c.
Spróbuj swoich sił
#include <stdio.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
int main() {
// TODO: Wczytaj znak określający typ figury ('c' dla koła, 'r' dla prostokąta)
// TODO: Jeśli 'c', wczytaj promień, utwórz Circle i wywołaj process_shape, przekazując jego część bazową
// TODO: Jeśli 'r', wczytaj szerokość i wysokość, utwórz Rectangle i wywołaj process_shape, przekazując jego część bazową
return 0;
}
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania modularnego
Pliki nagłówkoweZabezpieczenia przed wielokrotnym dołączeniemPliki źródłoweFunkcje statycznePodsumowanie: kalkulator modularny4Enkapsulacja
Koncepcja niejawnych wskaźnikówDefiniowanie niejawnych strukturGettery i setteryWalidacja w setterachPowtórka: tajemnicze pudełko2Obiekty i metody
Struktury jako obiektyWskaźnik „self”Poprawność constWskaźnik czy wartośćMetody pomocniczePodsumowanie: menedżer punktów5Projekt: Proste konto bankowe
Konfiguracja projektuImplementacja konta8Polimorfizm
Wskaźniki do funkcji w strukturachSymulowanie metodKoncepcja interfejsuImplementowanie interfejsówIteracja polimorficznaPodsumowanie: Greeter11Wzorce projektowe w C
Wzorzec SingletonWzorzec fabrykiWzorzec iteratoraPodsumowanie: fabryka loggera3Cykl życia obiektu
Wzorzec konstruktoraWzorzec destruktoraInicjalizacja na stosieKopia głębokaPodsumowanie: klasa opakowująca ciąg znaków6Dziedziczenie przez kompozycję
Osadzanie strukturZasada pierwszego elementuDostęp do elementów klasy nadrzędnejKonwersja w górę hierarchiiPodsumowanie: hierarchia kształtów9Projekt: Rysownik kształtów
Przegląd projektuImplementacja kołaImplementacja prostokątaZastosowanie polimorfizmuKontener kształtówPoćwicz samodzielnie: Kompilator C online