前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >R语言基础教程——第7章:面向对象编程(S4类)

R语言基础教程——第7章:面向对象编程(S4类)

作者头像
DoubleHelix
发布2019-08-07 15:01:39
2.7K0
发布2019-08-07 15:01:39
举报
文章被收录于专栏:生物信息云生物信息云
一些程序员认为S3类不具有面向对象编程固有的安全性。例如,你可以任意修改S3类,哪怕是不合法的修改。相比而言,S4类更加安全。

S4类的创建

可以调用setClass()来定义一个S4类。

代码语言:javascript
复制
setClass(Class, representation, prototype, contains=character(),
          validity, access, where, version, sealed, package,
          S3methods = FALSE, slots)

Class: 定义类名

slots: 定义属性和属性类型

prototype: 定义属性的默认值

contains=character(): 定义父类,继承关系

validity: 定义属性的类型检查

where: 定义存储空间

sealed: 如果设置TRUE,则同名类不能被再次定义

package: 定义所属的包

创建一个S4对象实例 为了方便我们检查对象的类型,引入pryr包作为辅助工具。 library(pryr)

代码语言:javascript
复制
# 定义一个S4对象
 > setClass("Person",slots=list(name="character",age="numeric"))
代码语言:javascript
复制
# 实例化一个Person对象
> father<-new("Person",name="F",age=44)
代码语言:javascript
复制
# 查看father对象,有两个属性name和age
> father
An object of class "Person"
Slot "name":
[1] "F"

Slot "age":
[1] 44
代码语言:javascript
复制
# 查看father对象类型,为Person
> class(father)
[1] "Person"
attr(,"package")
[1] ".GlobalEnv"

创建一个有继承关系的S4对象

代码语言:javascript
复制
# 创建一个S4对象Person
setClass("Person",slots=list(name="character",age="numeric"))
代码语言:javascript
复制
# 创建Person的子类
setClass("Son",slots=list(father="Person",mother="Person"),contains="Person")
代码语言:javascript
复制
# 实例化Person对象
father<-new("Person",name="F",age=44)
mother<-new("Person",name="M",age=39)
代码语言:javascript
复制
# 实例化一个Son对象
son<-new("Son",name="S",age=16,father=father,mother=mother)
# 查看son对象的name属性
son@name
# 查看son对象的age属性
son@age
# 查看son对象的father属性
son@father
Slot "age":
# 查看son对象的mother属性
slot(son,"mother")
# 检查son类型
otype(son)
# 检查son@name属性类型
otype(son@name)
# 检查son@mother属性类型
 otype(son@mother)
# 用isS4(),检查S4对象的类型
isS4(son)
isS4(son@name)
isS4(son@mother)

S4对象的默认值

代码语言:javascript
复制
setClass("Person",slots=list(name="character",age="numeric"))
# 属性age为空
 a<-new("Person",name="a")
 a
# 设置属性age的默认值20
setClass("Person",slots=list(name="character",age="numeric"),prototype = list(age = 20))
# 属性age为空
b<-new("Person",name="b")
# 属性age的默认值是20
b

S4对象的类型检查

代码语言:javascript
复制
setClass("Person",slots=list(name="character",age="numeric"))
# 传入错误的age类型
 bad<-new("Person",name="bad",age="abc")
# 设置age的非负检查
 setValidity("Person",function(object) {
+     if (object@age <= 0) stop("Age is negative.")
+ })
# 修传入小于0的年龄
bad2<-new("Person",name="bad",age=-1)

从一个已经实例化的对象中创建新对象

S4对象,还支持从一个已经实例化的对象中创建新对象,创建时可以覆盖旧对象的值

代码语言:javascript
复制
setClass("Person",slots=list(name="character",age="numeric"))
# 创建一个对象实例n1
n1<-new("Person",name="n1",age=19);n1
# 从实例n1中,创建实例n2,并修改name的属性值
 n2<-initialize(n1,name="n2");n2

访问对象的属性

在S3对象中,一般我使用$来访问一个对象的属性,但在S4对象中,我们只能使用@来访问一个对象的属性

代码语言:javascript
复制
setClass("Person",slots=list(name="character",age="numeric"))
a<-new("Person",name="a")
# 访问S4对象的属性
 a@name
 slot(a, "name")
# 错误的属性访问
a$name
a[1]
a[1]

S4的泛型函数

S4的泛型函数实现有别于S3的实现,S4分离了方法的定义和实现,如在其他语言中我们常说的接口和实现分离。通过setGeneric()来定义接口,通过setMethod()来定义现实类。这样可以让S4对象系统,更符合面向对象的特征。

普通函数的定义和调用

代码语言:javascript
复制
 work<-function(x) cat(x, "is working")
 work('Conan')
# 定义Person对象
setClass("Person",slots=list(name="character",age="numeric"))
# 定义泛型函数work,即接口
setGeneric("work",function(object) standardGeneric("work"))
# 定义work的现实,并指定参数类型为Person对象
setMethod("work", signature(object = "Person"), function(object) cat(object@name , "is working") )
# 创建一个Person对象a
a<-new("Person",name="Conan",age=16)
# 把对象a传入work函数
work(a)
Conan is working

通过S4对象系统,把原来的函数定义和调用2步,为成了4步进行:

(1)定义数据对象类型

(2)定义接口函数

(3)定义实现函数

(4)把数据对象以参数传入到接口函数,执行实现函数

通过S4对象系统,是一个结构化的,完整的面向对象实现。

查看S4对象的函数

当我们使用S4对象进行面向对象封装后,我们还需要能查看到S4对象的定义和函数定义。

还以上面Person和work的例子

代码语言:javascript
复制
# 检查work的类型
 ftype(work)
# 直接查看work函数
work
# 查看work函数的现实定义
 showMethods(work)
# 查看Person对象的work函数现实
getMethod("work", "Person")
selectMethod("work", "Person")
# 检查Person对象有没有work函数
 existsMethod("work", "Person")
 hasMethod("work", "Person")
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 MedBioInfoCloud 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • S4类的创建
  • 创建一个S4对象实例 为了方便我们检查对象的类型,引入pryr包作为辅助工具。 library(pryr)
  • 创建一个有继承关系的S4对象
  • S4对象的默认值
  • S4对象的类型检查
  • 从一个已经实例化的对象中创建新对象
  • 访问对象的属性
  • S4的泛型函数
  • 查看S4对象的函数
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档