R语言面向对象之S3 class

(本文是AdvancedR的S3章读书笔记)
S3类是R语言中最基础的类设计,是居于object+attribute的方式构造的。

构造

方法代码
一步构造o1 <- structure(data, class = "ClassA")
显式设置o1 <- data; class(o1) <- "ClassA"

和类相关的几个函数:

  • typeof(obj)
  • attributes(obj)
  • class(obj)/unclass(obj)
  • sloop::s3_dispatch()
  • sloop::s3_get_method()
  • inherits(obj, "classname")

泛函数和类方法 Generic & Methods

定义泛函数


# 定义一个新的泛函数
new_generic_func <- function(x, ...) {
    UseMethod("new_generic_func")
}


# 定义泛函数缺省的方法(method)
new_generic_func.default <- function(x, ...) {
    # 缺省实现
}


# 定义泛函数指定类的方法(method)
new_generic_func.ClassA <- function(x, ...) {
    # ClassA对应的实现
}

UseMethod(generic, object)第一个参数是泛函数的名字(字符串),第二个参数的传入的对象,function传入的第一个参数。

methods(generic.function, class) generic.function和class参数两者择一,可以查看实现了该泛函数的所有类,也可以查看一个class定义了哪些泛函数。
sloop::s3_methods_generic()sloop::s3_methods_class()显示更详细的信息。

继承

S3的继承比较简单,通过如下机制是实现:

  1. class属性是个字符串向量,按子类到父类从左到右依次排列。假如需要表示继承父类,取得父类的class向量后,在最前面添加子类的class名字。
  2. method调用,根据class向量,从左到右查找,直到找到泛函数的定义。
  3. 调用NextMethod()可以把method调用deletate到另一个泛函数。

泛函数查找机制

当调用一个泛函数时,根据传入的对象的类型去查找对应定义的函数。比如传入一个对象,其class是list,则去查找new_generic_func.list的函数。若找到了,则把参数传入直接调用; 若没有则查找new_generic_func.default函数;没有default函数则抛出错误。

对于继承类,顺着子类到父类的顺序回溯查找,直到找到default为止(假如有定义default函数)

sloop::s3_dispatch()可以清楚的显示泛函数调用到底dispatch给了哪个对应类定义的泛函数。其中前导符号的意思是:

  • => method exists and is found by UseMethod().
  • -> method exists and is used by NextMethod().
  • * method exists but is not used.
  • Nothing (and greyed out in console): method does not exist.

NextMethod()

调用NextMethod(), 触发泛函数往后查找一个定义了的实现,把参数传到该实现函数,并返回调用值。

# NextMethod定义
NextMethod(generic = NULL, object = NULL, ...)

generic指定了查找的generic,object指定了delegate的对象。
如果generic为NULL,则是调用NextMethod的函数名;
如果object为NULL,则查找参数的第一个对象起始的generic的下一个定义了的generic。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值