在前面的例子中,我们可以看出 S4 比 S3 更正式,因为 S4 类有类的正式定义。同样,

S4 的泛型函数也更加正式。
在一个关于形状的例子中,我们定义了一系列具有继承关系的 S4 类,只是继承关系的层级
结构比较简单。首先,Shape 是处于根节点的类,Polygon 和 Circle 都继承自 Shape,而
Triangle 和Rectangle 继承自Polygon。这些形状的继承结构如图10-5 所示。

图 10-5
除了 Shape 类,其他每个类都有一些用于描述这个类必要的字段:
setClass("Shape")
setClass("Polygon",
representation(sides = "integer"),
contains = "Shape")
setClass("Triangle",
representation(a = "numeric", b = "numeric", c = "numeric"),
prototype(a = 1, b = 1, c = 1, sides = 3L),
contains = "Polygon")
setClass("Rectangle",
representation(a = "numeric", b = "numeric"),
prototype(a = 1, b = 1, sides = 4L),
contains = "Polygon")
setClass("Circle",
representation(r = "numeric"),
prototype(r = 1, sides = Inf),
contains = "Shape")
定义了这些类,我们就可以构建一个泛型函数来计算一个 Shape 对象的面积。为此,
我们需要调用 setGeneric( )创建一个新的泛型函数:area( ),并为 area( )提供
一个调用 standardGeneric("area")的函数来使这个新的泛型函数可用于 S4 方法分
派。参数 valueClass 是用来确保每种方法的返回值必须是 numeric 类:
setGeneric("area", function(object) {
standardGeneric("area")
}, valueClass = "numeric")
## [1] "area"
一旦构建了泛型函数,我们就可以为不同种类的形状实现不同的方法。对于 Triangle,
给定三角形的 3 个边长,使用海伦公式[Heron's formula(https://en.wikipedia.org/wiki/Heron's_
formula)]来计算它的面积:
setMethod("area", signature("Triangle"), function(object) {
a <- object@a
b <- object@b
c <- object@c
s <- (a + b + c) / 2
sqrt(s * (s -a) *(s -b) * (s -c))
})
## [1] "area"
对于 Rectangle 和 Circle,我们可以很容易地写出它们的面积公式:
setMethod("area", signature("Rectangle"), function(object) {
object@a *object@b
})
## [1] "area"
setMethod("area", signature("Circle"), function(object) {
pi *object@r ^2
})
## [1] "area"
现在,我们创建一个 Triangle 类的对象实例,并查看泛型函数 area( )是否会分
派正确的方法,然后返回正确的答案:
triangle <- new("Triangle", a = 3, b = 4, c = 5)
area(triangle)
## [1] 6
再创建一个 Circle 类对象实例,看看方法分派是否正常进行:
circle <- new("Circle", r = 3)
area(circle)
## [1] 28.27433
两个答案都是正确的。泛型函数 area( )的工作方式与 S3 的泛型函数类似,都是根
据输入对象的类执行方法分派。

