Menu
CoddyTech

הגדרת מחלקות S4

חלק מהיחידה תכנות מונחה עצמים במסלול ה-R של Coddy. שיעור 22 מתוך 57.

S4 היא מערכת האובייקטים הפורמלית של R. setClass() מצהירה על מחלקה עם משבצות בעלות שמות ועל הטיפוס של כל אחת מהן, ו-new() יוצרת אובייקט. האופרטור @ קורא משבצת:

setClass("Person", slots = c(name = "character", age = "numeric"))
ada <- new("Person", name = "Ada", age = 36)
cat(ada@name, "is", ada@age)

פלט:

Ada is 36

setClass() מחזירה גם פונקציית יצירה. יש לשייך אותה לשם, בדרך כלל שם המחלקה, ולקרוא לה כמו לבנאי:

Person <- setClass("Person", slots = c(name = "character", age = "numeric"))
bo <- Person(name = "Bo", age = 7)
print(bo@age + 1)
print(is(bo, "Person"))

פלט:

[1] 8
[1] TRUE

בניגוד ל־S3, ‏R בודקת את המשבצות. משבצת לא מוכרת או ערך מהסוג הלא נכון גורמים ל־new() לעצור עם שגיאה, כך שלאובייקט S4 תמיד יש את המבנה שהמחלקה שלו מצהירה עליו:

setClass("Person", slots = c(name = "character", age = "numeric"))
p <- new("Person", name = "Cy", age = "ten")

פלט:

Error in validObject(.Object) : 
  invalid class “Person” object: invalid object for slot "age" in class "Person": got class "character", should be or extend class "numeric"
Calls: new -> initialize -> initialize -> validObject
Execution halted

משבצת שלא ניתנה לה ערך מקבלת ערך ריק מהסוג שלה, כגון character(0). prototype מגדיר במקום זאת ערכי ברירת מחדל ממשיים. קוד ישן יותר מצהיר על המשבצות באמצעות representation(), שפירושו זהה ל־slots:

setClass("Task", slots = c(title = "character", done = "logical"),
         prototype = list(done = FALSE))
setClass("Note", representation(text = "character"))
t <- new("Task", title = "Write report")
print(t@done)
print(length(new("Note")@text))

פלט:

[1] FALSE
[1] 0
challenge icon

אתגר

קל

הצהירו על מחלקת S4 בשם Book בקובץ Book.R עם שלושה שדות: title ו-author מסוג character, ו-pages מסוג numeric. לאחר מכן השלימו את book_label(b), שקוראת את השדות באמצעות @ ומחזירה את Dune by Frank Herbert (412 pages).

הקוד שסופק קורא שורות בפורמט title;author;pages, יוצר כל ספר באמצעות new("Book", ...), מדפיס את התווית שלו ולבסוף את שמות השדות של המחלקה.

כתבו את הקוד שלכם בקובץ Book.R. הקובץ main.R מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.

נסו בעצמכם

source("Book.R")

# קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, ";")[[1]]
  b <- new("Book", title = p[1], author = p[2], pages = as.numeric(p[3]))
  cat(book_label(b), "\n", sep = "")
}
cat("slots: ", paste(slotNames("Book"), collapse = ", "), "\n", sep = "")
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר R אונליין