show 方法
本课属于 Coddy R 学习旅程的“面向对象编程”单元。第 25 课,共 57 课。
打印 S4 对象时,R 会调用函数 show()。如果这个类没有对应的方法,R 会列出每个槽位。这样做是正确的,但内容很长:
setClass("Point", slots = c(x = "numeric", y = "numeric"))
p <- new("Point", x = 1, y = 2)
p输出:
An object of class "Point"
Slot "x":
[1] 1
Slot "y":
[1] 2setMethod("show", "Point", function(object) ...) 为类定义了自己的打印方式。该方法使用 cat() 打印对象,在顶层打印对象以及调用 print() 时都会使用它:
setClass("Point", slots = c(x = "numeric", y = "numeric"))
setMethod("show", "Point", function(object) {
cat("Point(", object@x, ", ", object@y, ")\n", sep = "")
})
p <- new("Point", x = 1, y = 2)
p
print(p)输出:
Point(1, 2)
Point(1, 2)一个槽可以保存另一个 S4 对象:将它的类型声明为类名。外层 show() 方法可以通过对内部对象调用 show() 来打印它:
setClass("Point", slots = c(x = "numeric", y = "numeric"))
setMethod("show", "Point", function(object) cat("(", object@x, ", ", object@y, ")", sep = ""))
setClass("Line", slots = c(from = "Point", to = "Point"))
setMethod("show", "Line", function(object) {
cat("line ")
show(object@from)
cat(" -> ")
show(object@to)
cat("\n")
})
new("Line", from = new("Point", x = 0, y = 0), to = new("Point", x = 3, y = 4))输出:
line (0, 0) -> (3, 4)用 representation("VIRTUAL") 声明的虚拟类无法通过 new() 创建。虚拟类是其他类的共同父类,S4 继承章会以此为基础。isVirtualClass() 可以区分这两类:
setClass("Shape", representation("VIRTUAL"))
setClass("Point", slots = c(x = "numeric"))
cat(isVirtualClass("Shape"), isVirtualClass("Point"), "\n")
msg <- tryCatch(new("Shape"), error = function(e) "cannot create a Shape")
cat(msg, "\n")输出:
TRUE FALSE
cannot create a Shape 挑战
简单点和线段是定义在两个文件中的两个 S4 类。这些类已经声明。请为它们添加 show() 方法:
- 在
Point.R中:点的输出为Point(1, 2),后面跟一个换行符。 - 在
Segment.R中:线段的输出为Segment Point(1, 2) to Point(4, 6), length 5,后面跟一个换行符,长度四舍五入到小数点后两位。你可以自己构建点的文本,也可以使用辅助函数;点的方法会输出自己的换行符,因此不要在线段输出的中间调用它。
提供的代码会读取 1,2 4,6 这行,然后通过各自的 show() 方法先输出第一个点,再输出线段。
你的代码应写在 Point.R 和 Segment.R 中。main.R 保存了提供的输入/输出代码,不能编辑。
亲手试试
source("Point.R")
source("Segment.R")
# 提供的输入/输出代码:保持原样。
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
n <- as.numeric(strsplit(line, "[ ,]")[[1]])
a <- new("Point", x = n[1], y = n[2])
b <- new("Point", x = n[3], y = n[4])
print(a)
print(new("Segment", from = a, to = b))
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: R 在线编译器