參考: 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);
}
)