10.9 类,泛型函数和面向对象

一个对象的类决定了它会如何被一个泛型函数1处理。相反,一个泛型函数由参数自身类的种类来决定完成特定工作或者事务的。如果参数缺乏任何类属性,或者在该问题中有一个不能被任何泛型函数处理的类,泛型函数会有一种默认的处理方式

下面的一个例子使这个问题变得清晰。类机制为用户提供了为特定问题设计和编写泛型函数的便利。在众多泛型函数中,plot() 用于图形化显示对象,summary() 用于各种类型的概述分析,以及 anova() 用于比较统计模型。

能以特定方式处理类的泛型函数的数目非常庞大。例如,可以在非常时髦的类对象 "data.frame" 中使用的函数有

[     [[<-    any    as.matrix
[<-   mean    plot   summary

可以用函数 methods() 得到当前对某个类对象可用的泛型函数列表:

> methods(class="data.frame")

相反,一个泛型函数可以处理的类同样很多。例如,plot() 有默认的方法和变量处理对象类 "data.frame","density","factor",等等。一个完整的列表同样可以通过函数 methods() 得到:

> methods(plot)

许多泛形函数的函数主体部分非常的短,如

> coef
function (object, ...) 
UseMethod("coef")

UseMethod 的出现暗示着这是一个泛形函数。为了查看那些方法可以使用,我们可以使用函数 methods()

> methods(coef)
[1] coef.aov*         coef.Arima*       coef.default*     coef.listof*
[5] coef.nls*         coef.summary.nls*

   Non-visible functions are asterisked

这个例子中有六个方法,不过其中任何一个都不能简单地通过键入名字来查看2。我 们可以通过下面两种方法查看

> getAnywhere("coef.aov")
A single object matching ‘coef.aov’ was found
It was found in the following places
  registered S3 method for coef from namespace stats
  namespace:stats
with value

function (object, ...)
{
    z <- object$coef
    z[!is.na(z)]
}

> getS3method("coef", "aov")
function (object, ...)
{
    z <- object$coef
    z[!is.na(z)]
}

泛型 gen 对应 cl 类将调用一个名为 gen.cl 的函数,所以无需这样对对此类函数命名,除非打算将其当作方法(methods)

读者可以参考文档 R 语言定义(R Language Definition) 以得到关于这种机制更完整的讨论。


1. 译者注:R 里面泛形函数和Java里面的接口(interface)行为最像。早期,我曾考虑用接口这个词来描述这个概念,但字面而言确实不妥。“泛型函数”的概念借鉴了候捷的翻译术语.
2. 译者注:如果简单的键入这些方法名(如coef.aov),R环境会报出错误信息 ‘‘Error: object "coef.aov" not found"。’

results matching ""

    No results matching ""