Slot và quyền truy cập
Thuộc phần Lập trình hướng đối tượng trong hành trình R của Coddy. Bài học 23 trên 57.
obj@slot <- value thay đổi một slot. Giống như đối tượng S3, đối tượng S4 là các giá trị: hàm thay đổi một đối tượng sẽ thao tác trên bản sao riêng và trả về bản sao đó:
setClass("Person", slots = c(name = "character", age = "numeric"))
birthday <- function(p) {
p@age <- p@age + 1
p
}
ada <- new("Person", name = "Ada", age = 36)
older <- birthday(ada)
cat(ada@age, older@age)Đầu ra:
36 37slot(obj, "name") làm tương tự như @ với tên slot dưới dạng chuỗi, nên nó hoạt động với tên được lưu trong một biến. slotNames() liệt kê các slot của một lớp hoặc đối tượng:
setClass("Person", slots = c(name = "character", age = "numeric"))
ada <- new("Person", name = "Ada", age = 36)
for (s in slotNames(ada)) cat(s, "=", format(slot(ada, s)), "\n")
slot(ada, "age") <- 37
print(ada@age)Đầu ra:
name = Ada
age = 36
[1] 37Mỗi phép gán đều được kiểm tra theo kiểu đã khai báo, không chỉ new(). Giá trị không đúng kiểu sẽ bị từ chối và đối tượng giữ nguyên giá trị cũ:
setClass("Person", slots = c(name = "character", age = "numeric"))
ada <- new("Person", name = "Ada", age = 36)
ada@age <- "old"Đầu ra:
Error in (function (cl, name, valueClass) :
assignment of an object of class “character” is not valid for @‘age’ in an object of class “Person”; is(value, "numeric") is not TRUE
Execution haltedgetSlots() trả về tên của tất cả các slot cùng với kiểu dữ liệu đã khai báo, nhờ đó code có thể chuyển đầu vào dạng văn bản sang kiểu dữ liệu mà slot yêu cầu:
setClass("Person", slots = c(name = "character", age = "numeric"))
types <- getSlots("Person")
print(types)
value <- "40"
if (types[["age"]] == "numeric") value <- as.numeric(value)
print(value + 1)Đầu ra:
name age
"character" "numeric"
[1] 41Thử thách
DễLớp Profile trong Profile.R có các slot name và city (ký tự), cùng với age (số). Hoàn thành hai hàm:
update_profile(p, field, value)dừng vớino field email(dùngcall. = FALSE) khi trường không phải là slot; nếu không, hàm chuyển đổi văn bảnvaluebằngas.numeric()khi slot có kiểu số, đặt slot bằngslot()và trả về hồ sơ đã thay đổi.profile_lines(p)trả về một dòng cho mỗi slot, theo thứ tự của các slot:name: Ada.
Code được cung cấp đọc tên, rồi đọc các dòng như city=Paris hoặc age=36, áp dụng từng dòng và in ra các dòng của hồ sơ.
Code của bạn nằm trong Profile.R. main.R chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.
Tự làm thử
source("Profile.R")
# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
p <- new("Profile", name = input[1], city = "unknown", age = 0)
for (line in input[-1]) {
kv <- strsplit(line, "=")[[1]]
p <- tryCatch(update_profile(p, kv[1], kv[2]), error = function(e) {
cat("error: ", conditionMessage(e), "\n", sep = "")
p
})
}
for (l in profile_lines(p)) cat(l, "\n", sep = "")
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Kiến thức cơ bản về S3
Làm việc với tệpDanh sách với một lớpHàm khởi tạoPhương thức in ra và định dạngTrình xác thực và hàm hỗ trợÔn tập: nhiệt độ4Tính đóng gói trong R
Closure dưới dạng đối tượngMôi trường dưới dạng đối tượngHàm truy cậpBảo vệ trạng tháiÔn tập: đồng hồ tính phí đỗ xe2S3, hàm generic và phương thức
Hàm generic và UseMethodPhương thức mặc địnhPhương thức cho hàm generic cơ sởCơ bản về NextMethodÔn tập: diện tích hình5Các lớp S4
Định nghĩa lớp S4Slot và quyền truy cậpKiểm tra tính hợp lệPhương thức showÔn tập: Danh mục sản phẩmTự luyện tập: Trình biên dịch R online