参考: http://blog.fens.me/r-object-oriented-intro/
http://cos.name/2009/07/studying-notes-on-oop-in-r/
A)创建S4对象:
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: 定义所属的包
- S3methods: R3.0.0以后不建议使用
- representation R3.0.0以后不建议使用
- access R3.0.0以后不建议使用
- version R3.0.0以后不建议使用
练习使用S4来定义Shape基类,Ecllipse子类,Circle子子类
# define in a style like C++
setClass("Shape",slots=list(name="character",shape="character"),prototype=list(name=character(0)))
setClass("Eclipse",contains="Shape",slots=list(radius="numeric"),
prototype=list(radius=c(1,1),shape="Eclipse"))
setClass("Circle",contains="Eclipse",slots=list(radius="numeric"), # overwrite "radius" in Eclipse
prototype=list(radius=1,shape="Circle"))
# 验证radius参数
setValidity("Eclipse",
function(obj)
{
if(length(obj@radius)!=2) stop("not valid radius for Ellipse");
if(any(obj@radius<0)) stop("Radius is negative");
}
)
# 面积泛函接口
setGeneric("Area",
function(obj,...) standardGeneric("Area"))
# 面积泛函实现
setMethod("Area","Eclipse",
function(obj,radius)
{
cat("Ellipse Area :\n");
return(pi*prod(obj@radius));
}
)
setMethod("Area","Circle",
function(obj,radius)
{
cat("Circle Area:\n");
return(pi*obj@radius^2);
}
)