Menu
Coddy logo textTech

הגדרת מחלקות הפניה

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

מחלקות ייחוס (RC) הן המערכת של R לאובייקטים שמשתנים במקום, כמו ב-Java או ב-Python. setRefClass() מצהירה על מחלקה עם שדות מטיפוסים מוגדרים ומחזירה מחולל; $new() יוצרת אובייקט, ו-$ קוראת ומשנה את השדות שלו:

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
a <- Account$new(owner = "Ada", balance = 100)
a$balance <- a$balance + 50
cat(a$owner, a$balance)

פלט:

Ada 150

אובייקט RC הוא הפניה, כמו סביבה. הקצאתו למשתנה אחר או העברתו לפונקציה אינן יוצרות עותק שלו, ולכן שינוי דרך כל שם הוא שינוי של אותו אובייקט:

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
pay_fee <- function(acc) acc$balance <- acc$balance - 5
a <- Account$new(owner = "Ada", balance = 100)
b <- a
b$balance <- 60
pay_fee(a)
cat(a$balance, b$balance)

פלט:

55 55

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

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
a <- Account$new(owner = "Ada", balance = 100)
msg <- tryCatch({ a$balance <- "lots"; "changed" }, error = function(e) conditionMessage(e))
cat(msg, "\n")
cat(a$balance, "\n")

פלט:

invalid assignment for reference class field ‘balance’, should be from class “numeric” or a subclass (was class “character”) 
100 

המחולל מתאר את המחלקה: Account$fields() מציגה את השדות ואת הטיפוסים שלהם. אובייקט שמודפס ללא מתודת show מציג את השדות שלו; שדה שלא ניתן לו ערך הוא ריק:

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
print(Account$fields())
Account$new(owner = "Bo")

פלט:

      owner     balance 
"character"   "numeric" 
Reference class object of class "Account"
Field "owner":
[1] "Bo"
Field "balance":
numeric(0)
challenge icon

אתגר

קל

הצהירו על מחלקת Reference מסוג Book בקובץ Book.R עם השדות title ו-author (מחרוזת) ו-pages (מספרי), והשאירו את הגנרטור בתוך Book. לאחר מכן כתבו את add_pages(book, n), שמוסיף את n למספר העמודים של הספר במקום ולא מחזירה ערך שימושי.

הקוד שסופק קורא את title;author;pages, יוצר את הספר, מעביר אותו למשתנה שני, מוסיף את המספרים הנותרים דרך השם השני הזה ומדפיס את הספר המקורי ואת שמות השדות.

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

נסו בעצמכם

source("Book.R")

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

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

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

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