Tuplas podem estender outras tuplas. TUPLE: child < parent slots ; declara uma classe cujas instâncias também são instâncias de parent: elas recebem as fendas do pai além das suas próprias, e os acessores do pai também funcionam nelas, como se tivessem sido definidos na classe filha.
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
O construtor boa recebe as fendas na ordem de declaração, com os pais primeiro. Para o dog acima:
dog boa ( name age breed -- dog )
Um neto puppy < dog que acrescentasse weeks ficaria assim:
puppy boa ( name age breed weeks -- puppy )
Toda declaração TUPLE: gera um predicado (name?). Com a herança, os predicados se aninham, ou seja, todo descendente satisfaz os predicados dos seus ancestrais:
"Rex" 4 "labrador" dog boa
dup dog? . ! => t
dup animal? . ! => t
O contrário não é verdade: um animal que não é um dog não passa no dog?.
Os métodos genéricos (M:, ensinados em generics) também despacham pela hierarquia: um método em animal é acionado para todo descendente, a menos que uma sobrescrita mais específica tenha prioridade. Você vai ver isso em boatswains-bilge logo depois deste exercício.
Um naturalista está catalogando os dragões que vivem ao redor da caldeira. Eles compartilham características entre si: todo dragão tem um nome, uma cor e uma idade, mas cada um se especializa de maneiras distintas. Você vai construir uma pequena árvore de herança de classes de dragão e uma única palavra que envelhece qualquer descendente.
Defina toda a árvore de herança de classes de tuplas desde o início (os construtores vêm nas tarefas a seguir):
dragon, com os campos name, color, age.fire-dragon, uma subclasse de dragon, que adiciona um campo flame-temp.ice-dragon, outra subclasse de dragon, que adiciona um campo chill-temp.volcano-dragon, uma subclasse de fire-dragon, que adiciona um
campo lava-volume.Depois, dê a dragon um construtor <dragon>.
"Falkor" "white" 100 <dragon> name>> . ! => "Falkor"
Dê a fire-dragon um construtor <fire-dragon>.
"Smaug" "red" 500 1200 <fire-dragon> flame-temp>> . ! => 1200
"Smaug" "red" 500 1200 <fire-dragon> dragon? . ! => t
Dê a ice-dragon um construtor <ice-dragon>.
"Frosty" "blue" 200 -40 <ice-dragon> chill-temp>> . ! => -40
"Frosty" "blue" 200 -40 <ice-dragon> fire-dragon? . ! => f (siblings)
Dê a volcano-dragon um construtor <volcano-dragon>.
"Vesuvius" "red" 1000 1500 99 <volcano-dragon> dragon? . ! => t
"Vesuvius" "red" 1000 1500 99 <volcano-dragon> fire-dragon? . ! => t
Defina age-dragon para incrementar em uma unidade o campo age de
qualquer dragão (ou descendente). Não retorna nada.
"Falkor" "white" 100 <dragon> dup age-dragon age>> . ! => 101
A mesma palavra deve funcionar em qualquer descendente. É exatamente esse o ponto do acessador compartilhado.
Crie sua conta no Exercism para aprender e dominar Factor com 47 conceitos163 exercícios e mentoria humana de verdade, tudo de graça.