Menu
CoddyTech

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] 2

setMethod("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 
challenge icon

挑战

简单

点和线段是定义在两个文件中的两个 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))
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: R 在线编译器