R语言中常用的对象系统有S3、S4、RC、R6,其中S3和S4是基于泛型函数(generic function),而RC、R6是完全的面向对象。这里介绍RC对象系统。
RC是Reference classes的简称,又被称为R5,在R语言的2.12版本被引人,是R语言最新一代的面向对象系统。RC不同于原来的S3和S4对象系统,RC对象系统的方法是在类中自定的,而不是泛型函数。RC对象的行为更类似于其他的编程语言,实例化对象的语法也有所改变。但由于RC对象系统还是依赖于S4对象系统,我们可以简单地理解为RC是对S4的更进一步的面向对象封装。从面向对象的角度来说,我们下面要重定义以下几个名词。
类:面向对象系统的基本类型,类是静态结构定义;
对象:类实例化后,在内存中生成结构体;
方法:是类中的函数定义,不通过泛型函数实现。
在S3和S4对象系统中,我们实现对象的行为时,都是借助于泛型函数来实现的。这种实现方法的最大问题是,在定义时函数和对象的代码是分离的,需要在运行时,通过判断对象的类型完成方法调用。而在RC对象系统中,将method()方法定义在类的内部,通过实例化的对象完成方法调用。
定义一个Animal类,Cat、Dog、Duck继承于Animal,Animal有2个属性:name、limbs,2个方法:bark()、action(),其继承图表如图(1)所示:
用R3.2.3实现的代码如下:
//RC2a.R
# part1 -------------------------------------------------------------------
rm(list = ls())
##加载包
library(pryr)
##定义Animal类,
Animal <- setRefClass("Animal",
fields = list(name="character",limbs='numeric'),
methods = list(
initialize = function(name){
name <<- 'Animal'
limbs <<- 4
},
bark = function() print("Animal::bark"),
action = function() print("I can walk on the foot")
)
)
##定义Cat类,继承Animal
Cat <- setRefClass("Cat",contains = "Animal",
methods = list(
initialize = function(name){
callSuper()
name <<- 'cat'
},
##重写父类方法
bark = function() print(paste(name,"is miao miao")),
action = function(){
callSuper()
print("I can Climb a tree")
}
)
)
##定义Dog类,继承Animal
Dog <- setRefClass("Dog",contains = "Animal",
methods = list(
initialize = function(name){
callSuper()
name <<- 'dog'
},
##重写父类方法
bark = function() print(paste(name,"is wang wang")),
action = function(){
callSuper()
print("I am Swim")
}
)
)
##定义Duck类
Duck <- setRefClass("Duck",contains = "Animal",
fields = list(wing='numeric'),
methods = list(
initialize = function(name){
name <<- 'duck'
limbs <<- 2
wing <<- 2
},
##重写父类方法
bark = function() print(paste(name,"is ga ga")),
action = function(){
callSuper()
print("I am swim.")
print("I also can fly a short way.")
}
)
)
##实例化cat
cat <- Cat$new()
cat$action()
##实例化dog
dog <- Dog$new()
dog$action()
##实例化duck
duck <- Duck$new()
duck$action()
效果如下: