«تاپل»ها میتوانند تاپلهای دیگر را گسترش دهند. دستور 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
همین واژه باید روی هر فرزندی کار کند؛ هدف اصلی از ساختن یک دسترسگر مشترک همین است.