setClass
位於 methods
包(package)。 說明
創建一個類定義並返回一個生成器函數以從該類創建對象。典型的用法是這樣的:
myClass <- setClass("myClass", slots= ...., contains =....)
其中第一個參數是新類的名稱,如果提供,參數 slots=
和 contains=
指定新類和新類應繼承的現有類中的槽。對 setClass()
的調用通常可以在包的源代碼中找到;加載包時,該類將在包的命名空間中定義。用類名指定生成器函數對用戶來說很方便,但不是必需的。
用法
setClass(Class, representation, prototype, contains=character(),
validity, access, where, version, sealed, package,
S3methods = FALSE, slots)
參數
Class |
類的字符串名稱。 |
slots |
新類中插槽的名稱和類。該參數必須在調用中通過名稱 參數必須是帶有名稱屬性的向量,名稱是新類中插槽的名稱。向量的每個元素指定一個現有的類;相應的槽必須來自該類或其子類。通常,這是命名類的字符向量。向量的元素作為類表示對象也是合法的,如 作為限製情況,參數可以是未命名的字符向量;這些元素被視為插槽名稱,並且所有插槽都具有不受限製的類 |
contains |
一個向量,指定該類應繼承的現有類。新類將具有超類的所有槽,對這些槽的類具有相同的要求。該參數必須在調用中通過名稱 請參閱“虛擬類”部分了解特殊超類 |
prototype, where, validity, sealed, package |
這些論點目前是允許的,但或者它們不太可能有用,或者有首選的現代替代方案。
|
representation, access, version, S3methods |
所有這些參數從 3.0.0 版本開始已棄用R並且應該避免.
包含
|
值
一個適合從類創建對象的生成器函數會以不可見的方式返回。對此函數的調用會生成對該類的new
的調用。該調用采用任意數量的參數,這些參數將傳遞給初始化方法。如果沒有為該類或其超類之一定義 initialize
方法,則默認方法需要具有插槽之一名稱的命名參數和來自所包含的類之一的對象的未命名參數。
通常,為了編程清晰起見,生成器函數會被分配類的名稱。這不是必需的,類中的對象也可以直接從 new
生成。生成器函數的優點是調用稍微簡單和清晰,並且調用將包含類的包名稱(如果來自不同包的兩個類具有相同名稱,則消除任何歧義)。
如果該類是虛擬類,則嘗試從生成器或 new()
生成對象將導致錯誤。
基本用途:槽和繼承
除類名之外的兩個基本參數是 slots
和 contains
,它們定義顯式槽和繼承(超類)。這些參數一起定義了該類的對象中的所有信息;即所有槽的名稱以及每個槽所需的類。
類的名稱決定哪些方法直接應用於該類的對象。超類信息指定通過繼承間接應用哪些方法。方法選擇中的繼承請參見Methods_Details。
類定義中的槽將是由 slots
直接指定的所有槽和所有包含的類中的所有槽的並集。隻能有一個具有給定名稱的插槽。類可以覆蓋具有給定名稱的槽的定義,但前提是新指定的類是繼承類的子類。例如,如果包含的類有一個槽 a
和類 "ANY"
,則子類可以指定 a
和類 "numeric"
,但如果該槽的原始規範是類 "character"
,則新調用setClass
會產生錯誤。
不允許插槽名稱 "class"
和 "Class"
。還有其他具有特殊含義的插槽名稱;這些名稱以 "."
字符開頭。為了安全起見,您應該定義自己的所有插槽,其名稱以字母字符開頭。
一些繼承的類將被特殊對待——對象類型、S3 類和一些特殊情況——無論是直接繼承還是間接繼承。請參閱接下來的三節。
虛擬課程
存在無法為其創建實際對象的類,即虛擬類。
虛擬課堂最常見和最有用的形式是階級聯盟,在調用中定義的虛擬類setClassUnion()
而不是調用給setClass()
。此調用列出了會員聯合的子類擴展了新類。在簽名中使用類聯合編寫的方法可以與任何成員類中的對象一起使用。類聯合可以包含其定義被密封的成員類,包括基本類R數據類型。
當僅提供 Class
參數(無槽或超類)或當 contains=
參數包含特殊類名 "VIRTUAL"
時,對 setClass()
的調用也將創建一個虛擬類。
在後一種情況下,虛擬類可能包含槽來提供一些常見行為,而無需完全定義對象 - 請參閱類traceable
作為示例。請注意,"VIRTUAL"
不會延續到子類;包含虛擬類的類本身並不自動是虛擬的。
從對象類型繼承
除了包含其他 S4 類之外,類定義還可以包含 S3 類(請參閱下一節)或內置 R pseudo-class——其中一個R對象類型或特殊類型之一R偽類"matrix"
和"array"
。一個類最多可以直接或間接包含一種對象類型。當它出現時,包含的類確定該類的“data part”。這顯示為pseudo-slot,".Data"
和 可以被視為一個槽,但實際上確定該槽中對象的類型。
新類中的對象嘗試繼承所包含類型的內置行為。正常情況下R數據類型包括向量、函數和表達式,實現相對簡單。對於任何物體x
從課堂上,typeof(x)
將是包含的基本類型;和一個特殊的pseudo-slot,.Data
,將與相應的類別一起顯示。請參閱"numWithId"
下麵的例子。
類也可以繼承自 "vector"
、 "matrix"
或 "array"
。這些對象的數據部分可以是任何矢量數據類型。
對於不包含這些類型或類之一的任何類的對象, typeof(x)
將是 "S4"
。
一些R數據類型的行為不正常,因為它們是非本地引用或其他不重複的對象。示例包括對應於類的示例"environment"
,"externalptr"
, 和"name"
。這些不能是具有用戶定義類(S4 或 S3)的對象的類型,因為設置屬性會覆蓋所有上下文中的對象。可以通過將繼承的對象存儲在保留槽中的間接機製來定義從此類類型繼承的類,".xData"
。請參閱類的示例"stampedEnv"
以下。來自此類的對象確實不是有一個".Data"
pseudo-slot。
對於大多數計算,這些類的行為是透明的,就好像它們直接從異常類型繼承一樣。 S3 方法調度和相關的 as.
類型 ()
函數應該正常運行,但直接使用對象類型的代碼則不會。例如, as.environment(e1)
將按預期與 "stampedEnv"
類一起工作,但 typeof(e1)
是 "S4"
。
從S3類繼承
Old-style S3 類沒有正式定義。當對象的類屬性包含被視為類名的字符串時,對象就是“from”類。
將此類類與正式類和方法一起使用必然是一件有風險的事情,因為無法保證對象的內容或繼承方法的一致性。鑒於此,仍然可以定義一個從 S3 類繼承的類,前提是該類已注冊為舊類(請參閱 setOldClass
)。
從廣義上講,S3 和 S4 方法分派都嘗試在任一係統中對繼承表現得明智。給定一個 S4 對象,S3 方法調度和 inherits
函數應使用 S4 繼承信息。給定一個 S3 對象,S4 泛型函數將使用 S3 繼承調度 S4 方法,前提是已通過 setOldClass
聲明了繼承。有關詳細信息,請參閱setOldClass
和參考文獻的第 10.8 節。
課程和套餐
類定義通常屬於包(但也可以在全局環境中定義,通過評估命令行上或源自命令行的文件中的表達式)。相應的包名稱是類定義的一部分;也就是說,classRepresentation
對象的一部分保存該定義。因此,對於大多數用途來說,兩個具有相同名稱的類可以存在於不同的包中。
當在 setClass
調用中為槽或超類提供類名時,將從當前包的命名空間中查找相應的類定義,假設相關調用直接出現在包的源代碼中,因為它應該避免歧義。類定義必須已在此包中、包的DESCRIPTION
和NAMESPACE
文件的導入指令中或在方法包定義的基本類中定義。 (‘methods’ 包必須包含在任何使用 S4 方法和類的包的導入指令中,以滿足 "CMD check"
實用程序的要求。)
如果一個包從不同的包導入兩個同名的類,則 name
參數的 packageSlot
需要設置為特定類的包名稱。這種情況應該很少見。
例子
## A simple class with two slots
track <- setClass("track", slots = c(x="numeric", y="numeric"))
## an object from the class
t1 <- track(x = 1:10, y = 1:10 + rnorm(10))
## A class extending the previous, adding one more slot
trackCurve <- setClass("trackCurve",
slots = c(smooth = "numeric"),
contains = "track")
## an object containing a superclass object
t1s <- trackCurve(t1, smooth = 1:10)
## A class similar to "trackCurve", but with different structure
## allowing matrices for the "y" and "smooth" slots
setClass("trackMultiCurve",
slots = c(x="numeric", y="matrix", smooth="matrix"),
prototype = list(x=numeric(), y=matrix(0,0,0),
smooth= matrix(0,0,0)))
## A class that extends the built-in data type "numeric"
numWithId <- setClass("numWithId", slots = c(id = "character"),
contains = "numeric")
numWithId(1:3, id = "An Example")
## inherit from reference object of type "environment"
stampedEnv <- setClass("stampedEnv", contains = "environment",
slots = c(update = "POSIXct"))
setMethod("[[<-", c("stampedEnv", "character", "missing"),
function(x, i, j, ..., value) {
ev <- as(x, "environment")
ev[[i]] <- value #update the object in the environment
x@update <- Sys.time() # and the update time
x})
e1 <- stampedEnv(update = Sys.time())
e1[["noise"]] <- rnorm(10)
參考
Chambers, John M. (2016) Extending R, Chapman & Hall. (Chapters 9 and 10.)
也可以看看
Classes_Details
用於類的一般討論,Methods_Details
用於方法的類似討論,makeClassRepresentation
相關用法
- R setClassUnion 定義為其他類的聯合的類
- R setOldClass 注冊舊式 (S3) 類和繼承
- R setGroupGeneric 創建函數的組通用版本
- R setGeneric 創建函數的通用版本
- R setAs 將對象強製為類的方法
- R setMethod 創建並保存方法
- R setIs 顯式指定超類
- R setLoadActions 設置包加載操作
- R selectSuperClasses 類的超類(特定類型)
- R showMethods 顯示指定函數或類的所有方法
- R slot 正式類對象中的槽
- R show 顯示對象
- R as 強製對象屬於某個類
- R language-class 表示未評估語言對象的類
- R className 類名包含對應的包
- R BasicClasses 基本數據類型對應的類
- R callGeneric 從方法調用當前通用函數
- R findClass 查找類定義
- R ReferenceClasses 具有按引用處理的字段的對象(OOP 樣式)
- R MethodsList 方法列表對象
- R StructureClasses 基本結構對應的類
- R getMethod 獲取或測試方法的定義
- R S4groupGeneric S4組通用函數
- R methodUtilities 用於方法和 S-Plus 兼容性的實用函數
- R getClass 獲取類定義
注:本文由純淨天空篩選整理自R-devel大神的英文原創作品 Create a Class Definition。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。