Menu
Coddy logo textTech

הרחבה באמצעות contains

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

contains = "Animal" הופך מחלקת S4 חדשה לתת־מחלקה של Animal. לתת־המחלקה יש את כל המשבצות של מחלקת־האב שלה, וגם משבצות משלה, ו־new() מקבלת את כולן:

setClass("Animal", slots = c(name = "character", age = "numeric"))
setClass("Dog", contains = "Animal", slots = c(breed = "character"))
rex <- new("Dog", name = "Rex", age = 3, breed = "collie")
print(slotNames("Dog"))
cat(rex@name, rex@breed)

פלט:

[1] "breed" "name"  "age"  
Rex collie

מתודות שנכתבו למחלקת האב פועלות גם עבור מחלקת הבן. כשאין לגנרית מתודה עבור Dog, S4 משתמשת בזו של Animal:

setClass("Animal", slots = c(name = "character"))
setClass("Dog", contains = "Animal")
invisible(setGeneric("intro", function(a) standardGeneric("intro")))
setMethod("intro", "Animal", function(a) paste("I am", a@name))
print(intro(new("Dog", name = "Rex")))

פלט:

[1] "I am Rex"

מחלקת בת דורסה שיטה של מחלקת האב על ידי הגדרת שיטה משלה עבור אותו גנרי. המחלקה הספציפית ביותר היא הקובעת, ותתי־המחלקות האחרות ממשיכות להשתמש בשיטה של מחלקת האב:

setClass("Animal", slots = c(name = "character"))
setClass("Dog", contains = "Animal")
setClass("Cat", contains = "Animal")
invisible(setGeneric("sound", function(a) standardGeneric("sound")))
setMethod("sound", "Animal", function(a) "...")
setMethod("sound", "Dog", function(a) "woof")
cat(sound(new("Dog", name = "Rex")), sound(new("Cat", name = "Tom")))

פלט:

woof ...

is(x, "Animal") מחזיר TRUE עבור כלב, ומשבצת שהוכרזה כ-"Animal" מקבלת Dog. קוד שנכתב עבור מחלקת האב עובד עם כל תת-מחלקה:

setClass("Animal", slots = c(name = "character"))
setClass("Dog", contains = "Animal")
setClass("Owner", slots = c(pet = "Animal"))
rex <- new("Dog", name = "Rex")
o <- new("Owner", pet = rex)
cat(is(rex, "Animal"), is(o@pet, "Dog"))

פלט:

TRUE TRUE
challenge icon

אתגר

קל

עובדים ומנהלים הם מחלקות S4 בשני קבצים. Employee.R מצהיר על Employee (המשבצות name, salary) ועל הגנרית describe(), ונדרשת מתודה עבור Employee שמחזירה Bo earns 40000. ב־Manager.R יש להצהיר על Manager, שמכיל את Employee ומוסיף את המשבצת reports (מספרית), ולדרוס את describe() כך שתחזיר Ada earns 60000 and manages 4.

הקוד שסופק קורא שורות employee Bo 40000 או manager Ada 60000 4 ומדפיס את describe(), האם האובייקט הוא עובד, ואת המשבצות שלו.

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

נסו בעצמכם

source("Employee.R")
source("Manager.R")

# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  x <- if (p[1] == "manager") {
    new("Manager", name = p[2], salary = as.numeric(p[3]), reports = as.numeric(p[4]))
  } else {
    new("Employee", name = p[2], salary = as.numeric(p[3]))
  }
  cat(describe(x), "\n", sep = "")
  cat("is an employee: ", is(x, "Employee"), ", slots: ", paste(slotNames(x), collapse = ", "), "\n", sep = "")
}
quiz iconבחנו את עצמכם

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

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

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