从扩展R by From,我听说R中存在的一切都是对象(在Python中也是这样:Python中的类是对象,类的类是元类)。S4类是对象吗?S4类的类型是什么?
> setClass("Person",
+ slots = c(
+ name = "character",
+ age = "numeric"
+ )
+ )
> typeof(Person)
Error in typeof(Person) : object 'Person' not found
> typeof("Person")
[1] "character"
> attributes(Person)
Error: object 'Person' not found谢谢。
发布于 2020-04-03 12:56:34
据我所知,R中的所有东西都是一个对象,但是类本身并不是直接的对象。
我们可以在R中进行面向对象的编程。事实上,R中的所有东西都是对象。对象是具有某些属性和方法的数据结构,这些属性和方法作用于其属性。类是对象的蓝图。我们可以把课堂想象成一座房子的草图(原型)。它包含了所有的细节,地板,门,窗户等。根据这些描述,我们建造的房子。
(来自这里)。
S3
考虑一下S3对象。您从未真正分配它们,只需定义一个适用于此特定类的方法:
summary.mnist <- function(x) print("HELLO!")
x <- 3
class(x) <- "mnist"
summary(x)
# [1] "HELLO!"
typeof(mnist)
# Error in typeof(mnist) : object 'mnist' not foundS4
然而,在使用S4时,要使用类,通常需要通过setClass定义生成器函数。然后,这个生成器函数是一个类型闭包的对象,但是类本身不是一个对象:
Person <- setClass("Person",
slots = c(
name = "character",
age = "numeric"
)
)
typeof(Person)
# [1] "closure"
myPerson <- Person()
typeof(myPerson)
# [1] "S4"发布于 2020-04-03 14:45:41
另一种看待这个问题的方法是,setClass()返回的对象是类classGeneratorFunction的对象。这绝对是个物体。而且,由于R中的函数也被认为是对象,所以它是一个对象。
我们将通过调整原始文章中的代码来说明问题。
personGenerator <- setClass("Person",
slots = c(name = "character",
age = "numeric"))
aPerson <- personGenerator()此时,我们有一个生成Person类型对象的类生成器函数和一个Person实例。
我们可以通过str()函数看到这一点。
str(aPerson)
> str(aPerson)
Formal class 'Person' [package ".GlobalEnv"] with 2 slots
..@ name: chr(0)
..@ age : num(0) 同样,我们可以打印personGenerator()函数的结构。
> str(personGenerator)
Formal class 'classGeneratorFunction' [package "methods"] with 3 slots
..@ .Data :function (...)
..@ className: chr "Person"
.. ..- attr(*, "package")= chr ".GlobalEnv"
..@ package : chr ".GlobalEnv"
> 回到钱伯斯的引用,它在哈德利韦翰的高级R叙述为:
要理解R中的计算,有两个口号是有帮助的。 --所有存在的东西都是一个物体 -发生的一切都是函数调用 约翰·钱伯斯引自“高级研究报告”,第79页。
由于最初的问题有点模棱两可,如果"S4类“指的是setClass()的返回值(类型为classGeneratorFunction的对象),那么这确实是一个对象。但是,如果原始问题中的"S4类“引用了setClass()参数中的内容,那么表示Person的东西在代码实例化它之前不是一个对象,如上面的personGenerator()函数所示。
发布于 2021-11-04 17:16:40
当通过S4定义setClass()类时,会创建classRepresentation类的一个对象(讽刺的是,classRepresentation本身就是一个S4类)。此对象定义类,并在通过new()创建类的实例时使用。在用户级别,这个classRepresentation通常是不可见的,因为它存储在定义它的包的名称空间中,或者存储在缓存的类表(methods:::.classTable)中。尽管如此,用户还是可以通过getClassDef()获得定义。
一些答案指出,setClass()返回一个classGeneratorFunction。但是,返回的classGeneratorFunction不是定义类的内容。实际上,在定义S4类时,通常会忽略setClass()的返回值,而通过new()编写自定义类构造函数。下面是一个示例:
setClass("Person",
slots = c(
name = "character",
age = "numeric"
)
)
# This ensures that every instance of Person is
# always initialized with a name and an age
Person <- function(name, age) {
new("Person", name=name, age=age)
}
aPerson <- Person("John", 50)
> str(aPerson)
Formal class 'Person' [package ".GlobalEnv"] with 2 slots
..@ name: chr "John"
..@ age : num 50
# Get the class definition itself
PersonDef <- getClassDef("Person")
> str(PersonDef)
Formal class 'classRepresentation' [package "methods"] with 11 slots
..@ slots :List of 2
.. ..$ name: chr "character"
.. .. ..- attr(*, "package")= chr "methods"
.. ..$ age : chr "numeric"
.. .. ..- attr(*, "package")= chr "methods"
..@ contains : list()
..@ virtual : logi FALSE
..@ prototype :Formal class 'S4' [package ""] with 0 slots
list()
.. .. ..$ name: chr(0)
.. .. ..$ age : num(0)
..@ validity : NULL
..@ access : list()
..@ className : chr "Person"
.. ..- attr(*, "package")= chr ".GlobalEnv"
..@ package : chr ".GlobalEnv"
..@ subclasses: list()
..@ versionKey:<externalptr>
..@ sealed : logi FALSEhttps://stackoverflow.com/questions/61011183
复制相似问题