S3和S4似乎是面向對象編程的官方(即內置)方法。我已經開始使用S3與嵌入在構造函數/方法中的函數的組合。我的目標是有一個對象$ method()類型的語法,以便我有半私人領域。我說半私密,因爲沒有辦法真正隱藏它們(據我所知)。下面是一個簡單的例子,實際上並沒有做任何事情:
#' 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=''))
}
和一些測試代碼:
test <- EmailClass(name="Jason", "[email protected]")
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("[email protected]")
test$getHistory()
test$sendMail("[email protected]")
test$getNumMessagesSent()
test2 <- EmailClass("Nobody", "[email protected]")
test2
test2$props
test2$getHistory()
test2$sendMail('[email protected]')
這裏是一個博客帖子我寫的這個做法的鏈接:http://bryer.org/2012/object-oriented-programming-in-r我歡迎評論,批評和建議,因爲如果這是最好的方法,我不相信自己。但是,對於我試圖解決的問題,它效果很好。特別是,對於makeR軟件包(http://jbryer.github.com/makeR),我不希望用戶直接更改數據字段,因爲我需要確保表示對象狀態的XML文件保持同步。只要用戶遵守我在文檔中概述的規則,就可以很好地工作。
參考資料上的信息:http://stackoverflow.com/questions/5137199/what-is-the-significance-of-the-new-reference-classes – 2012-03-01 18:29:07
謝謝,你能重新發布鏈接作爲答案嗎?如果你可以包含什麼參考類的小概要,以及爲什麼他們更喜歡S3/S4類,那將會很好。 – 2012-03-01 18:34:19
一隻小鳥在我耳邊低聲說約翰錢伯斯即將出版一本書。但不要告訴任何人我說過的話; ;-) – 2012-03-01 18:41:53