Menu
Coddy logo textTech

Symulowanie metod

Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 39 z 61.

Wiesz już, jak umieścić wskaźnik na funkcję w strukturze. Prawdziwa moc tkwi w przypisywaniu różnych funkcji do różnych instancji tego samego typu struktury. W ten sposób symulujemy metody o różnym zachowaniu.

Rozważ strukturę reprezentującą działanie z możliwością dostosowania logiki:

typedef void (*ActionFunc)(void);

typedef struct {
    const char* name;
    ActionFunc execute;
} Action;

Podczas tworzenia instancji przypisujesz każdej z nich inną funkcję:

void say_hello(void) {
    printf("Hello!\n");
}

void say_goodbye(void) {
    printf("Goodbye!\n");
}

int main() {
    Action greet = { "Greet", say_hello };
    Action farewell = { "Farewell", say_goodbye };
    
    greet.execute();    // Wynik: Hello!
    farewell.execute(); // Wynik: Goodbye!
    return 0;
}

Zarówno greet, jak i farewell są tego samego typu (Action), a jednak wywołanie execute dla każdego z nich daje zupełnie inne rezultaty. Struktura nie tylko przechowuje dane. Przechowuje zachowanie, które różni się w zależności od instancji.

Ten wzorzec odzwierciedla sposób działania obiektów w innych językach: każdy obiekt może mieć własną implementację metody, mimo że obiekty te współdzielą ten sam interfejs.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system Speaker, który pokazuje, jak różne instancje tego samego typu struktury mogą zachowywać się zupełnie inaczej w zależności od tego, która funkcja zostanie do nich przypisana.

Utworzysz dwa pliki, aby uporządkować kod:

  • speaker.h: Zdefiniuj typ wskaźnika do funkcji o nazwie SpeakFunc, która nie przyjmuje parametrów i niczego nie zwraca. Następnie zdefiniuj strukturę Speaker zawierającą name (typu const char*) oraz wskaźnik do funkcji speak typu SpeakFunc.
  • main.c: Dołącz plik nagłówkowy i zaimplementuj trzy różne funkcje wydające dźwięki:
    • bark: wypisuje Woof!
    • meow: wypisuje Meow!
    • chirp: wypisuje Chirp!
    Następnie utwórz dwie instancje Speaker, każdą przypisaną do innej funkcji na podstawie danych wejściowych, i wywołaj ich metody speak, aby zobaczyć polimorficzne zachowanie w akcji.

Twój program otrzyma dwa wejścia: typ pierwszego głośnika (1 oznacza bark, 2 oznacza meow, 3 oznacza chirp) oraz typ drugiego głośnika (również 1, 2 lub 3).

Utwórz dwie instancje Speaker. Możesz nazwać je dowolnie (na przykład "Dog", "Cat", "Bird" lub po prostu "Speaker1", "Speaker2"). Przypisz każdą z nich do odpowiedniej funkcji na podstawie jej kodu wejściowego, a następnie wywołaj speak dla każdej instancji po kolei.

Przykładowe wyjście, gdy pierwszy typ to 1, a drugi typ to 2:

Woof!
Meow!

Przykładowe wyjście, gdy pierwszy typ to 3, a drugi typ to 3:

Chirp!
Chirp!

Najważniejsze jest to, że oba głośniki są tego samego typu Speaker, a mimo to generują różne wyjścia, ponieważ każdemu przypisano inną funkcję w polu speak. Pamiętaj, aby użyć strażników dołączania w pliku nagłówkowym.

Spróbuj swoich sił

#include <stdio.h>
#include "speaker.h"

// TODO: Zaimplementuj funkcję bark, która wypisuje "Woof!"

// TODO: Zaimplementuj funkcję meow, która wypisuje "Meow!"

// TODO: Zaimplementuj funkcję chirp, która wypisuje "Chirp!"

int main() {
    int type1, type2;
    scanf("%d", &type1);
    scanf("%d", &type2);
    
    // TODO: Utwórz dwie instancje Speaker
    
    // TODO: Przypisz funkcję speak pierwszej instancji Speaker na podstawie type1
    // (1 = bark, 2 = meow, 3 = chirp)
    
    // TODO: Przypisz funkcję speak drugiej instancji Speaker na podstawie type2
    // (1 = bark, 2 = meow, 3 = chirp)
    
    // TODO: Wywołaj speak kolejno dla każdej instancji Speaker
    
    return 0;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C online