Menu
CoddyTech

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

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

contains = "Animal" הופך מחלקת S4 חדשה לתת־מחלקה של Animal. לתת־המחלקה יש את כל ה־slots של מחלקת האב, בנוסף ל־slots משלה, ו־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 אונליין