定义 S4 泛型函数的更多相关文章

  1. 排序算法 2 qsort 库函数,泛型函数

    _____谈谈排序算法 交换排序——>冒泡排序-->快速排序 选择排序——>简单选择排序——>堆排序 插入排序——>直接插入排序——>希尔排序 _____排序算法对 ...

  2. Scala 深入浅出实战经典 第42讲:scala 泛型类,泛型函数,泛型在spark中的广泛应用

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  3. Swift泛型和泛型函数

    泛型(generic)可以使我们在程序代码中定义一些可变的部分,在运行的时候指定.使用泛型可以最大限度地重用代码.保护类型的安全以及提高性能.在Swift集合类中,已经采用了泛型.一.一个问题的思考怎 ...

  4. Java泛型函数的运行时类型检查的问题

    在一个数据持久化处理中定义了数据保存和读取的 泛型函数的,但是在运行时出现类型转换错误,类型不匹配,出错的位置不是load方法,而是在调用load方法之后,得到了列表数据,对列表数据进行使用时出现的. ...

  5. 定义 S4 类

    S3 类仅用一个字符向量表示,与之不同的是,S4 类要求对类和方法有正式定义.为了定义一个 S4 类,我们需要调用 setClass( ),并提供一种类成员的表示,这种表示被称为字段(slots).通 ...

  6. 指针数组,数组指针,函数指针,main函数实质,二重指针,函数指针作为參数,泛型函数

     1.指针数组 数组里面的每一个元素都是指针. 指针数组的案比例如以下: 易犯错误: 2.数组指针 归根结底还是指针,仅仅是取*的时候可以取出一整个数组出来. 数组指针:(一个指针指向了数组.一般 ...

  7. kotlin之函数的范围和泛型函数

    kotlin 中函数可以定义为局部函数,成员函数以及扩展函数 局部函数:就是嵌套在函数内的函数 成员函数就是定义在类或者对象之内的函数 泛型函数就是函数可以带有泛型参数,可通过尖括号来指定

  8. Entity Framework 6 Recipes 2nd Edition(11-12)译 -> 定义内置函数

    11-12. 定义内置函数 问题 想要定义一个在eSQL 和LINQ 查询里使用的内置函数. 解决方案 我们要在数据库中使用IsNull 函数,但是EF没有为eSQL 或LINQ发布这个函数. 假设我 ...

  9. C++中为什么要将析构函数定义成虚函数

    构造函数不可以是虚函数的,这个很显然,毕竟虚函数都对应一个虚函数表,虚函数表是存在对象内存空间的,如果构造函数是虚的,就需要一个虚函数表来调用,但是类还没实例化没有内存空间就没有虚函数表,这根本就是个 ...

随机推荐

  1. 如何获取e.printStackTrace()的内容

    e.printStackTrace()通常是打印在控制台的,但是,有时候程序上线了需要看这个堆栈的内容就不容易了,一来生产环境打印的东西很多或者很少,二来有时候无法直接查看到,这个时候就需要把这些内容 ...

  2. Unity3D笔记十 游戏元素

    一.地形 1.1 树元素 1.2 草元素 二.光源 2.1 点光源 点光源(Point Light):好像包围在一个类似球形的物体中,读者可将球形理解为点光源的照射范围,就像家里的灯泡可以照亮整个屋子 ...

  3. WCF(五) 深入理解绑定

    适用于本机WCF-WCF交互性能最佳的绑定: 允许跨主机,但只能用于部署同一台主机上,不能访问命名管道 netNamePipeBinding总结 一 WCF与SOA SOA是一种通过为所有软件提供服务 ...

  4. Java实现远程服务生产与消费(RPC)的4种方法-RMI,WebService,HttpClient,RestTemplate

    目录 一. 通过rmi实现远程服务的生产与消费 远程服务提供者实现. 创建rmi-provider项目(Maven) 远程服务消费者实现 创建rmi-consumer项目 二. 通过WebServic ...

  5. 白话陈述之——从python脚本变化解析由路径引起的GP服务运行失败问题

    补充一下未完待续的利用Python分析GP服务运行结果的输出路径 & 实现服务输出路径的本地化,这篇博客中主要介绍了如何实现将GP服务生成的结果输出至本地及输入输出路径导致GP服务运行失败的问 ...

  6. redis cluster集群部署

    上一篇http://www.cnblogs.com/qinyujie/p/9029153.html,主要讲解了 redis cluster 集群架构 的优势.redis cluster 和 redis ...

  7. POJ1236:Network of Schools(tarjan+缩点)?

    题目: http://poj.org/problem?id=1236 [题意] N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,问题1 ...

  8. Eclipse中没有javax.servlet和javax.servlet.http包的处理办法

    使用Eclips开发JSP也需要这两个包:javax.servlet和javax.servlet.http:若提示没有javax.servlet包则安装如下处理办法解决: 如果你装了Tomacat,那 ...

  9. 找回 linux root密码的几种方法

    第1种方法: 1.在系统进入单用户状态,直接用passwd root去更改  2.用安装光盘引导系统,进行linux rescue状态,将原来/分区挂接上来,作法如下: Java代码  #> c ...

  10. 4gcc编译器

    gcc编译器(GNU C Compiler) 现在我们所说的 gcc 是 GUN Compiler Collection的缩写,可以支持多种语言编译,比如 C,C++,Java, pascal 等 g ...