R-S4目录
R语言 S4系统
S4的动机
为了解决S3的问题,S4专注于更加正式的面向对象。
显著的概念上的优势(conceptual advantages),但是性能有所下降。
使用了正式的继承系统(inheritance)。
1. 声明新类
每个类有许多槽(slots),每个槽都有特定的类型或者类(class)。
通过setClass()
语句声明一个新类:
setClass("coords",
slots = c(x = "numeric", y = "numeric"))
2. 构造对象(construct)
2.1 创建对象
有了一个类,用new()
创建一个这个类的对象.
声明类名,再提供slot的参数
pts <- new("coords", x = rnorm(5), y = rnorm(5))
2.2 构造函数
使用new()
并不是很理想,而构造函数(constructor function)能对slots进行有效性检查
coords <- function(x, y) {
# 有效性检查(validity check)
if (length(x) != length(y)) stop("equal length x and y required")
if (!is.numeric(x) || !is.numeric(y)) stop("numeric x and y required")
new("coords", x = as.vector(x), y = as.vector(y))
}
# 这时再用构造函数构造一个实例(instance)
pts <- coords(round(rnorm(5), 2), round(rnorm(5), 2))
# 此时就已经可以打印了,如下
> pts
An object of class "coords"
Slot "x":
[1] 1.57 1.56 -1.68 -0.97 0.65
Slot "y":
[1] -0.31 1.30 -0.03 1.02 -1.92
3. 访问与提取(access)
3.1 访问操作符
用@
对slots的值进行访问操作(access operator)
> pts@x
[1] 1.57 1.56 -1.68 -0.97 0.65
3.2 访问函数
@
过多地揭示了(reveal)类的内部结构,
而应该构造一个访问函数(访问器,accessor function),
可以更轻松地更改类的内部结构
xcoords <- function(obj) obj@x
4. 泛型(generic)
4.1 针对已有泛函,定义泛型方法
与S3不同的是,S3的方法分派取决于潜在的多个指定参数的类,而S4不只局限于一个,
指定参数的类型定义了方法的签名(signature)。
特殊类名ANY
匹配所有类,但是优先级最低(precedure)。
例子:S4中有泛函show
,用于对S4对象进行输出,比如打印
如下,对于泛函show
,针对coords类,使用setMethod()
定义一个泛型方法show()
,以实现泛函
# 注意,这里的slots也都是用accessor访问的
setMethod(show, signature(object = "coords"), function(object)
print(data.frame(x = xcoords(object), y = ycoords(object))))
# 定义show()之后,就可以通过直接输入实例名对实例进行展示/打印了
> pts
x y
1 1.57 -0.31
2 1.56 1.30
3 -1.68 -0.03
4 -