Dziedziczenie, funkcje wirtualne

POOL pozwala na dziedziczenie klas. Oznacza to, że można zdefiniować klasę bazową (nadrzędną) - ogólny opis zbioru modeli żółwi oraz klasy potomne, używające klasy bazowej jako wzorca i doprecyzowujące szczegóły charakterystyczne dla danego modelu.

Klasy potomne mają dostęp do wszystkich funkcji i zmiennych klasy bazowej.

Klasy potomne mogą używać jednej, lub wielu klas bazowych, łącząc w ten sposób ich funkcjonalność.

Klasy potomne mogą zawierać nowe definicje funkcji z klas bazowych jeśli nie zmieniają liczby ich parametrów. Funkcje w POOL są wirtualne: jeśli w klasie bazowej są wywołania funkcji przedefiniowanych w klasie potomnej, żółw-obiekt zawsze używa definicji "najbliższej" dla swojej klasy w górę hierarchii klas.

Konstruktor żółwia klasy potomnej wykonuje najpierw konstruktory klas bazowych - w kolejności, w jakiej zostały zadeklarowane w instrukcjach use. Kolejność deklaracji klas bazowych określa ostateczny zestaw zmiennych i funkcji dostępnych w klasie potomnej.

Przykład 1:
Program ilustruje definicję klasy pochodnej dziedziczącej z klasy bazowej, kolejność wykonania konstruktorów żółwia-obiektu oraz dostępność funkcji i zmiennych w żółwiu klasy pochodnej.

to bazowa :x :y
  to get op :y end
  make "pub :x
  print "bazowa
end

to pochodna :x :y
  use bazowa :x :y
  to fn op :x + :y end
  print "pochodna
end

"t := (newt $pochodna 2 3) ;konstruktor klasy pochodnej
print get @ :t    ;wywołanie funkcji klasy bazowej
print fn @ :t     ;wywołanie funkcji klasy pochodnej
print :pub @ :t   ;zmienna publiczna klasy bazowej
;print :x @ :t    ;błąd: :x jest zmienną prywatną

Rezultat wykonania:

bazowa
pochodna
3
5
2

Przykład 2:
Program ilustruje zastosowanie funkcji wirtualnych. Klasa bazowa zawiera obsługę odświeżania rysunku krzywych parametrycznych. Funkcja onworldchanged jest wywoływana po każdej zmianie parametrów rysowania. Funkcja ta wywołuje prototyp funkcji rysuj, której implementacja znajduje się w klasach potomnych. Dzięki zastosowanej strukturze rozbudowa programu o kolejne rodzaje krzywych ogranicza się do utworzenia klasy zawierającej wyłącznie kod specyficzny dla nowego typu krzywej.

;klasa bazowa: zapewnia implementację funkcjonalności
;wspólnej dla wszystkich klas potomnych
to krzywa :c
  to rysuj ;prototyp funkcji rysującej:
  end      ; - implementacja w klasach pochodnych

  ;funkcja wspólna dla wszystkich klas - odmalowuje
  ;krzywą jeśli zmieniły się parametry wyświetlania
  to onworldchanged
    let "nx :pool_cfg,"scale_x
    let "ny :pool_cfg,"scale_y
    let "mx :pool_cfg,"center_x
    let "my :pool_cfg,"center_y
    if :sx <> :nx || :sy <> :ny || :cx <> :mx || :cy <> :my [
      (print :nx :ny :cx :cy)
      "sx := :nx "sy := :ny
      "cx := :mx "cy := :my
      rysuj     ; <--- wywołanie funkcji-prototypu
    ]
  end

  ;konstruktor krzywej zapamiętuje początkowe
  ;parametry: sklalę i pozycję środka ekranu
  let "sx :pool_cfg,"scale_x
  let "sy :pool_cfg,"scale_y
  let "cx :pool_cfg,"center_x
  let "cy :pool_cfg,"center_y

  setpc :c ;ustawienie koloru krzywej
end

;klasa potomna: krzywa Lissajous
to lissajous :s :a :b :c
  use krzywa :c
  to rysuj
    pu setxy 0 :s pd
    repeat 361 [
      let "x :s * sin :a * repcount
      let "y :s * cos :b * repcount
      setxy :x :y
    ]
  end
end

;klasa potomna: krzywa "motylkowa"
to motylkowa :s :c
  use krzywa :c
  to rysuj
    pu setxy 0 :s * (m_exp - 2) pd
    for [t 0 3600] [
      let "f :s * ((exp cos :t) -
        2 * (cos 4 * :t) -
        power sin :t/12 5)

      let "x :f * sin :t
      let "y :f * cos :t
      setxy :x :y
    ]
  end
end

ht
window
;konstruktory obiektów klas potomnych:
"l := (newt $lissajous 150 7 9 50)
"e := (newt $motylkowa 50 {80 0 30 40})
;początkowy rysunek:
rysuj @ :l
rysuj @ :e

Rezultat wykonania:
Rysunek krzywych; po każdej zmianie skali lub pozycji środka - program wypisuje nowe parametry wyświetlania.

Zobacz także:

use - deklaracja dziedziczenia z klasy bazowej

Żółw - obiekt
#, turtle - odczytaj żółwia

Funkcja jako wartość
$, func - odczytaj funkcję

Spis treści