【r<-高级】R-面向对象编程(二)
2018-08-20 本文已影响132人
王诗翔
内容:
- S4
- 引用类(Reference class, RC)
- R6扩展包
S4对象系统
在S3之后,R引入一个更正式更严谨的面向对象系统S4。这个系统允许我们使用预定义和继承结构来正式定义类。它也支持多重分派,即根据泛型函数的多个参数的类选择方法。
下面学习如何定义S4类和方法。
定义S4类
与S3不同,S4类要求对类和方法有正式定义。为了定义一个S4类,我们需要调用setClass()并提供一个类成员的表示,该表示称为字段(slot)。
下面我们用S4类重新定义product对象:
setClass("Product",
representation(name = "character",
price = "numeric",
inventory = "integer"))
类被定义后,我们可以使用getSlots()从类定义中获取字段:
getSlots("Product")
#> name price inventory
#> "character" "numeric" "integer"
现在我们使用new()创建一个新的S4类对象实例,并指定字段的取值:
laptop = new("Product", name = "Laptop-A", price = 299, inventory = 1000)
#> Error in validObject(.Object): invalid class "Product" object: invalid object for slot "inventory" in class "Product": got class "numeric", should be or extend class "integer"
你可能会奇怪为什么报错。但仔细查看你会发现inventory必须是整数,而我们输入的1000是数值,它的类不是integer。
laptop = new("Product", name = "Laptop-A", price = 299, inventory = 1000L)
laptop
#> An object of class "Product"
#> Slot "name":
#> [1] "Laptop-A"
#>
#> Slot "price":
#> [1] 299
#>
#> Slot "inventory":
#> [1] 1000
现在实例laptop创建好了。
对于S4对象我们仍然可以用typeof()和class()获取信息:
typeof(laptop)
#> [1] "S4"
class(laptop)
#> [1] "Product"
#> attr(,"package")
#> [1] ".GlobalEnv"
这次对象的类型是S4,而非列表或其他数据类型,而且它的类是S4类的名字。
我们可以使用检查函数判断是否是S4:
isS4(laptop)
#> [1] TRUE
与使用$访问列表或环境不同,我们需要使用@来访问一个S4对象的字段:
laptop@price * laptop@inventory
#> [1] 299000