R语言的S4类

S3类的最大优点是方便,但是使用S3类并不安全。例如,你可以任意修改S3类,哪怕是不合法的修改。关于S3类,可以参考R语言的S3类与泛型函数。相比而言,S4类更加安全。

我们可以用下面的方式定义一个S4类mybox并初始化一个对象:

setClass('mybox',
    slots = list(long = 'numeric', width = 'numeric', height = 'numeric', name = 'character')
)
myBox <- new('mybox')
myBox

An object of class "mybox"
Slot "long":
numeric(0)

Slot "width":
numeric(0)

Slot "height":
numeric(0)

Slot "name":
character(0)

 

现在我们看到,对象myBox中有一系列的slot变量(可以翻译为槽变量),其类型就是我们设置的类型。在上面初始化的代码中,我们并未对slot变量赋值。我们可以在初始化的时候赋值:

myBox <- new('mybox', long = 3, width = 4, height = 5, name = 'box1')
myBox

An object of class "mybox"
Slot "long":
[1] 3

Slot "width":
[1] 4

Slot "height":
[1] 5

Slot "name":
[1] "box1"


现在,我们看到myBox对象中的slot变量已经被赋值。我们可以用下面两种方式来获得某个slot变量:

slot(myBox, 'long')
myBox@long


当然,我们也可以对某个slot赋值:

myBox@long <- 100
 

为了显示S4类是安全的,我们故意输入错误:

myBox@longg <- 100

此时会提示错误:

Error in checkAtAssignment("mybox", "longg", "numeric") :
  ‘longg’ is not a slot in class “mybox”
注意,对于S3类来说,这种情况不会有任何提示。

 

我们可以为类mybox定一个方法volume用来计算盒子的体积。注意,因为volume这个函数之前没有存在过,我们首先需要定义这个函数本身作为泛型函数,然后再设置mybox类的方法:

setGeneric('volume',
    function(object) {
        standardGeneric('volume')
    }
)


setMethod('volume', 'mybox', 
    function(object) {
        return(object@long * object@width * object@height)
    }
)


现在我们可以计算盒子的体积了:

volume(myBox)

[1] 60


 

现在我们可以总结一下S3类和S4类的区别了。

1.在定义S3类的时候,没有显式的定义过程,而定义S4类的时候需要调用函数setClass;

2.在初始化S3对象的时候,只是建立了一个list,然后设置其class属性,而初始化S4对象时需要使用函数new;

3.提取变量的符号不同,S3为$,而S4为@;

4.在应用泛型函数时,S3需要定义f.classname,而S4需要使用setMethod函数;

5.在声明泛型函数时,S3使用UseMethod(), 而S4使用setGeneric()。

 

 

 

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值