浏览Hadley Wickham的S4维基: https://github.com/hadley/devtools/wiki/S4
setClass("Person", representation(name = "character", age = "numeric"),
prototype(name = NA_character_, age = NA_real_))
hadley <- new("Person", name = "Hadley")
我们如何为Person设计构造函数(像这样)
Person<-function(name=NA,age=NA){
new("Person",name=name,age=age)
}
不这样做:
> Person()
Error in validObject(.Object) :
invalid class "Person" object: 1: invalid object for slot "name" in class "Person": got class "logical", should be or extend class "character"
invalid class "Person" object: 2: invalid object for slot "age" in class "Person": got class "logical", should be or extend class "numeric"
答案 0 :(得分:4)
在你的例子中看起来答案就在那里:
Person<-function(name=NA_character_,age=NA_real_){
new("Person",name=name,age=age)
}
产量
> Person()
An object of class "Person"
Slot "name":
[1] NA
Slot "age":
[1] NA
> Person("Moi")
An object of class "Person"
Slot "name":
[1] "Moi"
Slot "age":
[1] NA
> Person("Moi", 42)
An object of class "Person"
Slot "name":
[1] "Moi"
Slot "age":
[1] 42
然而,这是相当un-S4并且重复了在类定义中已经分配的默认值。也许你更愿意做
Person <- function(...) new("Person",...)
并且牺牲了没有命名参数的调用能力?
答案 1 :(得分:3)
我希望给最终用户一些关于参数类型的提示,而不是@themel使用...
的建议。同时放弃原型并使用length(x@name) == 0
作为字段未初始化的指示,使用People
类而不是Person
,反映R的向量化结构,并使用{{1在构造函数中,所以派生类也可以使用构造函数。
...
和
setClass("People",
representation=representation(
firstNames="character",
ages="numeric"),
validity=function(object) {
if (length(object@firstNames) != length(object@ages))
"'firstNames' and 'ages' must have same length"
else TRUE
})
People = function(firstNames=character(), ages=numeric(), ...)
new("People", firstNames=firstNames, ages=ages, ...)