R开发(part12)--基于RC的面向对象编程

学习笔记,仅供参考,有错必纠

参考自:《R的极客理想》-- 张丹


文章目录

    • R开发
      • 基于RC的面向对象编程
        • 创建RC类和对象
        • 对象赋值
        • 定义对象的方法
        • RC对象内置方法和内置属性
        • RC类的辅助函数



R开发


基于RC的面向对象编程


RC是Reference classes的简称,又被称为R5,RC不同于原来的S3和S4对象系统,RC对象系统的方法是在类中自定的,而不是泛型函数。RC对象的行为更类似于其他的编程语言,实例化对象的语法也有所改变。但由于RC对象系统还是依赖于S4对象系统,我们可以简单地理解为RC是对S4的更进一步的面向对象封装。


创建RC类和对象


  • setRefClass函数

RC对象系统以为基本类型,有专门的类的定义函数setRefClass和实例化对象的生成方法。

语法:

setRefClass(Class, fields = , contains = , methods =,
     where =, inheritPackage =, ...)

参数列表:

参数 解释
Class 定义类名
fields 定义属性和属性类型
contains 定义父类,继承关系
methods 定义类中的方法
where 定义存储空间

  • 创建RC类和实例

创建一个RC类:

#定义一个RC类
User <- setRefClass("User", fields = list(name = "character"))

实例化一个RC对象:

#实例化一个User对象u1
u1 <- User$new(name = "u1")
u1
#输出start
Reference class object of class "User"
Field "name":
[1] "u1"
#输出end

class(User)
#输出start
[1] "refObjectGenerator"
attr(,"package")
[1] "methods"
#输出end

is.object(User) #TRUE
otype(User) #"RC"
class(u1)
#输出start
[1] "User"
attr(,"package")
[1] ".GlobalEnv"
#输出end

is.object(u1) #TRUE
otype(u1) #"RC"

  • 创建一个有继承关系的RC

#创建RC类User
User <- setRefClass("User",  fields = list(name = "character"))

#创建User的子类Member
Member<-setRefClass("Member", contains = "User", 
                    fields = list(manage = "User"))
#实例化User
manager <- User$new(name = "manager")
#实例化一个Member对象
menber <- Member$new(name = "menber", manage = manager)

#查看member对象
menber
#输出start
Reference class object of class "Member"
Field "name":
[1] "menber"
Field "manage":
Reference class object of class "User"
Field "name":
[1] "manager"
#输出end

#查看member对象的name属性
menber$name #"menber"
#检查对象的属性类型
otype(menber$name) #"base"
otype(menber$manage) #"RC"

  • RC对象的默认值

RC的类有一个指定构造器方法$initialize(),这个构造器方法在实例化对象时,会自动被运行一次,通过这个构造方法可以设置属性的默认值。

#定义一个RC类, 并设置默认值
User <- setRefClass("User", fields = list(name = "character", level = "numeric"),
                    methods = list(
                      initialize = function(name, level) {
                        print("User::initialize自动执行")
                        name <<- "Huang"
                        level <<- 12
                      }
                    ))

#实例化对象
u1 <- User$new() #"User::initialize自动执行"
#查看对象u1,属性被增加了默认值
u1
#输出start
Reference class object of class "User"
Field "name":
[1] "Huang"
Field "level":
[1] 12
#输出end

对象赋值


#定义User类
User <- setRefClass("User",  
                    fields = list(name = "character", age = "numeric",
                                  gender = "factor"))
#定义一个factor类型
genderFactor <- factor(c("F", "M"))
#实例化u1
u1<-User$new(name = "u1", age = 30, gender = genderFactor[1])
#查看age属性值
u1$age #30
u1$gender
#输出start
[1] F
Levels: F M
#输出end

给u1的age属性赋值:

u1$age <- 10
u1$age #10

把u1对象赋值给u2对象:

#把u1赋值给u2对象
u2 <- u1
#查看u2的age属性
u2$age #10
#重新赋值
u1$age <- 20
#查看u1, u2的age属性
u1$age #20
u2$age #20

由于把u1赋值给u2的时候,传递的是u1的实例化对象的引用,而不是值本身,这一点与其他语言中对象赋值是一样的。

如果想进行赋值而不是引用传递,可以用下面的方法实现:

#调用u1的内置方法copy,赋值给u3
u3 <- u1$copy()
#查看u3的age属性
u3$age #20
#重新赋值
u1$age <- 30
#查看u1的age属性,发生改变
u1$age #30
#查看u3的age属性,没有改变
u3$age #20

定义对象的方法


在RC对象系统中,方法可以定义在类的内部,通过实例化的对象完成方法调用。


User <- setRefClass("User", 
                    fields = list(name = "character", favorite = "vector"),
                    methods = list(
                      addFavorite = function(x) {
                        favorite <<- c(favorite, x)
                      },
                      delFavorite = function(x) {
                        favorite <<- favorite[-which(favorite == x)]
                      },
                      setFavorite = function(x) {
                        favorite <<- x
                      }
                    ))

#实例化对象
u1 <- User$new(name = "u1", favorite = c("movie", "football"))
u1$favorite #"movie"    "football"
#删除一个兴趣
u1$delFavorite("football")
#增加一个兴趣
u1$addFavorite("reading")
u1$favorite #"movie"   "reading"
#重新设置兴趣列表
u1$setFavorite(c("game", "reading"))
u1$favorite #"game"    "reading"

RC对象内置方法和内置属性


对于RC的实例化对象,除了我们自己定义的方法,还有几个内置的方法,属性复制赋值时使用的copy方法,就是其中之一。


  • 内置方法

内置方法 作用
initialize 类的初始化函数,用于设置属性的默认值,只能在类定义的方法中使用
callSuper 调用父类的同名方法,只能在类定义的方法中使用
copy 复制实例化对象的所有属性
initFields 给对象的属性赋值
field 查看属性或给属性赋值
getClass 查看对象的类定义
getRefClass 同getClass
show 查看当前对象
export 查看属性值,以类为作用域
import 把一个对象的属性值赋值给另一个对象
trace 跟踪对象中方法调用,用于程序debug
untrace 取消跟踪
usingMethods 用于实现方法调用,只能在类定义的方法中使用

  • 内置属性

RC对象实例化后,有两个内置属性。


内置方法 作用
.self 实例化对象自身
.refClassDef 类的定义类型

RC类的辅助函数


当我们定义好一个RC的类时,有一些辅助函数可以帮助我们查看类的属性和方法,用于创建实例化的对象的$new()函数,也属于这类辅助函数.


  • 辅助函数

辅助函数 含义
new 实例化对象
help 查询类中方法的调用
methods 列出类中定义的所有方法
fields 列出类中定义的所有属性
lock 给属性加锁,实例化对象的属性只允许赋值一次,即赋值变量,不可修改
trace 跟踪方法
accessors 给属性生成get/set方法

你可能感兴趣的:(R语言,R)