S3 và S4 dường như là cách tiếp cận chính thức (nghĩa là tích hợp sẵn) cho lập trình OO. Tôi đã bắt đầu sử dụng kết hợp S3 với các hàm được nhúng trong hàm / phương thức của hàm tạo. Mục tiêu của tôi là có một cú pháp kiểu đối tượng $ method () để tôi có các trường bán riêng. Tôi nói bán riêng vì không có cách nào thực sự che giấu chúng (theo như tôi biết). Đây là một ví dụ đơn giản không thực sự làm gì cả:
#' Constructor
EmailClass <- function(name, email) {
nc = list(
name = name,
email = email,
get = function(x) nc[[x]],
set = function(x, value) nc[[x]] <<- value,
props = list(),
history = list(),
getHistory = function() return(nc$history),
getNumMessagesSent = function() return(length(nc$history))
)
#Add a few more methods
nc$sendMail = function(to) {
cat(paste("Sending mail to", to, 'from', nc$email))
h <- nc$history
h[[(length(h)+1)]] <- list(to=to, timestamp=Sys.time())
assign('history', h, envir=nc)
}
nc$addProp = function(name, value) {
p <- nc$props
p[[name]] <- value
assign('props', p, envir=nc)
}
nc <- list2env(nc)
class(nc) <- "EmailClass"
return(nc)
}
#' Define S3 generic method for the print function.
print.EmailClass <- function(x) {
if(class(x) != "EmailClass") stop();
cat(paste(x$get("name"), "'s email address is ", x$get("email"), sep=''))
}
Và một số mã kiểm tra:
test <- EmailClass(name="Jason", "jason@bryer.org")
test$addProp('hello', 'world')
test$props
test
class(test)
str(test)
test$get("name")
test$get("email")
test$set("name", "Heather")
test$get("name")
test
test$sendMail("jbryer@excelsior.edu")
test$getHistory()
test$sendMail("test@domain.edu")
test$getNumMessagesSent()
test2 <- EmailClass("Nobody", "dontemailme@nowhere.com")
test2
test2$props
test2$getHistory()
test2$sendMail('nobody@exclesior.edu')
Đây là một liên kết đến một bài đăng trên blog mà tôi đã viết về cách tiếp cận này: http://bowder.org/2012/object-oriented-programming-in-r Tôi sẽ hoan nghênh các bình luận, phê bình và đề xuất cho phương pháp này vì tôi không bị thuyết phục bản thân tôi nếu đây là cách tiếp cận tốt nhất. Tuy nhiên, đối với vấn đề tôi đã cố gắng giải quyết nó đã hoạt động rất tốt. Cụ thể, đối với gói makeR ( http://jbowder.github.com/makeR ) Tôi không muốn người dùng thay đổi trực tiếp các trường dữ liệu vì tôi cần đảm bảo rằng tệp XML đại diện cho trạng thái đối tượng của tôi sẽ được đồng bộ hóa. Điều này hoạt động hoàn hảo miễn là người dùng tuân thủ các quy tắc tôi phác thảo trong tài liệu.
Thông tin về các lớp tham khảo: stackoverflow.com/questions/5137199/ từ
– Dương Quỳnh Trang 18:29:07 01/03/2012Cảm ơn, bạn có thể đăng lại liên kết như câu trả lời? Sẽ thật tuyệt nếu bạn có thể bao gồm một bản tóm tắt nhỏ về các lớp Tham chiếu là gì và tại sao chúng thích hợp hơn so với các lớp S3 / S4.
– Huỳnh Tuyết Hương 18:34:19 01/03/2012Một con chim nhỏ thì thầm vào tai tôi rằng một cuốn sách về điều này sẽ được gửi bởi John Chambers. Nhưng đừng nói với bất cứ ai tôi đã nói rằng ... ;-)
– Ngô Mai Khanh 18:41:53 01/03/2012Có thể cùng một chú chim nhỏ đó dán một câu trả lời dưới đây với một số thông tin thêm về các lớp Refenence;)
– Phan Thiên Khánh 18:43:16 01/03/2012