Οι πλειάδες μπορούν να επεκτείνουν άλλες πλειάδες. Η δήλωση TUPLE: child < parent slots ; ορίζει μια κλάση της οποίας τα στιγμιότυπα είναι και στιγμιότυπα του parent: παίρνουν τα πεδία του γονέα επιπλέον των δικών τους, και οι μέθοδοι πρόσβασης του γονέα λειτουργούν κι αυτές πάνω τους, σαν να είχαν οριστεί στο παιδί.
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)
boa
Ο κατασκευαστής boa δέχεται τα πεδία με σειρά δήλωσης, πρώτα του γονέα. Για το dog παραπάνω:
dog boa ( name age breed -- dog )
Ένα εγγόνι, το puppy < dog που προσθέτει το weeks, θα ήταν:
puppy boa ( name age breed weeks -- puppy )
Κάθε δήλωση TUPLE: παράγει ένα κατηγόρημα (name?). Με την κληρονομικότητα τα κατηγορήματα είναι εμφωλευμένα: κάθε απόγονος ικανοποιεί τα κατηγορήματα των προγόνων του.
"Rex" 4 "labrador" dog boa
dup dog? . ! => t
dup animal? . ! => t
Το αντίστροφο δεν ισχύει: ένα animal που δεν είναι dog αποτυγχάνει στο dog?.
Οι γενικές μέθοδοι (M:, που διδάσκονται στα generics) εφαρμόζονται κι αυτές προς τα πάνω στην ιεραρχία: μια μέθοδος στο animal ενεργοποιείται για κάθε απόγονο, εκτός αν μια πιο εξειδικευμένη υπερκάλυψη έχει προτεραιότητα. Θα το δεις στο boatswains-bilge αμέσως μετά από αυτή την άσκηση.
Ένας φυσιοδίφης καταγράφει τους δράκους που ζουν γύρω από την καλντέρα. Μοιράζονται κάποια χαρακτηριστικά μεταξύ τους (κάθε δράκος έχει όνομα, χρώμα και ηλικία), αλλά ο καθένας εξειδικεύεται με τον δικό του ξεχωριστό τρόπο. Θα φτιάξεις ένα μικρό δέντρο κληρονομικότητας από κλάσεις δράκων και μία μόνο λέξη που γερνάει κάθε απόγονο.
Όρισε εξαρχής ολόκληρο το δέντρο κληρονομικότητας των κλάσεων-πλειάδων (οι κατασκευαστές τους έρχονται στις εργασίες που ακολουθούν):
dragon με πεδία name, color, age.fire-dragon, υποκλάση του dragon, που προσθέτει ένα πεδίο flame-temp.ice-dragon, άλλη μια υποκλάση του dragon, που προσθέτει ένα πεδίο chill-temp.volcano-dragon, υποκλάση του fire-dragon, που προσθέτει ένα πεδίο lava-volume.Έπειτα δώσε στο dragon έναν κατασκευαστή <dragon>.
"Falkor" "white" 100 <dragon> name>> . ! => "Falkor"
Δώσε στο fire-dragon έναν κατασκευαστή <fire-dragon>.
"Smaug" "red" 500 1200 <fire-dragon> flame-temp>> . ! => 1200
"Smaug" "red" 500 1200 <fire-dragon> dragon? . ! => t
Δώσε στο ice-dragon έναν κατασκευαστή <ice-dragon>.
"Frosty" "blue" 200 -40 <ice-dragon> chill-temp>> . ! => -40
"Frosty" "blue" 200 -40 <ice-dragon> fire-dragon? . ! => f (siblings)
Δώσε στο volcano-dragon έναν κατασκευαστή <volcano-dragon>.
"Vesuvius" "red" 1000 1500 99 <volcano-dragon> dragon? . ! => t
"Vesuvius" "red" 1000 1500 99 <volcano-dragon> fire-dragon? . ! => t
Όρισε το age-dragon ώστε να αυξάνει κατά ένα το πεδίο age κάθε δράκου (ή απογόνου). Δεν επιστρέφει τίποτα.
"Falkor" "white" 100 <dragon> dup age-dragon age>> . ! => 101
Η ίδια λέξη πρέπει να δουλεύει σε κάθε απόγονο: αυτό είναι όλο το νόημα του κοινού μηχανισμού πρόσβασης.
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Factor με 47 έννοιες163 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.