Tracks
/
Factor
Factor
/
Übungen
/
Drachennachkommen
Drachennachkommen

Drachennachkommen

Lernübung

Einführung

Tupel können andere Tupel erweitern. TUPLE: child < parent slots ; deklariert eine Klasse, deren Instanzen auch Instanzen von parent sind: Sie erhalten die Slots des Elternteils zusätzlich zu ihren eigenen, und die Accessoren des Elternteils funktionieren auch für sie, ganz so, als wären sie direkt im Kind definiert worden.

USING: accessors ;

TUPLE: animal name age ;
TUPLE: dog < animal breed ;

"Rex" 4 "labrador" dog boa .
! => T{ dog { name "Rex" } { age 4 } { breed "labrador" } }

"Rex" 4 "labrador" dog boa name>> .   ! => "Rex"   (inherited accessor)

Slot-Reihenfolge bei boa

Der Konstruktor boa nimmt die Slots in der Reihenfolge ihrer Deklaration, Eltern zuerst. Für dog oben:

dog boa ( name age breed -- dog )

Ein Enkelkind puppy < dog mit zusätzlichem weeks wäre:

puppy boa ( name age breed weeks -- puppy )

Prädikat-Hierarchie

Jede Deklaration mit TUPLE: erzeugt ein Prädikat (name?). Bei Vererbung verschachteln sich die Prädikate: Jeder Nachkomme erfüllt die Prädikate seiner Vorfahren:

"Rex" 4 "labrador" dog boa
dup dog? .        ! => t
dup animal? .     ! => t

Umgekehrt gilt das nicht: Ein animal, das kein dog ist, erfüllt dog? nicht.

Ausblick

Auch generische Methoden (M:, die in generics behandelt werden) greifen die Hierarchie hinauf: Eine Methode für animal wird für jeden Nachkomme ausgeführt, sofern nicht eine spezifischere Überschreibung Vorrang hat. Das siehst du in boatswains-bilge gleich nach dieser Übung.

Anleitung

Eine Naturforscherin katalogisiert die Drachen, die rund um die Caldera leben. Sie teilen Merkmale miteinander: Jeder Drache hat einen Namen, eine Farbe und ein Alter. Doch sie sind auf ganz eigene Weise spezialisiert. Du baust einen kleinen Vererbungsbaum aus Drachenklassen und ein einzelnes Wort, das jeden Nachkommen altern lässt.

1. Die Drachenfamilie

Definiere den gesamten Vererbungsbaum der Tupelklassen von Anfang an (ihre Konstruktoren kommen in den Aufgaben, die folgen):

  • dragon mit den Slots name, color und age.
  • fire-dragon, eine Unterklasse von dragon, mit einem zusätzlichen Slot flame-temp.
  • ice-dragon, eine weitere Unterklasse von dragon, mit einem zusätzlichen Slot chill-temp.
  • volcano-dragon, eine Unterklasse von fire-dragon, mit einem zusätzlichen Slot lava-volume.

Dann gib dragon einen Konstruktor <dragon>.

"Falkor" "white" 100 <dragon> name>> .   ! => "Falkor"

2. Die Feuerspeier

Gib fire-dragon einen Konstruktor <fire-dragon>.

"Smaug" "red" 500 1200 <fire-dragon> flame-temp>> .   ! => 1200
"Smaug" "red" 500 1200 <fire-dragon> dragon? .        ! => t

3. Die Eisspeier

Gib ice-dragon einen Konstruktor <ice-dragon>.

"Frosty" "blue" 200 -40 <ice-dragon> chill-temp>> .   ! => -40
"Frosty" "blue" 200 -40 <ice-dragon> fire-dragon? .   ! => f   (siblings)

4. Die Vulkanbewohner

Gib volcano-dragon einen Konstruktor <volcano-dragon>.

"Vesuvius" "red" 1000 1500 99 <volcano-dragon> dragon? .       ! => t
"Vesuvius" "red" 1000 1500 99 <volcano-dragon> fire-dragon? .  ! => t

5. Jeden Drachen altern lassen

Definiere age-dragon so, dass es den Slot age jedes Drachen (oder Nachkommen) um eins erhöht. Es gibt nichts zurück.

"Falkor" "white" 100 <dragon> dup age-dragon age>> .   ! => 101

Dasselbe Wort sollte bei jedem Nachkommen funktionieren. Genau darum geht es bei dem gemeinsamen Zugriffswort.

Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Factor Exercism

Bereit, mit Drachennachkommen zu starten?

Melde dich bei Exercism an, um Factor mit 47 Konzepte163 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.