הרחבה באמצעות 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אתגר
קלעובדים ומנהלים הם מחלקות 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 = "")
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות S3
עבודה עם קבציםרשימות עם מחלקהפונקציות בנאימתודות print ו-formatמאמתים ופונקציות עזרחזרה – טמפרטורות7ירושה ב-S4
הרחבה באמצעות containscallNextMethodמחלקות וירטואליותבדיקת טיפוסים באמצעות is()סיכום – שומר גן החיותתרגלו בעצמכם: קומפיילר R אונליין